2024-09-09 18:02:53 +01:00
|
|
|
//go:build mage
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io/fs"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"slices"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2024-09-10 08:41:31 +01:00
|
|
|
dirModePerm fs.FileMode = 0o700
|
2024-09-09 18:02:53 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Directories ensure that the directories specified in the configuration is present within the home directory.
|
|
|
|
func Directories() error {
|
|
|
|
config, err := newConfig()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unable to load the configuration: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
userHome, err := os.UserHomeDir()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unable to get the user's home directory: %w", err)
|
|
|
|
}
|
|
|
|
|
2024-09-10 08:41:31 +01:00
|
|
|
directories := make([]string, 0)
|
|
|
|
|
|
|
|
if config.Directories.UseDefaultDirectories{
|
|
|
|
defaultHomeDirs := homeDirectories(userHome, defaultDirectories())
|
|
|
|
directories = append(directories, defaultHomeDirs...)
|
|
|
|
}
|
2024-09-09 18:02:53 +01:00
|
|
|
|
2024-09-10 08:41:31 +01:00
|
|
|
if config.Directories.IncludeXDGDirectories{
|
|
|
|
directories = append(directories, xdgDirectories()...)
|
2024-09-09 18:02:53 +01:00
|
|
|
}
|
|
|
|
|
2024-09-10 08:41:31 +01:00
|
|
|
if len(config.Directories.AdditionalDirectories) != 0 {
|
|
|
|
additionalHomeDirs := homeDirectories(userHome, config.Directories.AdditionalDirectories)
|
|
|
|
directories = append(directories, additionalHomeDirs...)
|
|
|
|
}
|
2024-09-09 18:02:53 +01:00
|
|
|
|
2024-09-10 08:41:31 +01:00
|
|
|
for _, dir := range slices.All(directories) {
|
|
|
|
if err := ensureDirectory(dir); err != nil {
|
|
|
|
return fmt.Errorf("unable to ensure that %s is present: %w", dir, err)
|
|
|
|
}
|
2024-09-09 18:02:53 +01:00
|
|
|
|
2024-09-10 08:41:31 +01:00
|
|
|
fmt.Printf("Successfully ensured %s is present.\n", dir)
|
|
|
|
}
|
2024-09-09 18:02:53 +01:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func ensureDirectory(path string) error {
|
2024-09-10 08:41:31 +01:00
|
|
|
info, err := os.Stat(path)
|
2024-09-09 18:02:53 +01:00
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, os.ErrNotExist) {
|
|
|
|
if err := os.Mkdir(path, dirModePerm); err != nil {
|
|
|
|
return fmt.Errorf("unable to create the directory: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-09-10 08:41:31 +01:00
|
|
|
return fmt.Errorf(
|
|
|
|
"received an unexpected error after attempting to get the directory information: %w",
|
|
|
|
err,
|
|
|
|
)
|
2024-09-09 18:02:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if !info.IsDir() {
|
|
|
|
return errors.New("the path exists but it is not a directory")
|
|
|
|
}
|
|
|
|
|
|
|
|
if info.Mode().Perm() != dirModePerm {
|
|
|
|
if err := os.Chmod(path, dirModePerm); err != nil {
|
|
|
|
return fmt.Errorf("unable to update the directory's mode to %d: %w", dirModePerm, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2024-09-10 08:41:31 +01:00
|
|
|
|
|
|
|
func defaultDirectories() []string {
|
|
|
|
return []string{
|
|
|
|
".local",
|
|
|
|
".local/bin",
|
|
|
|
"Applications",
|
|
|
|
"Documents",
|
|
|
|
"Downloads",
|
|
|
|
"Games",
|
|
|
|
"Git",
|
|
|
|
"Music",
|
|
|
|
"Pictures",
|
|
|
|
"Templates",
|
|
|
|
"Videos",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func homeDirectories(userHome string, directories []string) []string{
|
|
|
|
absolutePaths := make([]string, len(directories))
|
|
|
|
|
|
|
|
for ind := range slices.All(directories) {
|
|
|
|
absolutePaths[ind] = filepath.Join(userHome, directories[ind])
|
|
|
|
}
|
|
|
|
|
|
|
|
return absolutePaths
|
|
|
|
}
|
|
|
|
|
|
|
|
func xdgDirectories() []string {
|
|
|
|
xdgEnvVars := []string{
|
|
|
|
"XDG_DATA_HOME",
|
|
|
|
"XDG_CONFIG_HOME",
|
|
|
|
"XDG_CACHE_HOME",
|
|
|
|
"XDG_STATE_HOME",
|
|
|
|
}
|
|
|
|
|
|
|
|
directories := make([]string, 0)
|
|
|
|
|
|
|
|
for _, envVar := range slices.All(xdgEnvVars) {
|
|
|
|
directory := os.Getenv(envVar)
|
|
|
|
if directory != "" {
|
|
|
|
directories = append(directories, directory)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return directories
|
|
|
|
}
|