amtoine / nu-git-manager Goto Github PK
View Code? Open in Web Editor NEWA collection of Nushell tools to manage Git repositories.
License: GNU General Public License v3.0
A collection of Nushell tools to manage Git repositories.
License: GNU General Public License v3.0
as per title
tk run --clean {
gm update-cache
gm clone --depth 1 https://github.com/amtoine/nu-git-manager
let repo = gm list --full-path | find nu-git-manager | get 0
cd $repo
gm remove --no-confirm nu-git-manager
}
will give
Error: × Cannot remove any parent directory
╭─[/home/amtoine/.local/share/nupm/modules/nu-git-manager/mod.nu:433:1]
433 │
434 │ rm --recursive --force --verbose $repo_to_remove
· ───────┬───────
· ╰── cannot remove any parent directory
435 │
╰────
i expected either the repo to be removed or at least a nice error
key | value |
---|---|
version | 0.89.0 |
branch | |
commit_hash | |
build_os | linux-x86_64 |
build_target | x86_64-unknown-linux-gnu |
rust_version | rustc 1.73.0 (cc66ad468 2023-10-03) |
rust_channel | stable-x86_64-unknown-linux-gnu |
cargo_version | cargo 1.73.0 (9c4383fb5 2023-08-26) |
build_time | 2024-01-11 18:20:14 +01:00 |
build_rust_channel | release |
allocator | mimalloc |
features | default, sqlite, trash, which, zip |
installed_plugins | clipboard copy, clipboard paste, gstat, nu_plugin_explore, query git |
No response
i've noticed a bunch of
str replace (get-repo-store-path) '' | str trim --left --char "/"
or similar in the source base 🤔
i think they should be refactored into something like path trim-root
.
in the nushell/nu_scripts
repo, we have the following files that could be interesting at some point
╭───┬───────────────────────────────────────────────────────────╮
│ 0 │ aliases/git/nu_alias_git.nu │
│ 1 │ custom-completions/auto-generate/completions/git-sizer.nu │
│ 2 │ custom-completions/auto-generate/completions/git.nu │
│ 3 │ custom-completions/auto-generate/completions/gitk.nu │
│ 4 │ modules/git/git.nu │
│ 5 │ modules/git/git_branch_cleanup.nu │
│ 6 │ modules/prompt/async_git_prompt/async-git-prompt.nu │
│ 7 │ modules/prompt/panache-git.nu │
│ 8 │ modules/prompt/powerline/power_git.nu │
│ 9 │ sourced/cool-oneliners/git_gone.nu │
╰───┴───────────────────────────────────────────────────────────╯
Note
generated withfd git | lines | find --invert themes before_v0.60 github gitlab custom-completions/git | find --invert --regex '/$'
there are also a bunch of things scattered around in my nu_scripts
👍
especially
use path join "foo" "bar"
instead of path join "foo/bar"
to abstract path joining.
the usage section of the README is already out of date...
i think it would be great and time to have some script to generate all the available modules and list the commands in them.
something in the CI would be great.
when using gm repo branches --clean
when checked out on a dangling branch, the command will halt because git branch -D
fails.
tk run --clean {
# setup the repo
let repo = $nu.temp-path | path join foo
if ($repo | path exists) {
rm -f -r $repo
}
git init $repo
cd $repo
git checkout --orphan main
git commit --allow-empty --no-gpg-sign --message "init"
# create two branches and checkout the first one
git branch bar
git branch foo
git checkout bar
print $"dangling branches: (gm repo branches | where ($it.remotes | is-empty) | get branch)"
gm repo branches --clean
}
Initialized empty Git repository in /tmp/foo/.git/
Switched to a new branch 'main'
[main (root-commit) e35547d] init
Switched to branch 'bar'
dangling branches: [bar, foo, main]
2023-12-06T16:33:36.290|INF|deleting branch `bar`
error: Cannot delete branch 'bar' checked out at '/tmp/foo'
i expected gm repo branches --clean
to skip branch bar
and remove foo
without an error.
key | value |
---|---|
version | 0.87.1 |
branch | |
commit_hash | |
build_os | linux-x86_64 |
build_target | x86_64-unknown-linux-gnu |
rust_version | rustc 1.73.0 (cc66ad468 2023-10-03) |
rust_channel | stable-x86_64-unknown-linux-gnu |
cargo_version | cargo 1.73.0 (9c4383fb5 2023-08-26) |
build_time | 2023-11-21 18:26:35 +01:00 |
build_rust_channel | release |
allocator | mimalloc |
features | default, sqlite, trash, which, zip |
installed_plugins | clipboard copy, clipboard paste, gstat, notify, nu_plugin_explore, query git |
No response
found the use of a deprecated command just after releasing 0.3.0
and trying out gm clean
😋
unfold
is going to be renamed generate
very soon 😏
tk run --clean { gm clone https://github.com/amtoine/nu-git-manager --depth 1 }
tk run { gm update-cache; gm clean }
Error: × Deprecated option
╭─[/home/amtoine/.local/share/nupm/modules/nu-git-manager/fs/dir.nu:6:1]
6 │ export def clean-empty-directories-rec []: list<path> -> list<path> {
7 │ let deleted = unfold $in {|directories|
· ───┬──
· ╰── `unfold` is deprecated and will be removed in 0.88.
8 │ let next = $directories | each {|it|
╰────
help: Please use `generate` instead.
no deprecation warning
key | value |
---|---|
version | 0.87.0 |
branch | |
commit_hash | |
build_os | linux-x86_64 |
build_target | x86_64-unknown-linux-gnu |
rust_version | rustc 1.73.0 (cc66ad468 2023-10-03) |
rust_channel | stable-x86_64-unknown-linux-gnu |
cargo_version | cargo 1.73.0 (9c4383fb5 2023-08-26) |
build_time | 2023-11-15 18:45:43 +01:00 |
build_rust_channel | release |
allocator | mimalloc |
features | default, sqlite, trash, which, zip |
installed_plugins | clipboard copy, clipboard paste, jwalk, nu_plugin_explore |
No response
nu-git-manager
is not able to clone Suckless software.
> gm clone git://git.suckless.org/st
Cloning into '/home/amtoine/documents/repos/git.suckless.org/st/st'...
fatal: repository 'https://git.suckless.org/st/st/' not found
i would like to be able to do something like
> gm clone git://git.suckless.org/st --fetch git --push git
to specify to use the GIT protocol to at least fetch, you probably won't push there.
right now, the error is not that great when running gh ...
being logged out 🤔
and it does not fail in the sense that the LAST_EXIT_CODE
is not set to 1
in that case 🤔
an idea that looks to be working: add gh auth status
at the start
remaining things: what happens when the user is
You are not logged into any GitHub hosts. Run gh auth login to authenticate.
--logged-out
option to query the API with http get
let's say i update repos of my store manually:
git init
a repo called manual/foo
git init
a repo called manual/bar
rm
a repo called auto/baz
when i run gm update-cache
to remove auto/baz
from it and add manual/foo
and manual/bar
to it, i think it would be cool to have an output like the following:
> gm update-cache
updating cache... done
#┬───name───┬status─
0│manual/foo│added
1│manual/bar│added
2│auto/baz │removed
─┴──────────┴───────
this implies that the signature of gm update-cache
would change a bit from
"gm update-cache" []: nothing -> nothing
to
"gm update-cache" []: nothing -> table<name: string, status: string>
i've been thinking a bit about the user experience of nu-git-manager
.
with #26, i feel the command API is quite good and simple (:crossed_fingers:)
however, here i would like to talk about the way the library definitions are imported 😋
cc/ @melMass
i think all the commands from nu-git-manager
should be subcommands of gm
, to have
git
or gh
which can break external completershere is what i propose, the implementation is really a detail in the scope of this issue 👌
use nu-git-manager main [gm, "gm list", "gm clone", ...]
use nu-git-manager main *
use nu-git-manager sugar git ["gm branch", "gm fetch", ...]
use nu-git-manager sugar git *
use nu-git-manager sugar gh ["gm pr checkout", ...]
use nu-git-manager sugar gh *
# would import all `gm branch`, `gm fetch`, `gm pr checkout`, ..., without `sugar` as prefix
use nu-git-manager sugar *
# would import all `gm clone`, `gm pr checkout`, ..., without `sugar` nor `main` as prefixes
use nu-git-manager *
related to
nu-git-manager
=> it has a usage and extra usagei expected to see the extra usage as well
key | value |
---|---|
version | 0.89.0 |
branch | |
commit_hash | |
build_os | linux-x86_64 |
build_target | x86_64-unknown-linux-gnu |
rust_version | rustc 1.73.0 (cc66ad468 2023-10-03) |
rust_channel | stable-x86_64-unknown-linux-gnu |
cargo_version | cargo 1.73.0 (9c4383fb5 2023-08-26) |
build_time | 2024-01-11 18:20:14 +01:00 |
build_rust_channel | release |
allocator | mimalloc |
features | default, sqlite, trash, which, zip |
installed_plugins | clipboard copy, clipboard paste, gstat, nu_plugin_explore |
No response
what do you think @melMass about adding some GitHub management scripts here? 😮
i have my gh
module and that little script i just wrote to help me review nushell
PRs 😋
def "nu-complete list-repos" [context: string] {
let user = ($context | str replace 'gh\s*pr\s*open\s*' "" | split row " " | get 0)
http get ({
scheme: https,
username: "",
host: api.github.com,
path: $"/orgs/($user)/repos",
params: {
sort: updated,
per_page: 100,
page: 1
}
} | url join)
| select name description
| rename value description
}
def "nu-complete gh-status" [] {[
[value description];
[failure "The CI does not pass."]
[pending "The CI is currently running."]
[success "All the CI jobs have passed."]
]}
def "nu-complete gh-review" [] {[
[value description];
[none "No review at all."]
[changes-requested "There are changes to be applied."]
[approved "The PR has been approved."]
]}
export def "gh pr open" [
owner: string
repo: string@"nu-complete list-repos"
--draft: bool
--ready: bool # has precedence over `--draft`
--status: string@"nu-complete gh-status"
--review: string@"nu-complete gh-review"
] {
let draft = (if $draft or $ready {
$draft and (not $ready)
})
let query = [
[is pr]
[is open]
[draft $draft]
[status $status]
[review $review]
]
let url = ({
scheme: https,
host: github.com,
path: $"/($owner)/($repo)/pulls",
params: {
q: (
$query
| where {|it| $it.1 != null}
| each { str join "%3A" }
| str join "+"
)
}
} | url join)
xdg-open $url
}
Note
- added context-aware completion for
repo
- added
--draft
option- do not add
draft
to the query if neither--draft
nor--ready
are raised
i also have a GitHub gist management script here.
Originally posted by amtoine April 23, 2023
for now i see four main ideas we have
x-motemen/ghq
itselfgit-grab.nu
@melMass
def clone [
owner: string
repo: string
--host: string = "github.com"
--protocol: string = "https"
] {(
git clone
({
scheme: $protocol,
host: $host,
path: $"/($owner)/($repo)",
} | url join)
($env.GIT_REPOS_HOME | path join $host $owner $repo)
)}
repo.nu
when using gm remove
empty parent directories are left there untouched.
this could break manual scripts that try to list stuff in the store...
tk run --clean {
gm update-cache
gm clone https://github.com/amtoine/nu-git-manager --depth 1
gm remove --no-confirm nu-git-manager
print ($env.GIT_REPOS_HOME | path join "github.com/amtoine" | path exists)
print ($env.GIT_REPOS_HOME | path join "github.com/amtoine" | ls $in | is-empty)
}
will print
true
true
i expected gm remove
to clean the empty mess and thus the repro snippet above to print false
twice.
key | value |
---|---|
version | 0.86.1 |
branch | main |
commit_hash | 0ca8fcf58c02bef31f1eb65e001d71f5648b3b35 |
build_os | linux-x86_64 |
build_target | x86_64-unknown-linux-gnu |
rust_version | rustc 1.71.1 (eb26296b5 2023-08-03) |
rust_channel | 1.71.1-x86_64-unknown-linux-gnu |
cargo_version | cargo 1.71.1 (7f1d04c00 2023-07-29) |
build_time | 2023-11-02 17:56:54 +01:00 |
build_rust_channel | release |
allocator | mimalloc |
features | default, sqlite, trash, which, zip |
installed_plugins | jwalk, nu_plugin_explore |
No response
as per title
git checkout ea557bb8ebaed2bb40951ea434ab89712a718de5
diff --git a/src/nu-git-manager/mod.nu b/src/nu-git-manager/mod.nu
index 488854b..c3b82be 100644
--- a/src/nu-git-manager/mod.nu
+++ b/src/nu-git-manager/mod.nu
@@ -324,5 +324,7 @@ export def "gm remove" [
check-cache-file $cache_file
remove-from-cache $cache_file ($root | path join $repo_to_remove)
+ "foo" | path sanitize
+
null
}
use toolkit.nu; toolkit test
=> it runs just fineuse ./src/nu-git-manager/ *
and see the following errorError: nu::parser::extra_positional
× Extra positional argument.
╭─[/home/amtoine/documents/repos/github.com/amtoine/nu-git-manager/src/nu-git-manager/mod.nu:326:1]
326 │
327 │ "foo" | path sanitize
· ────┬───
· ╰── extra positional argument
328 │
╰────
help: Usage: path
i expected the tests to fail
key | value |
---|---|
version | 0.86.1 |
branch | |
commit_hash | c1738620e33105a2622588561c8f3d1d69735678 |
build_os | linux-x86_64 |
build_target | x86_64-unknown-linux-gnu |
rust_version | rustc 1.71.1 (eb26296b5 2023-08-03) |
rust_channel | 1.71.1-x86_64-unknown-linux-gnu |
cargo_version | cargo 1.71.1 (7f1d04c00 2023-07-29) |
build_time | 2023-11-08 22:48:06 +01:00 |
build_rust_channel | release |
allocator | mimalloc |
features | default, sqlite, trash, which, zip |
installed_plugins | jwalk, nu_plugin_explore |
No response
i would like to split the tests
tests internals
from the current tests
tests gm
from #48
tests gm clone
for all the clone testslet's say i have already the nushell/nushell
repo cloned.
when i gm clone https://github.com/amtoine/nushell
, i.e. my fork of the Nushell repo, a new amtoine/nushell
repo gets created in the store of nu-git-manager
.
i would like gm
to merge the two local copies, e.g. put everything in nushell/nushell
and create two remotes
nushell
which points to nushell/nushell
amtoine
which points to amtoine/nushell
for my future self: a command to get the list of all the forks with their paths and root commit 👌
def get-forks []: nothing -> table<root: string, paths: list<string>> {
gm list --full-path
| each {{
repo: $in,
root: (^git -C $in rev-list HEAD | lines | last)
}}
| group-by root
| transpose k v
| where ($it.v | length) > 1
| select k v.repo
| rename --column { k: "root", v_repo: "paths" }
}
def is-grafted [repo?: path] {
let repo = if $repo == null {
pwd
} else {
if not ($repo | path exists) {
error make {
msg: $"(ansi red_bold)directory_not_found(ansi reset)"
label: {
text: "no such directory"
start: (metadata $repo).span.start
end: (metadata $repo).span.end
}
}
}
$repo
}
let root_commit = ^git -C $repo rev-list HEAD | lines | last
^git -C $repo log --oneline --decorate $root_commit
| parse --regex '[0-9a-f]+ \(grafted.*'
| is-empty
| not $in
}
in the long run, i think we need unit and integration tests, as much as possible 👍
really just a question 😌
This is what initially happens when you bring nu-git-manager out of the box...
In other words the first time installing it...
I started off by running
gm clone https://github.com/amtoine/nu-git-manager
And then got the message that "cache not found"
So I went ahead and ran the command
gm update-cache
And this is what happend --- nushell crashed and paniced with this error message
updating cache... Error: × Deprecated option
╭─[/Users/ma/j/tmp17/nu-git-manager/nu-git-manager/fs/store.nu:38:1]
38 │ cd (get-repo-store-path)
39 │ let heads: list<string> = glob "**/HEAD" --not [
· ──┬─
· ╰── `glob --not {list<string>}` is deprecated and will be removed in 0.88.
40 │ **/.git/**/refs/remotes/**/HEAD,
╰────
help: Please use `glob --exclude {list<string>}` instead.
thread 'main' panicked at 'attempt to add with overflow', crates/nu-command/src/filters/range.rs:108:58
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
This happens on both the main branch and the release of nushell 0.86
Both error out in the exact same spot...
https://github.com/nushell/nushell/blob/main/crates/nu-command/src/filters/range.rs#L108
as per title
first run
tk run --clean {
gm update-cache
# clone two forks
gm clone https://github.com/amtoine/nushell
gm clone https://github.com/nushell/nushell
# setup `nushell` as a remote of `amtoine`
^git -C ($env.GIT_REPOS_HOME | path join "github.com/amtoine/nushell") remote add nushell https://github.com/nushell/nushell
# try to squash into `amtoine`
gm squash-forks --non-interactive-preselect {
8f3b273337b53bd86d5594d5edc9d4ad7242bd4c: "github.com/amtoine/nushell"
}
}
deleted /tmp/nu-git-manager/repos
deleted /tmp/nu-git-manager/repos.cache
updating cache... done
Cloning into '/tmp/nu-git-manager/repos/github.com/amtoine/nushell'...
remote: Enumerating objects: 102625, done.
remote: Counting objects: 100% (102625/102625), done.
remote: Compressing objects: 100% (27930/27930), done.
remote: Total 102625 (delta 73950), reused 101765 (delta 73656), pack-reused 0
Receiving objects: 100% (102625/102625), 38.30 MiB | 21.49 MiB/s, done.
Resolving deltas: 100% (73950/73950), done.
updating cache... done
Cloning into '/tmp/nu-git-manager/repos/github.com/nushell/nushell'...
remote: Enumerating objects: 102194, done.
remote: Counting objects: 100% (102194/102194), done.
remote: Compressing objects: 100% (27838/27838), done.
remote: Total 102194 (delta 73627), reused 101309 (delta 73323), pack-reused 0
Receiving objects: 100% (102194/102194), 38.24 MiB | 12.13 MiB/s, done.
Resolving deltas: 100% (73627/73627), done.
Warning: ⚠ cloning_fork
| this repo is a fork of 1 other repo because they share the same root commit: 8f3b273337b53bd86d5594d5edc9d4ad7242bd4c
| - github.com/amtoine/nushell
updating cache... done
error: remote nushell already exists.
Note
see the error at the bottom
now, if we list the repos, we still see nushell
...
tk run { gm list }
─┬──────────────────────────
0│github.com/amtoine/nushell
1│github.com/nushell/nushell
─┴──────────────────────────
i expected tk run { gm list }
to only return the amtoine
fork.
key | value |
---|---|
version | 0.87.0 |
branch | |
commit_hash | |
build_os | linux-x86_64 |
build_target | x86_64-unknown-linux-gnu |
rust_version | rustc 1.73.0 (cc66ad468 2023-10-03) |
rust_channel | stable-x86_64-unknown-linux-gnu |
cargo_version | cargo 1.73.0 (9c4383fb5 2023-08-26) |
build_time | 2023-11-15 18:45:43 +01:00 |
build_rust_channel | release |
allocator | mimalloc |
features | default, sqlite, trash, which, zip |
installed_plugins | clipboard copy, clipboard paste, jwalk, nu_plugin_explore |
No response
i stumbled upon the following interesting structure
module foo {
export def main [] { help foo }
export def bar [] { "foo bar" }
}
where foo
would do nothing but give the help
of the module 😏
> use foo
> foo bar
foo bar
> foo
Usage:
> foo
Subcommands:
foo bar -
Flags:
-h, --help - Display the help message for this command
as per title, i would like to refactor the base directories of all the tests to be the same, to avoid messing around too much with the filesystem.
when Git has a version prior to 2.43.0, --bare
and --origin
are incompatible options of ^git clone
, thus gm clone --bare
will fail with
fatal: --bare and --origin foo options are incompatible.
tk run {
gm clone https://github.com/raphamorim/rio --bare
}
will fail on Ubuntu for instance.
either
> git --version
git version 2.34.1
See commit 3b910d6 (22 Sep 2022) by Jeff King (peff).
(Merged by Junio C Hamano (gitster) in commit 7aeb0d4, 10 Oct 2022)
related to
i would like to
gm version
command when it gets possiblepackage.nuon
in the long run, i'd like to have more external and custom completions inside both gm
and sugar
👍
gm
sugar
gh
CLI command of GitHub in sugar completions gh
: based on gh version 2.28.0 (2023-04-25)
?git
command
core
, cherry
, remote
, worktree
, ..., to allow importing only usefull commands more easilysugar git
sugar gist
(removed)sugar gh
sugar dotfiles
(removed)A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.