diff --git a/Makefile b/Makefile index d35b794..f208980 100644 --- a/Makefile +++ b/Makefile @@ -4,4 +4,4 @@ help: ## display this help @awk 'BEGIN{FS = ":.*##"; printf "\033[1m\nUsage\n \033[1;92m make\033[0;36m \033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } ' $(MAKEFILE_LIST) serve: ## Run "intake serve" with live reload - @air -build.cmd "go build -o tmp/intake" -build.bin tmp/intake -build.args_bin serve,--db,tmp/db.sqlite + @air -build.cmd "go build -o tmp/intake" -build.bin tmp/intake -build.args_bin serve,--data-dir,tmp diff --git a/README.md b/README.md index 6950911..043e54d 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ When a deactivated item is no longer returned by `fetch`, it is deleted. This allows you to consume feed content at your own pace without missing anything. Intake stores all its data in a SQLite database. +This database is stored in `$INTAKE_DATA_DIR`, `$XDG_DATA_HOME/intake`, or `$HOME/.local/share/intake`, whichever is resolved first. +The database can also be specified on the command line via `--data-dir`/`-d` instead of the environment. ### Items diff --git a/cmd/root.go b/cmd/root.go index 6d97c70..bfd0b22 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -23,14 +23,14 @@ func Execute() { } } -var dbPath string +var dataPath string func init() { // Disable the automatic help command rootCmd.SetHelpCommand(&cobra.Command{Hidden: true}) // All commands need to operate on a database - rootCmd.PersistentFlags().StringVarP(&dbPath, "db", "d", "", "Path to the intake sqlite database (default: INTAKE_DB)") + rootCmd.PersistentFlags().StringVarP(&dataPath, "data-dir", "d", "", "Path to the intake data directory containing the database") } // @@ -38,22 +38,22 @@ func init() { // func getDbPath() string { - if dbPath != "" { - return dbPath + if dataPath != "" { + return core.DatabasePath(dataPath) } - env := os.Getenv("INTAKE_DB") - if env != "" { - return env + if dataDir := core.ResolveDataDir(); dataDir != "" { + return core.DatabasePath(dataDir) } fmt.Println("error: no database specified") - fmt.Println("Either --db or the environment variable INTAKE_DB must be set.") + fmt.Println("One of --data-dir, INTAKE_DATA_DIR, XDG_DATA_HOME, or HOME must be defined.") os.Exit(1) return "" } // Attempt to open the specified database and exit with an error if it fails. func openDb() *core.DB { - db, err := core.OpenDb(getDbPath()) + dbPath := getDbPath() + db, err := core.OpenDb(dbPath) if err != nil { log.Fatalf("error: failed to open %s", dbPath) } diff --git a/core/data.go b/core/data.go new file mode 100644 index 0000000..51bf025 --- /dev/null +++ b/core/data.go @@ -0,0 +1,21 @@ +package core + +import ( + "os" + "path/filepath" +) + +func ResolveDataDir() string { + if intakeData := os.Getenv("INTAKE_DATA_DIR"); intakeData != "" { + return intakeData + } else if xdgData := os.Getenv("XDG_DATA_HOME"); xdgData != "" { + return filepath.Join(xdgData, "intake") + } else if home := os.Getenv("HOME"); home != "" { + return filepath.Join(home, ".local", "share", "intake") + } + return "" +} + +func DatabasePath(dataDir string) string { + return filepath.Join(dataDir, "intake.db") +} diff --git a/test/test_items.sh b/test/test_items.sh index a38b04c..2e946b7 100755 --- a/test/test_items.sh +++ b/test/test_items.sh @@ -2,8 +2,8 @@ set -eu go build -o tmp/intake -rm "$1" || true -export INTAKE_DB="$1" +rm tmp/intake.db* || true +export INTAKE_DATA_DIR="tmp" tmp/intake migrate tmp/intake source add -s feedtest tmp/intake item add -s feedtest --id "this-item-has-no-title"