config

package
v0.0.0-...-d2e54b7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package config implements TOML configuration loading, validation, and platform-specific path resolution for onedrive-go. It supports a four-layer override chain (defaults -> config file -> environment -> CLI flags) with per-drive overrides that selectively replace global values.

The config file uses flat TOML keys for global settings and quoted section names containing ":" for drive configuration (e.g. ["personal:[email protected]"]).

Index

Constants

View Source
const (
	EnvConfig = "ONEDRIVE_GO_CONFIG"
	EnvDrive  = "ONEDRIVE_GO_DRIVE"
)

Environment variable names for overrides. These form the third layer in the four-layer override chain (defaults -> file -> environment -> CLI flags).

Variables

This section is empty.

Functions

func AppendDriveSection

func AppendDriveSection(path string, canonicalID driveid.CanonicalID, syncDir string) error

AppendDriveSection appends a new drive section at the end of an existing config file. Used by subsequent logins and `drive add`. The write is atomic to avoid partial writes on crash.

func BaseSyncDir

func BaseSyncDir(cid driveid.CanonicalID, orgName string) string

BaseSyncDir returns the base sync directory name for a drive type, without collision detection. Exported for use by collectOtherSyncDirs which needs the base name without triggering a collision cascade.

func CollectOtherSyncDirs

func CollectOtherSyncDirs(cfg *Config, excludeID driveid.CanonicalID, logger *slog.Logger) []string

CollectOtherSyncDirs collects sync_dir values from all drives in the config except the specified one. For drives without explicit sync_dir, computes the base name (without collision cascade) so all potential collisions are detected. Pass a zero CanonicalID to include all drives (no exclusion).

func CreateConfigWithDrive

func CreateConfigWithDrive(path string, canonicalID driveid.CanonicalID, syncDir string) error

CreateConfigWithDrive creates a new config file from the default template and appends a drive section. Used on first login when no config file exists. The write is atomic (temp file + rename) and parent directories are created as needed.

func DefaultCacheDir

func DefaultCacheDir() string

DefaultCacheDir returns the platform-specific directory for cache files. On Linux, respects XDG_CACHE_HOME (defaults to ~/.cache/onedrive-go). On macOS, uses ~/Library/Caches/onedrive-go per Apple guidelines.

func DefaultConfigDir

func DefaultConfigDir() string

DefaultConfigDir returns the platform-specific directory for config files. On Linux, respects XDG_CONFIG_HOME (defaults to ~/.config/onedrive-go). On macOS, uses ~/Library/Application Support/onedrive-go per Apple guidelines. Other platforms fall back to ~/.config/onedrive-go.

func DefaultConfigPath

func DefaultConfigPath() string

DefaultConfigPath returns the full path to the default config file. This is used as the fallback when neither ONEDRIVE_GO_CONFIG nor --config is specified.

func DefaultDataDir

func DefaultDataDir() string

DefaultDataDir returns the platform-specific directory for application data (state databases, logs, tokens). On Linux, respects XDG_DATA_HOME (defaults to ~/.local/share/onedrive-go). On macOS, uses ~/Library/Application Support/onedrive-go (macOS convention collapses config and data into one directory).

func DefaultSyncDir

func DefaultSyncDir(cid driveid.CanonicalID, orgName, displayName string, existingDirs []string) string

DefaultSyncDir computes a default sync directory for a drive. Uses a two-level scheme: base name first, disambiguated with display name then email on collision. All callers must pass existingDirs (tilde-expanded or unexpanded) for accurate collision detection.

Personal: ~/OneDrive → ~/OneDrive - {displayName} → ~/OneDrive - {email} Business: ~/OneDrive - {OrgName} → ~/OneDrive - {OrgName} - {displayName} → + {email}

(~/OneDrive - Business if no org name)

SharePoint: ~/SharePoint - {site} - {library} → + {displayName} → + {email}

func DeleteDriveSection

func DeleteDriveSection(path string, canonicalID driveid.CanonicalID) error

DeleteDriveSection removes a drive section (header + all keys) from the config file. Also removes blank lines immediately preceding the section header for clean formatting. Used by `drive remove --purge` and `logout --purge`.

