diff --git a/README.md b/README.md index 8301b42..e3d7a82 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,20 @@ $ ls -a .bash* .bash_logout ``` +You can also list the packages installed in a given directory. If you do not +override it with the `--target` flag, then it lists packages installed into the +current working directory by default. + +```console +$ stowaway stow dotfiles/bash stowaway/examples/git +$ stowaway packages +/home/me/stowaway/examples/git +/home/me/dotfiles/bash +$ stowaway packages --prefix /home/me/stowaway +/home/me/stowaway/examples/git +$ stowaway stow --delete dotfiles/bash stowaway/examples/git +``` + ### Interactive mode You can also pass the `--interactive` flag to the `stow` command, which will prompt the user to select which packages they want to install or uninstall from diff --git a/cmd/packages.go b/cmd/packages.go new file mode 100644 index 0000000..1c3ec10 --- /dev/null +++ b/cmd/packages.go @@ -0,0 +1,70 @@ +package cmd + +import ( + "fmt" + "log" + "os" + "path/filepath" + "strings" + + "github.com/jamesbehr/stowaway/filesystem" + "github.com/spf13/cobra" +) + +var prefix string + +var packagesCmd = &cobra.Command{ + Use: "packages", + Short: "List installed packages", + Run: func(cmd *cobra.Command, args []string) { + pwd, err := os.Getwd() + if err != nil { + log.Fatal(err) + } + + if target == "" { + target = pwd + } else { + target, err = filepath.Abs(target) + if err != nil { + log.Fatal(err) + } + } + + targetPath := filesystem.MakePath(target) + + state := targetPath.Join(".stowaway") + + files, err := state.ReadDir() + if err != nil { + log.Fatal(err) + } + + if prefix != "" { + prefix, err = filepath.Abs(prefix) + if err != nil { + log.Fatal(err) + } + } + + for _, file := range files { + if !file.IsDir() { + continue + } + + source, err := state.Join(file.Name(), "source").Readlink() + if err != nil { + log.Fatal(err) + } + + if prefix == "" || strings.HasPrefix(source.String(), prefix) { + fmt.Println(source) + } + } + }, +} + +func init() { + packagesCmd.Flags().StringVarP(&target, "target", "t", "", "directory to list installed packages for (default is $PWD)") + packagesCmd.Flags().StringVarP(&prefix, "prefix", "p", "", "only list packages that start with this") +} diff --git a/cmd/root.go b/cmd/root.go index 6c9a7dc..1356ef9 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,6 +14,7 @@ var rootCmd = &cobra.Command{ func init() { rootCmd.AddCommand(stowCmd) + rootCmd.AddCommand(packagesCmd) } func Execute() { diff --git a/filesystem/path.go b/filesystem/path.go index 5726f9a..03364b1 100644 --- a/filesystem/path.go +++ b/filesystem/path.go @@ -82,6 +82,10 @@ func (p Path) Symlink(target Path) error { return os.Symlink(string(target), string(p)) } +func (p Path) ReadDir() ([]fs.DirEntry, error) { + return os.ReadDir(string(p)) +} + func (p Path) Walk(f filepath.WalkFunc) error { fsys := os.DirFS(string(p)) return fs.WalkDir(fsys, ".", func(path string, entry fs.DirEntry, err error) error {