Skip to content

Commit

Permalink
Merge pull request #68 from teddylear/feature/xdg-base-dir-2
Browse files Browse the repository at this point in the history
Feature/xdg base dir 2
  • Loading branch information
SwampDragons authored Jul 28, 2021
2 parents d47c130 + 006be29 commit 4c9e709
Show file tree
Hide file tree
Showing 10 changed files with 435 additions and 25 deletions.
20 changes: 11 additions & 9 deletions packer/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,29 @@ import (
"path/filepath"
)

var DefaultCacheDir = "packer_cache"

// CachePath returns an absolute path to a cache file or directory
//
// When the directory is not absolute, CachePath will try to get
// current working directory to be able to return a full path.
// CachePath tries to create the resulting path if it doesn't exist.
//
// CachePath can error in case it cannot find the cwd.
// When the directory is not absolute, CachePath will try to make a
// a cache depending on the operating system.
//
// ex:
// TODO: Update this with better examples
// NOTE: cache directory will change depending on operating system dependent
// For Windows:
// PACKER_CACHE_DIR="" CacheDir() => "./packer_cache/
// PACKER_CACHE_DIR="" CacheDir("foo") => "./packer_cache/foo
// PACKER_CACHE_DIR="bar" CacheDir("foo") => "./bar/foo
// PACKER_CACHE_DIR="/home/there" CacheDir("foo", "bar") => "/home/there/foo/bar
// For Unix:
// PACKER_CACHE_DIR="", XDG_CONFIG_HOME="", Default_config CacheDir() => "$HOME/cache/packer"
// PACKER_CACHE_DIR="", XDG_CONFIG_HOME="", Default_config CacheDir("foo") => "$HOME/cache/packer/foo"
// PACKER_CACHE_DIR="bar", XDG_CONFIG_HOME="", Default_config CacheDir("foo") => "./bar/foo
// PACKER_CACHE_DIR="/home/there", XDG_CONFIG_HOME="", Default_config CacheDir("foo", "bar") => "/home/there/foo/bar
func CachePath(paths ...string) (path string, err error) {
defer func() {
// create the dir based on return path if it doesn't exist
os.MkdirAll(filepath.Dir(path), os.ModePerm)
}()
cacheDir := DefaultCacheDir
cacheDir := getDefaultCacheDir()
if cd := os.Getenv("PACKER_CACHE_DIR"); cd != "" {
cacheDir = cd
}
Expand Down
21 changes: 21 additions & 0 deletions packer/cache_config_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// +build darwin freebsd linux netbsd openbsd solaris

package packer

import (
"os"
"path/filepath"
)

func getDefaultCacheDir() string {
var defaultConfigFileDir string

if xdgCacheHome := os.Getenv("XDG_CACHE_HOME"); xdgCacheHome != "" {
return filepath.Join(xdgCacheHome, "packer")
}

homeDir := os.Getenv("HOME")
defaultConfigFileDir = filepath.Join(homeDir, ".cache", "packer")

return defaultConfigFileDir
}
108 changes: 108 additions & 0 deletions packer/cache_config_unix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// +build darwin freebsd linux netbsd openbsd solaris

package packer

import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)

