Skip to content

Commit

Permalink
Merge pull request #865 from rsteube/action-chdirf
Browse files Browse the repository at this point in the history
added Action.ChdirF
  • Loading branch information
rsteube committed Jul 30, 2023
2 parents 17c20e8 + 55018d1 commit 8245a20
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 1 deletion.
12 changes: 12 additions & 0 deletions action.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/rsteube/carapace/internal/lexer"
pkgcache "github.com/rsteube/carapace/pkg/cache"
"github.com/rsteube/carapace/pkg/style"
pkgtraverse "github.com/rsteube/carapace/pkg/traverse"
)

// Action indicates how to complete a flag or positional argument.
Expand Down Expand Up @@ -72,6 +73,17 @@ func (a Action) Chdir(dir string) Action {
})
}

// ChdirF is like Chdir but uses a function.
func (a Action) ChdirF(f func(tc pkgtraverse.Context) (string, error)) Action {
return ActionCallback(func(c Context) Action {
newDir, err := f(c)
if err != nil {
return ActionMessage(err.Error())
}
return a.Chdir(newDir)
})
}

// Filter filters given values.
//
// carapace.ActionValues("A", "B", "C").Filter([]string{"B"}) // ["A", "C"]
Expand Down
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [Action](./carapace/action.md)
- [Cache](./carapace/action/cache.md)
- [Chdir](./carapace/action/chdir.md)
- [ChdirF](./carapace/action/chdirF.md)
- [Filter](./carapace/action/filter.md)
- [Invoke](./carapace/action/invoke.md)
- [List](./carapace/action/list.md)
Expand Down
78 changes: 78 additions & 0 deletions docs/src/carapace/action/chdirF.cast
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{"version": 2, "width": 108, "height": 24, "timestamp": 1690737535, "env": {"SHELL": "elvish", "TERM": "tmux-256color"}}
[0.092459, "o", "\u001b[?7h\u001b[7m⏎\u001b[m \r \r\u001b[?7l\u001b[?2004h"]
[0.093001, "o", "\u001b[?25l\r???> ???> \r\u001b[5C\u001b[?25h\u001b[?25l\r\u001b[5C\u001b[K\r\u001b[5C\u001b[?25h"]
[0.108398, "o", "\u001b[?25l\r\u001b[K\r\n\u001b[0;1;36mcarapace/example\u001b[0;m on \u001b[0;1;35m action-chdirf\u001b[0;m \u001b[0;1;31m[$!?]\u001b[0;m via \u001b[0;1;36m🐹 v1.20.6 \r\n\u001b[0;1;37mesh\u001b[0;m \u001b[0;1;32m❯\u001b[0;m \r\u001b[6C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[0.349581, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[0;31me\u001b[0;m\r\u001b[7C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.349882, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.365076, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.365192, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.523566, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[7C\u001b[0;31mx\u001b[0;m\r\u001b[8C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[8C\u001b[?25h"]
[0.73246, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexa\u001b[0;m\r\u001b[9C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[9C\u001b[?25h"]
[0.905226, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;31mexam\u001b[0;m\r\u001b[10C\u001b[?25h"]
[0.905307, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[10C\u001b[?25h"]
[1.039568, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[10C\u001b[0;31mp\u001b[0;m\r\u001b[11C\u001b[?25h"]
[1.039657, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[11C\u001b[?25h"]
[1.164604, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[11C\u001b[0;31ml\u001b[0;m\r\u001b[12C\u001b[?25h"]
[1.164681, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[12C\u001b[?25h"]
[1.25928, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexample\u001b[0;m\r\u001b[13C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[13C\u001b[?25h"]
[1.329448, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[13C \r\u001b[14C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[14C\u001b[?25h"]
[1.435507, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[14Ca\r\u001b[15C\u001b[?25h"]
[1.435599, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[15C\u001b[?25h"]
[1.537323, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[15Cc\r\u001b[16C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[16C\u001b[?25h"]
[1.729619, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[16Ction \r\u001b[21C\u001b[?25h"]
[2.137944, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[21C-\r\u001b[22C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[22C\u001b[?25h"]
[2.293727, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[22C-\r\u001b[23C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[23C\u001b[?25h"]
[2.347265, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[23Cf\r\u001b[24C\u001b[?25h"]
[2.458612, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[24Ci\r\u001b[25C\u001b[?25h"]
[2.458703, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[25C\u001b[?25h"]
[2.555516, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[25Cles\r\u001b[28C\u001b[?25h"]
[2.893802, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[28C \r\u001b[29C\u001b[?25h"]
[2.974574, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[29C\u001b[0;4mREADME.md \r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7;38;2;255;184;108mREADME.md\u001b[0;m \u001b[0;38;2;189;147;249m_test/\u001b[0;m \u001b[0;38;2;189;147;249mcmd/\u001b[0;m \u001b[0;38;2;255;184;108mmain.go\u001b[0;m \u001b[0;38;2;255;184;108mmain_test.go\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[3.743225, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[29C\u001b[K\u001b[0;4m_test/\r\n\r\n\u001b[0;m\u001b[K\u001b[0;38;2;255;184;108mREADME.md\u001b[0;m \u001b[0;7;38;2;189;147;249m_test/\u001b[0;m \u001b[0;38;2;189;147;249mcmd/\u001b[0;m \u001b[0;38;2;255;184;108mmain.go\u001b[0;m \u001b[0;38;2;255;184;108mmain_test.go\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[3.880629, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[29C\u001b[K\u001b[0;4mcmd/\r\n\r\n\u001b[11C\u001b[0;m\u001b[K\u001b[0;38;2;189;147;249m_test/\u001b[0;m \u001b[0;7;38;2;189;147;249mcmd/\u001b[0;m \u001b[0;38;2;255;184;108mmain.go\u001b[0;m \u001b[0;38;2;255;184;108mmain_test.go\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[3.981609, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[29C\u001b[Kcmd/\r\n\u001b[J\u001b[A\r\u001b[33C\u001b[?25h"]
[3.981681, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[33C\u001b[?25h"]
[4.112655, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[29C\u001b[K\u001b[0;4mcmd/_test/\r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7;38;2;189;147;249m_test/ \u001b[0;m \u001b[0;38;2;255;184;108mchain.go \u001b[0;m \u001b[0;38;2;255;184;108mhelp_test.go \u001b[0;m \u001b[0;38;2;255;184;108mmodifier_test.go \u001b[0;m \u001b[0;38;2;255;184;108mroot_test.go\r\n\u001b[0;38;2;189;147;249m_test_files/ \u001b[0;m \u001b[0;38;2;255;184;108mchain_test.go\u001b[0;m \u001b[0;38;2;255;184;108minterspersed.go \u001b[0;m \u001b[0;38;2;255;184;108mmultiparts.go \u001b[0;m \u001b[0;38;2;255;184;108mspecial.go \r\naction.go \u001b[0;m \u001b[0;38;2;255;184;108mflag.go \u001b[0;m \u001b[0;38;2;255;184;108minterspersed_test.go\u001b[0;m \u001b[0;38;2;255;184;108mmultiparts_test.go\r\naction_test.go\u001b[0;m \u001b[0;38;2;255;184;108mgroup.go \u001b[0;m \u001b[0;38;2;255;184;108mmodifier.go \u001b[0;m \u001b[0;38;2;255;184;108mroot.go \u001b[0;m\u001b[4A\r\u001b[22C\u001b[?25h"]
[5.241304, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[6C\u001b[K\r\n\u001b[J\u001b[A\r\u001b[6C\u001b[?25h"]
[5.241737, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[5.24199, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[5.260033, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[5.26021, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[5.455256, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[0;31me\u001b[0;m\r\u001b[7C\u001b[?25h"]
[5.455694, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[5.457, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[5.67326, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[7C\u001b[0;31mx\u001b[0;m\r\u001b[8C\u001b[?25h"]
[5.876588, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexa\u001b[0;m\r\u001b[9C\u001b[?25h"]
[6.039265, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;31mexam\u001b[0;m\r\u001b[10C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[10C\u001b[?25h"]
[6.134917, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[10C\u001b[0;31mp\u001b[0;m\r\u001b[11C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[11C\u001b[?25h"]
[6.308619, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[11C\u001b[0;31ml\u001b[0;m\r\u001b[12C\u001b[?25h"]
[6.308725, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[12C\u001b[?25h"]
[6.461986, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexample\u001b[0;m\r\u001b[13C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[13C\u001b[?25h"]
[6.610441, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[13C \r\u001b[14C\u001b[?25h"]
[6.610555, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[14C\u001b[?25h"]
[6.712067, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[14Cm\r\u001b[15C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[15C\u001b[?25h"]
[6.783718, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[15Co\r\u001b[16C\u001b[?25h"]
[6.7838, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[16C\u001b[?25h"]
[6.939724, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[16Cdifier \r\u001b[23C\u001b[?25h"]
[7.325224, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[23C-\r\u001b[24C\u001b[?25h"]
[7.325314, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[24C\u001b[?25h"]
[7.476947, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[24C-\r\u001b[25C\u001b[?25h"]
[7.477064, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[25C\u001b[?25h"]
[7.593983, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[25Cc\r\u001b[26C\u001b[?25h"]
[7.594077, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[26C\u001b[?25h"]
[7.70787, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[26Ch\r\u001b[27C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[27C\u001b[?25h"]
[7.891844, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[27Cdir\r\u001b[30C\u001b[?25h"]
[8.314837, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[23C\u001b[K\u001b[0;4m--chdir \r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7;34m--chdir\u001b[0;2;7m (Chdir())\u001b[0;m \u001b[0;34m--chdirf\u001b[0;2m (ChdirF())\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[8.624603, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[30C\u001b[K\u001b[0;4mf \r\n\r\n\u001b[0;m\u001b[K\u001b[0;34m--chdir\u001b[0;2m (Chdir())\u001b[0;m \u001b[0;7;34m--chdirf\u001b[0;2;7m (ChdirF())\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[8.831416, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[23C\u001b[K--chdirf \r\n\u001b[J\u001b[A\r\u001b[32C\u001b[?25h"]
[8.831533, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[32C\u001b[?25h"]
[9.31619, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[32C\u001b[0;4mDockerfile \r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7;38;2;255;184;108mDockerfile \u001b[0;m \u001b[0;38;2;255;184;108mcommand.go \u001b[0;m \u001b[0;38;2;189;147;249mdocs/ \u001b[0;m \u001b[0;38;2;255;184;108minvokedAction.go \r\nLICENSE.txt \u001b[0;m \u001b[0;38;2;255;184;108mcompat.go \u001b[0;m \u001b[0;38;2;189;147;249mexample-nonposix/ \u001b[0;m \u001b[0;38;2;255;184;108minvokedAction_test.go\r\nREADME.md \u001b[0;m \u001b[0;38;2;255;184;108mcompat_test.go \u001b[0;m \u001b[0;38;2;189;147;249mexample/ \u001b[0;m \u001b[0;38;2;255;184;108mlog.go \r\naction.go \u001b[0;m \u001b[0;38;2;255;184;108mcomplete.go \u001b[0;m \u001b[0;38;2;255;184;108mgo.mod \u001b[0;m \u001b[0;38;2;189;147;249mpkg/ \r\n\u001b[0;38;2;255;184;108maction_test.go \u001b[0;m \u001b[0;38;2;255;184;108mcontext.go \u001b[0;m \u001b[0;38;2;255;184;108mgo.sum \u001b[0;m \u001b[0;38;2;255;184;108mstorage.go \r\nbatch.go \u001b[0;m \u001b[0;38;2;255;184;108mcontext_test.go \u001b[0;m \u001b[0;38;2;255;184;108mgo.work \u001b[0;m \u001b[0;38;2;255;184;108mstorage_test.go \r\nbatch_test.go \u001b[0;m \u001b[0;38;2;255;184;108mdefaultActions.go \u001b[0;m \u001b[0;38;2;255;184;108mgo.work.sum \u001b[0;m \u001b[0;38;2;189;147;249mthird_party/ \r\n\u001b[0;38;2;255;184;108mcarapace.go \u001b[0;m \u001b[0;38;2;255;184;108mdefaultActions_test.go\u001b[0;m \u001b[0;38;2;189;147;249minternal/ \u001b[0;m \u001b[0;38;2;255;184;108mtraverse.go \r\ncarapace_test.go\u001b[0;m \u001b[0;38;2;255;184;108mdocker-compose.yml \u001b[0;m \u001b[0;38;2;255;184;108minternalActions.go\u001b[0;m\u001b[9A\r\u001b[22C\u001b[?25h"]
[12.282843, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[6C\u001b[K\r\n\u001b[J\u001b[A\r\u001b[6C\u001b[?25h"]
[12.283535, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[12.305827, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[12.305984, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[13.109807, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[0;31me\u001b[0;m\r\u001b[7C\u001b[?25h"]
[13.288469, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[7C\u001b[0;31mx\u001b[0;m\r\u001b[8C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[8C\u001b[?25h"]
[13.41831, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[8C\u001b[0;31mi\u001b[0;m\r\u001b[9C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[9C\u001b[?25h"]
[13.502972, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexit\u001b[0;m\r\u001b[10C\u001b[?25h"]
[13.594763, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\r\u001b[?25h\u001b[?7h\u001b[?2004l\r"]
12 changes: 12 additions & 0 deletions docs/src/carapace/action/chdirF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ChdirF

[`ChdirF`] is like [ChDir] but uses a function.

```go
carapace.ActionFiles().ChdirF(traverse.GitWorkTree)
```

![](./chdirF.cast)

[Chdir]:./chdir.md
[`ChdirF`]: https://pkg.go.dev/github.com/rsteube/carapace#Action.ChdirF
5 changes: 4 additions & 1 deletion example/cmd/modifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/rsteube/carapace"
"github.com/rsteube/carapace/pkg/cache"
"github.com/rsteube/carapace/pkg/style"
"github.com/rsteube/carapace/pkg/traverse"
"github.com/spf13/cobra"
)

Expand All @@ -25,6 +26,7 @@ func init() {
modifierCmd.Flags().String("cache", "", "Cache()")
modifierCmd.Flags().String("cache-key", "", "Cache()")
modifierCmd.Flags().String("chdir", "", "Chdir()")
modifierCmd.Flags().String("chdirf", "", "ChdirF()")
modifierCmd.Flags().String("filter", "", "Filter()")
modifierCmd.Flags().String("invoke", "", "Invoke()")
modifierCmd.Flags().String("list", "", "List()")
Expand Down Expand Up @@ -83,7 +85,8 @@ func init() {
return carapace.ActionValues()
}
}),
"chdir": carapace.ActionFiles().Chdir(os.TempDir()),
"chdir": carapace.ActionFiles().Chdir(os.TempDir()),
"chdirf": carapace.ActionFiles().ChdirF(traverse.GitWorkTree),
"filter": carapace.ActionValuesDescribed(
"1", "one",
"2", "two",
Expand Down
28 changes: 28 additions & 0 deletions pkg/traverse/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package traverse

import (
"path/filepath"
)

// GitDir is the location of the .git folder.
func GitDir(tc Context) (string, error) {
if dir, ok := tc.LookupEnv("GIT_DIR"); ok {
return filepath.ToSlash(dir), nil
}
return Parent(".git")(tc)
}

// GitWorkTree is the location of the root of the working directory for a non-bare repository.
func GitWorkTree(tc Context) (string, error) {
if dir, ok := tc.LookupEnv("GIT_WORK_TREE"); ok {
return filepath.ToSlash(dir), nil
}

if _, ok := tc.LookupEnv("GIT_DIR"); ok {
wd, _ := tc.Abs("") // TODO provide better access to Context.Dir
return wd, nil
}

gitdir, err := GitDir(tc)
return filepath.Dir(gitdir), err
}
23 changes: 23 additions & 0 deletions pkg/traverse/os.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package traverse

import "os"

// UserHomeDir returns the current user's home directory.
func UserHomeDir(tc Context) (string, error) {
return os.UserHomeDir()
}

// UserCacheDir returns the default root directory to use for user-specific cached data.
func UserCacheDir(tc Context) (string, error) {
return os.UserCacheDir()
}

// UserConfigDir returns the default root directory to use for user-specific configuration data.
func UserConfigDir(tc Context) (string, error) {
return os.UserConfigDir()
}

// TempDir returns the default directory to use for temporary files.
func TempDir(tc Context) (string, error) {
return os.TempDir(), nil
}
51 changes: 51 additions & 0 deletions pkg/traverse/traverse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package traverse

import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
)

type Context interface {
Abs(s string) (string, error)
Getenv(key string) string
LookupEnv(key string) (string, bool)
}

func Parent(names ...string) func(tc Context) (string, error) {
return func(tc Context) (string, error) {
wd, err := tc.Abs("")
if err != nil {
return "", err
}

for _, name := range names {
if dir, err := traverse(wd, name); err == nil {
return dir, nil
}
}
formattedNames := fmt.Sprintf("%#v", names)
formattedNames = strings.TrimPrefix(formattedNames, "[]string{")
formattedNames = strings.TrimSuffix(formattedNames, "}")
return "", errors.New("could not find parent directory containing any of: " + formattedNames)
}
}

// TODO also stop at `~`
func traverse(path string, name string) (target string, err error) {
var absPath string
if absPath, err = filepath.Abs(path); err == nil {
target = filepath.ToSlash(absPath + "/" + name)
if _, err = os.Stat(target); err != nil {
parent := filepath.Dir(absPath)
if parent != path {
return traverse(parent, name)
} else {
err = errors.New("could not find: " + name)
}
}
}
return
}
23 changes: 23 additions & 0 deletions pkg/traverse/xdg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package traverse

import (
"path/filepath"
)

// XdgCacheHome returns the cache directory (fallback to UserCacheDir).
func XdgCacheHome(tc Context) (dir string, err error) {
if dir = tc.Getenv("XDG_CACHE_HOME"); dir == "" {
dir, err = UserCacheDir(tc)
}
dir = filepath.ToSlash(dir)
return
}

// XdgConfigHome returns the home directory (fallback to UserConfigDir).
func XdgConfigHome(tc Context) (dir string, err error) {
if dir = tc.Getenv("XDG_CONFIG_HOME"); dir == "" {
dir, err = UserConfigDir(tc)
}
dir = filepath.ToSlash(dir)
return
}

0 comments on commit 8245a20

Please sign in to comment.