Documentation
¶
Overview ¶
Package paths provides centralized path handling for dodot.
This package implements the XDG Base Directory specification and provides a consistent API for all path operations throughout the dodot codebase. It handles:
- Dotfiles root directory discovery and configuration
- XDG directory structure (data, config, cache)
- Path normalization and expansion
- Pack-specific path generation
- State and backup file locations
Environment Variables ¶
The package respects the following environment variables:
- DOTFILES_ROOT: Primary location for dotfiles (default: ~/dotfiles)
- DODOT_DATA_DIR: Override XDG data directory (default: $XDG_DATA_HOME/dodot)
- DODOT_CONFIG_DIR: Override XDG config directory (default: $XDG_CONFIG_HOME/dodot)
- DODOT_CACHE_DIR: Override XDG cache directory (default: $XDG_CACHE_HOME/dodot)
XDG Base Directory Structure ¶
dodot follows the XDG Base Directory specification:
- Data: $XDG_DATA_HOME/dodot (persistent data, state files, backups)
- Config: $XDG_CONFIG_HOME/dodot (user configuration)
- Cache: $XDG_CACHE_HOME/dodot (temporary files, caches)
Usage ¶
import "github.com/arthur-debert/dodot/pkg/paths"
// Create a new Paths instance
p, err := paths.New("") // Auto-detect dotfiles root
if err != nil {
log.Fatal(err)
}
// Get various paths
root := p.DotfilesRoot() // /home/user/dotfiles
packPath := p.PackPath("vim") // /home/user/dotfiles/vim
stateFile := p.StatePath("vim", "install") // $XDG_DATA_HOME/dodot/state/vim/install.json
// Check if a path is within dotfiles
isInside, err := p.IsInDotfiles("/home/user/dotfiles/vim/vimrc")
// isInside == true
Package paths provides centralized path handling for dodot. It implements XDG Base Directory specification compliance and provides a consistent API for all path operations in the codebase.
Index ¶
- Constants
- func CommonPrefix(paths ...string) string
- func ContainsPath(parent, child string) bool
- func ExpandHome(path string) string
- func GetHomeDirectory() (string, error)
- func GetHomeDirectoryWithDefault(defaultDir string) string
- func GetShellScriptPath(shell string) string
- func IsAbsolutePath(path string) bool
- func IsHiddenPath(path string) bool
- func JoinPaths(elem ...string) (string, error)
- func MustValidatePath(path string)
- func PathDepth(path string) int
- func RelativePath(base, target string) (string, error)
- func ResolveShellScriptPath(scriptName string) (string, error)
- func SanitizePath(path string) string
- func SplitPath(path string) (dir, file string)
- func ValidatePackName(name string) error
- func ValidatePath(path string) error
- func ValidatePathSecurity(path string) error
- type Paths
- func (p *Paths) BackupsDir() string
- func (p *Paths) CacheDir() string
- func (p *Paths) ConfigDir() string
- func (p *Paths) DataDir() string
- func (p *Paths) DeployedDir() string
- func (p *Paths) DotfilesRoot() string
- func (p *Paths) GetDataSubdir(name string) string
- func (p *Paths) GetDeployedSubdir(name string) string
- func (p *Paths) HomebrewDir() string
- func (p *Paths) InitScriptPath() string
- func (p *Paths) InstallDir() string
- func (p *Paths) IsInDotfiles(path string) (bool, error)
- func (p *Paths) LogFilePath() string
- func (p *Paths) NormalizePath(path string) (string, error)
- func (p *Paths) PackConfigPath(packName string) string
- func (p *Paths) PackPath(packName string) string
- func (p *Paths) PathDir() string
- func (p *Paths) SentinelPath(powerUpType, packName string) string
- func (p *Paths) ShellDir() string
- func (p *Paths) ShellProfileDir() string
- func (p *Paths) ShellSourceDir() string
- func (p *Paths) StateDir() string
- func (p *Paths) StatePath(packName, powerUpName string) string
- func (p *Paths) SymlinkDir() string
- func (p *Paths) TemplatesDir() string
- func (p *Paths) UsedFallback() bool
Constants ¶
const ( // EnvDotfilesRoot is the primary environment variable for dotfiles location EnvDotfilesRoot = "DOTFILES_ROOT" // EnvDodotDataDir overrides the XDG data directory for dodot EnvDodotDataDir = "DODOT_DATA_DIR" // EnvDodotConfigDir overrides the XDG config directory for dodot EnvDodotConfigDir = "DODOT_CONFIG_DIR" // EnvDodotCacheDir overrides the XDG cache directory for dodot EnvDodotCacheDir = "DODOT_CACHE_DIR" // EnvHome is the standard home directory variable EnvHome = "HOME" )
Environment variable names
const ( // DefaultDotfilesDir is the default directory name for dotfiles DefaultDotfilesDir = "dotfiles" // DodotDirName is the directory name for dodot-specific files DodotDirName = "dodot" // PackConfigFile is the name of the pack configuration file PackConfigFile = ".dodot.toml" // StateDir is the subdirectory for state files StateDir = "state" // BackupsDir is the subdirectory for backups BackupsDir = "backups" // TemplatesDir is the subdirectory for templates TemplatesDir = "templates" // DeployedDir is the subdirectory for deployed files DeployedDir = "deployed" // ShellDir is the subdirectory for shell scripts ShellDir = "shell" // InstallDir is the subdirectory for install sentinels InstallDir = "install" // HomebrewDir is the subdirectory for homebrew sentinels HomebrewDir = "homebrew" // InitScriptName is the name of the init script InitScriptName = "dodot-init.sh" // LogFileName is the name of the log file LogFileName = "dodot.log" )
Default directories and files
Variables ¶
This section is empty.
Functions ¶
func CommonPrefix ¶
CommonPrefix returns the longest common prefix of the provided paths. Returns empty string if paths have no common prefix.
func ContainsPath ¶
ContainsPath checks if child is contained within parent. Both paths are normalized before comparison.
func ExpandHome ¶
ExpandHome is a utility function that expands ~ in paths This is exposed for compatibility with existing code
func GetHomeDirectory ¶
GetHomeDirectory returns the user's home directory with proper error handling This is migrated from pkg/utils/home.go
func GetHomeDirectoryWithDefault ¶
GetHomeDirectoryWithDefault returns the home directory or a default value This is migrated from pkg/utils/home.go
func GetShellScriptPath ¶ added in v0.1.1
GetShellScriptPath returns the path to the shell integration script It uses the resolved path if found, otherwise returns the expected installation path
func IsAbsolutePath ¶
IsAbsolutePath returns true if the path is absolute. This is a cross-platform wrapper around filepath.IsAbs.
func IsHiddenPath ¶
IsHiddenPath returns true if the path represents a hidden file or directory. On Unix-like systems, this means the basename starts with a dot. On Windows, this would check file attributes (not implemented here).
func JoinPaths ¶
JoinPaths safely joins path elements, ensuring proper separators. This is a wrapper around filepath.Join that also validates the result.
func MustValidatePath ¶
func MustValidatePath(path string)
MustValidatePath panics if the path is invalid. This should only be used with hardcoded paths that must be valid.
func PathDepth ¶
PathDepth returns the depth of a path (number of directories). For example: "/" = 0, "/a" = 1, "/a/b" = 2
func RelativePath ¶
RelativePath returns the relative path from base to target. Returns an error if the paths cannot be made relative.
func ResolveShellScriptPath ¶ added in v0.1.1
ResolveShellScriptPath finds the shell integration script with fallback logic It first tries the installed location, then falls back to development location
func SanitizePath ¶
SanitizePath attempts to clean and make a path safe for use. It: - Normalizes path separators - Removes redundant separators - Resolves . and .. elements - Removes trailing separators (except for root)
func SplitPath ¶
SplitPath splits a path into its directory and file components. This is a wrapper around filepath.Split that also handles edge cases.
func ValidatePackName ¶
ValidatePackName ensures a pack name is valid for use in paths. Pack names must: - Not be empty - Not contain path separators - Not contain special characters that could cause issues - Not be reserved names (. or ..)
func ValidatePath ¶
ValidatePath performs comprehensive validation on a path. It checks for: - Empty paths - Invalid characters (on Windows) - Path traversal attempts - Excessive path length
func ValidatePathSecurity ¶
ValidatePathSecurity performs security-focused validation on a path. It checks for common path traversal attacks and suspicious patterns.
Types ¶
type Paths ¶
type Paths struct {
// contains filtered or unexported fields
}
Paths provides centralized path management for dodot
func New ¶
New creates a new Paths instance with the given dotfiles root. If dotfilesRoot is empty, it will be determined from environment variables or defaults.
func (*Paths) BackupsDir ¶
BackupsDir returns the directory for backup files
func (*Paths) DeployedDir ¶
DeployedDir returns the deployed directory path
func (*Paths) DotfilesRoot ¶
DotfilesRoot returns the root directory for dotfiles
func (*Paths) GetDataSubdir ¶
GetDataSubdir returns a subdirectory path under the XDG data directory. This is a helper method to reduce boilerplate for the many data subdirectories.
func (*Paths) GetDeployedSubdir ¶
GetDeployedSubdir returns a subdirectory path under the deployed directory. This is a helper method to reduce boilerplate for the deployed subdirectories.
func (*Paths) HomebrewDir ¶ added in v0.1.1
HomebrewDir returns the homebrew sentinel directory
func (*Paths) InitScriptPath ¶
InitScriptPath returns the path to the dodot-init.sh script
func (*Paths) InstallDir ¶
InstallDir returns the install scripts sentinel directory
func (*Paths) IsInDotfiles ¶
IsInDotfiles checks if a path is within the dotfiles root
func (*Paths) LogFilePath ¶
LogFilePath returns the path to the dodot log file Respects XDG_STATE_HOME if set
func (*Paths) NormalizePath ¶
NormalizePath normalizes a path by expanding home, making it absolute, and cleaning it
func (*Paths) PackConfigPath ¶
PackConfigPath returns the path to a pack's configuration file
func (*Paths) SentinelPath ¶ added in v0.1.3
SentinelPath returns the path to a sentinel file for a given powerup and pack. This provides a unified way to construct sentinel file paths across the codebase. The sentinel file is used to track whether a run-once action has been executed.
The path structure is: <DataDir>/<powerUpType>/<packName> For example: ~/.local/share/dodot/install/vim
Currently supported powerUpTypes:
- "install" - for install.sh scripts
- "homebrew" - for Brewfile executions
func (*Paths) ShellProfileDir ¶
ShellProfileDir returns the shell profile deployment directory
func (*Paths) ShellSourceDir ¶
ShellSourceDir returns the shell source deployment directory
func (*Paths) StatePath ¶
StatePath returns the path to a state file for a specific pack and powerup
func (*Paths) SymlinkDir ¶
SymlinkDir returns the symlink deployment directory
func (*Paths) TemplatesDir ¶
TemplatesDir returns the directory for template files
func (*Paths) UsedFallback ¶ added in v0.1.0
UsedFallback returns true if the current working directory was used as fallback