func DiscoverTokens

func DiscoverTokens(logger *slog.Logger) []driveid.CanonicalID

DiscoverTokens lists token files in the default data directory and returns canonical drive IDs extracted from filenames. Token files follow the naming convention: token_{type}_{email}.json (e.g., [email protected]). Used for smart error messages and drive list.

func DriveStatePath

func DriveStatePath(canonicalID driveid.CanonicalID) string

DriveStatePath returns the state DB path for a canonical drive ID. Each drive gets its own state database. The ":" separator in canonical IDs is replaced with "_" for filesystem safety.

"personal:[email protected]" -> "{dataDir}/[email protected]"
"sharepoint:[email protected]:marketing:Docs" -> "{dataDir}/[email protected]_marketing_Docs.db"

func DriveTokenPath

func DriveTokenPath(canonicalID driveid.CanonicalID) string

DriveTokenPath returns the token file path for a canonical drive ID. SharePoint drives share the business account's token since they use the same OAuth session. For example:

"personal:[email protected]" -> "{dataDir}/[email protected]"
"sharepoint:[email protected]:marketing:Docs" -> "{dataDir}/[email protected]"

func ParseSize

func ParseSize(s string) (int64, error)

ParseSize converts a human-readable size string to bytes. Supports both SI (KB, MB, GB, TB) and IEC (KiB, MiB, GiB, TiB) suffixes. Empty string and "0" return 0. A bare number is treated as raw bytes.

func ReadTokenMetaForSyncDir

func ReadTokenMetaForSyncDir(cid driveid.CanonicalID, logger *slog.Logger) (orgName, displayName string)

ReadTokenMetaForSyncDir reads org_name and display_name from the token file's cached metadata. Returns empty strings if the token file is missing or doesn't contain metadata. Uses tokenfile.ReadMeta (leaf package) to avoid an import cycle with graph.

func SanitizePathComponent

func SanitizePathComponent(s string) string

SanitizePathComponent replaces filesystem-unsafe characters with "-". Exported for use by callers that build path components from user data.

func SetDriveKey

func SetDriveKey(path string, canonicalID driveid.CanonicalID, key, value string) error

SetDriveKey finds a drive section by canonical ID and sets a key-value pair. If the key already exists within the section, its line is replaced. If not found, the key is inserted on the line after the section header. Used by `drive remove` to set `enabled = false`.

Value formatting: booleans ("true"/"false") are written without quotes; all other values are written as quoted strings.

func UploadSessionDir

func UploadSessionDir() string

UploadSessionDir returns the directory for persisted upload session files. These are JSON files containing pre-authenticated upload URLs, stored with 0700 directory permissions for security.

func Validate

func Validate(cfg *Config) error

Validate checks all configuration values and returns all errors found. It accumulates every error rather than stopping at the first, so users see a complete report and can fix all issues in one pass.

func ValidateResolved

func ValidateResolved(rd *ResolvedDrive) error

ValidateResolved checks cross-field constraints on a fully resolved drive. Unlike Validate(), which checks raw config file values, this runs after the four-layer override chain (defaults -> file -> env -> CLI) has been applied. It catches constraints that only make sense on the final merged result.

func WarnUnimplemented

func WarnUnimplemented(rd *ResolvedDrive, logger *slog.Logger)

WarnUnimplemented logs a warning for each config field that is set to a non-default value but is not yet implemented. This prevents users from thinking their settings take effect when they silently don't (B-141).

Types

type BandwidthScheduleEntry

type BandwidthScheduleEntry struct {
	Time  string `toml:"time"`
	Limit string `toml:"limit"`
}

BandwidthScheduleEntry defines a time-of-day bandwidth limit. Entries must be sorted chronologically.

type CLIOverrides

type CLIOverrides struct {
	ConfigPath string // --config flag (empty = use default)
	Account    string // --account flag (auth commands)
	Drive      string // --drive flag (drive selection)
	DryRun     *bool  // --dry-run flag
}

CLIOverrides holds values from CLI flags that override config file and environment settings. Pointer fields distinguish "not specified" (nil) from "explicitly set to zero value" — this matters because --dry-run=false is different from not passing --dry-run at all.