func TestCachePath(t *testing.T) {
// temporary directories for env vars
xdgCacheHomeTempDir, err := ioutil.TempDir(os.TempDir(), "*")
if err != nil {
t.Fatalf("Failed to create temp test directory: failing test: %v", err)
}
defer os.RemoveAll(xdgCacheHomeTempDir)
packerCacheTempDir, err := ioutil.TempDir(os.TempDir(), "*")
if err != nil {
t.Fatalf("Failed to create temp test directory: failing test: %v", err)
}
defer os.RemoveAll(packerCacheTempDir)

// reset env
packerCacheDir := os.Getenv("PACKER_CACHE_DIR")
os.Setenv("PACKER_CACHE_DIR", "")
defer func() {
os.Setenv("PACKER_CACHE_DIR", packerCacheDir)
}()

xdgCacheHomeDir := os.Getenv("XDG_CACHE_HOME")
os.Setenv("XDG_CACHE_HOME", "")
defer func() {
os.Setenv("XDG_CACHE_HOME", xdgCacheHomeDir)
}()

type args struct {
paths []string
}
tests := []struct {
name string
args args
env map[string]string
want string
wantErr bool
}{
{
"base",
args{},
nil,
filepath.Join(os.Getenv("HOME"), ".cache", "packer"),
false,
},
{
"base and path",
args{[]string{"a", "b"}},
nil,
filepath.Join(os.Getenv("HOME"), ".cache", "packer", "a", "b"),
false,
},
{
"env PACKER_CACHE_DIR and path",
args{[]string{"a", "b"}},
map[string]string{"PACKER_CACHE_DIR": packerCacheTempDir},
filepath.Join(packerCacheTempDir, "a", "b"),
false,
},
{
"env XDG_CACHE_HOME and path",
args{[]string{"a", "b"}},
map[string]string{"XDG_CACHE_HOME": xdgCacheHomeTempDir},
filepath.Join(xdgCacheHomeTempDir, "packer", "a", "b"),
false,
},
{
"env PACKER_CACHE_DIR, XDG_CACHE_HOME, and path",
args{[]string{"a", "b"}},
map[string]string{
"XDG_CACHE_HOME": xdgCacheHomeTempDir,
"PACKER_CACHE_DIR": packerCacheTempDir,
},
filepath.Join(packerCacheTempDir, "a", "b"),
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for k, v := range tt.env {
os.Setenv(k, v)
}
got, err := CachePath(tt.args.paths...)
if (err != nil) != tt.wantErr {
t.Errorf("CachePath() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("CachePath() = %v, want %v", got, tt.want)
}
resetTestEnv()
})
}
}

func resetTestEnv() {
os.Setenv("PACKER_CACHE_DIR", "")
os.Setenv("XDG_CACHE_HOME", "")
}
11 changes: 11 additions & 0 deletions packer/cache_config_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// +build windows

package packer

const (
defaultConfigFile = "packer_cache"
)

func getDefaultCacheDir() string {
return defaultConfigFile
}
2 changes: 2 additions & 0 deletions packer/cache_test.go → packer/cache_config_windows_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// +build windows

package packer

import (
Expand Down
16 changes: 0 additions & 16 deletions pathing/config_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,6 @@ func configFile() (string, error) {
return filepath.Join(dir, defaultConfigFile), nil
}

func configDir() (string, error) {
var dir string
if cd := os.Getenv("PACKER_CONFIG_DIR"); cd != "" {
log.Printf("Detected config directory from env var: %s", cd)
dir = cd
} else {
homedir, err := homeDir()
if err != nil {
return "", err
}
dir = homedir
}

return filepath.Join(dir, defaultConfigDir), nil
}

// Given a path, check to see if it's using ~ to reference a user directory.
// If so, then replace that component with the requested user directory.
// In "~/", "~" gets replaced by current user's home dir.
Expand Down
41 changes: 41 additions & 0 deletions pathing/config_file_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,48 @@

package pathing

import (
"errors"
"log"
"os"
"path/filepath"
)

const (
defaultConfigFile = ".packerconfig"
defaultConfigDir = ".packer.d"
)

func configDir() (path string, err error) {

if cd := os.Getenv("PACKER_CONFIG_DIR"); cd != "" {
log.Printf("Detected config directory from env var: %s", cd)
return filepath.Join(cd, defaultConfigDir), nil
}

var dir string
homedir := os.Getenv("HOME")

if homedir == "" {
return "", errors.New("No $HOME environment variable found, required to set Config Directory")
}

if hasDefaultConfigFileLocation(homedir) {
dir = filepath.Join(homedir, defaultConfigDir)
log.Printf("Old default config directory found: %s", dir)
} else if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" {
log.Printf("Detected xdg config directory from env var: %s", xdgConfigHome)
dir = filepath.Join(xdgConfigHome, "packer")
} else {
dir = filepath.Join(homedir, ".config", "packer")
}

return dir, nil
}

func hasDefaultConfigFileLocation(homedir string) bool {
if _, err := os.Stat(filepath.Join(homedir, defaultConfigDir)); err != nil {
return false
}
return true
}
Loading

0 comments on commit 4c9e709

Please sign in to comment.