type Config

type Config struct {
	FilterConfig
	TransfersConfig
	SafetyConfig
	SyncConfig
	LoggingConfig
	NetworkConfig
	Drives map[driveid.CanonicalID]Drive `toml:"-"` // parsed via two-pass decode, keyed by canonical ID
}

Config is the top-level configuration structure. Global settings live in embedded sub-structs, which BurntSushi/toml promotes to flat TOML keys. Drive sections use quoted headers containing ":" and are parsed in a separate decode pass. Map keys are validated CanonicalIDs — invalid keys are rejected at parse time.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a Config populated with all default values. This is used both as the starting point for TOML decoding (so unset fields retain defaults) and as the fallback when no config file exists.

func Load

func Load(path string, logger *slog.Logger) (*Config, error)

Load reads and parses a TOML config file using a two-pass decode, validates it, and returns the resulting Config. Pass 1 decodes flat global settings into embedded structs. Pass 2 extracts drive sections (keys containing ":"). Unknown keys are treated as fatal errors with "did you mean?" suggestions.

func LoadOrDefault

func LoadOrDefault(path string, logger *slog.Logger) (*Config, error)

LoadOrDefault reads a TOML config file if it exists, otherwise returns a Config populated with all default values. This supports the zero-config first-run experience: users can start without creating a config file.

type Drive

type Drive struct {
	SyncDir      string   `toml:"sync_dir"`
	StateDir     string   `toml:"state_dir,omitempty"` // override state DB directory (default: platform data dir)
	Enabled      *bool    `toml:"enabled,omitempty"`
	Alias        string   `toml:"alias,omitempty"`
	RemotePath   string   `toml:"remote_path,omitempty"`
	DriveID      string   `toml:"drive_id,omitempty"`
	SkipDotfiles *bool    `toml:"skip_dotfiles,omitempty"`
	SkipDirs     []string `toml:"skip_dirs,omitempty"`
	SkipFiles    []string `toml:"skip_files,omitempty"`
	PollInterval string   `toml:"poll_interval,omitempty"`
}

Drive represents a single synced drive in the config file. Drive sections are keyed by canonical IDs like "personal:[email protected]". Per-drive fields override global settings when set (pointer fields distinguish "not specified" from "set to zero value").

func MatchDrive

func MatchDrive(cfg *Config, selector string, logger *slog.Logger) (driveid.CanonicalID, Drive, error)

MatchDrive selects a drive from the config by selector string. The matching precedence is: exact canonical ID > alias > partial canonical ID substring. If selector is empty, auto-selects when exactly one drive is configured.

When no drives are configured, provides smart error messages: checks for existing tokens on disk and suggests "drive add" or "login" accordingly.

type EnvOverrides

type EnvOverrides struct {
	ConfigPath string // ONEDRIVE_GO_CONFIG: override config file path
	Drive      string // ONEDRIVE_GO_DRIVE: drive selector (canonical ID, alias, or partial match)
}

EnvOverrides holds values derived from environment variables. These are resolved by ReadEnvOverrides and passed to ResolveDrive() for application in the correct precedence order.

func ReadEnvOverrides

func ReadEnvOverrides(logger *slog.Logger) EnvOverrides

ReadEnvOverrides reads environment variables and returns any overrides found. This does not modify the Config; callers pass the result to ResolveDrive().

type FilterConfig

type FilterConfig struct {
	SkipFiles    []string `toml:"skip_files"`
	SkipDirs     []string `toml:"skip_dirs"`
	SkipDotfiles bool     `toml:"skip_dotfiles"`
	SkipSymlinks bool     `toml:"skip_symlinks"`
	MaxFileSize  string   `toml:"max_file_size"`
	SyncPaths    []string `toml:"sync_paths"`
	IgnoreMarker string   `toml:"ignore_marker"`
}

FilterConfig controls which files and directories are included in sync. These patterns are matched against the relative path within the sync directory.

type LoggingConfig

type LoggingConfig struct {
	LogLevel         string `toml:"log_level"`
	LogFile          string `toml:"log_file"`
	LogFormat        string `toml:"log_format"`
	LogRetentionDays int    `toml:"log_retention_days"`
}

LoggingConfig controls log output behavior: level, format, and rotation.

type NetworkConfig

type NetworkConfig struct {
	ConnectTimeout string `toml:"connect_timeout"`
	DataTimeout    string `toml:"data_timeout"`
	UserAgent      string `toml:"user_agent"`
	ForceHTTP11    bool   `toml:"force_http_11"`
}

NetworkConfig controls HTTP client behavior: timeouts, user agent, and protocol version. force_http_11 is useful behind corporate proxies that don't support HTTP/2.

type ResolvedDrive

type ResolvedDrive struct {
	CanonicalID driveid.CanonicalID
	Alias       string
	Enabled     bool
	SyncDir     string // absolute path after tilde expansion
	StateDir    string // override for state DB directory (empty = platform default)
	RemotePath  string
	DriveID     driveid.ID

	FilterConfig
	TransfersConfig
	SafetyConfig
	SyncConfig
	LoggingConfig
	NetworkConfig
}

ResolvedDrive contains drive fields plus effective config sections after merging global defaults with per-drive overrides and CLI/env flags. This is the final product consumed by the CLI and sync engine.

func ResolveDrive

func ResolveDrive(env EnvOverrides, cli CLIOverrides, logger *slog.Logger) (*ResolvedDrive, error)

ResolveDrive loads configuration and applies the four-layer override chain: defaults -> config file -> environment variables -> CLI flags. It returns a fully resolved and validated drive configuration ready for use.

func (*ResolvedDrive) StatePath

func (rd *ResolvedDrive) StatePath() string

StatePath returns the state DB file path for this drive. When StateDir is set, the DB is placed inside that directory instead of the platform default data directory. This allows E2E tests to use per-test temp dirs for isolation.

type SafetyConfig

type SafetyConfig struct {
	BigDeleteThreshold        int    `toml:"big_delete_threshold"`
	BigDeletePercentage       int    `toml:"big_delete_percentage"`
	BigDeleteMinItems         int    `toml:"big_delete_min_items"`
	MinFreeSpace              string `toml:"min_free_space"`
	UseRecycleBin             bool   `toml:"use_recycle_bin"`
	UseLocalTrash             bool   `toml:"use_local_trash"`
	DisableDownloadValidation bool   `toml:"disable_download_validation"`
	DisableUploadValidation   bool   `toml:"disable_upload_validation"`
	SyncDirPermissions        string `toml:"sync_dir_permissions"`
	SyncFilePermissions       string `toml:"sync_file_permissions"`
}

SafetyConfig controls protective defaults and thresholds that prevent accidental data loss during sync operations.

type SyncConfig

type SyncConfig struct {
	PollInterval             string `toml:"poll_interval"`
	FullscanFrequency        int    `toml:"fullscan_frequency"`
	Websocket                bool   `toml:"websocket"`
	ConflictStrategy         string `toml:"conflict_strategy"`
	ConflictReminderInterval string `toml:"conflict_reminder_interval"`
	DryRun                   bool   `toml:"dry_run"`
	VerifyInterval           string `toml:"verify_interval"`
	ShutdownTimeout          string `toml:"shutdown_timeout"`
}

SyncConfig controls sync engine behavior: polling intervals, conflict resolution strategy, and graceful shutdown timing.

type TransfersConfig

type TransfersConfig struct {
	ParallelDownloads int                      `toml:"parallel_downloads"`
	ParallelUploads   int                      `toml:"parallel_uploads"`
	ParallelCheckers  int                      `toml:"parallel_checkers"`
	ChunkSize         string                   `toml:"chunk_size"`
	BandwidthLimit    string                   `toml:"bandwidth_limit"`
	BandwidthSchedule []BandwidthScheduleEntry `toml:"bandwidth_schedule"`
	TransferOrder     string                   `toml:"transfer_order"`
}

TransfersConfig controls parallel workers, chunk sizes, and bandwidth limits. The chunk_size must be a multiple of 320 KiB per the OneDrive upload API spec.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL