From 63fd9d1660f8fde0047997fd674f3d2f6c5226cc Mon Sep 17 00:00:00 2001 From: despiegk Date: Tue, 22 Jul 2025 09:20:10 +0200 Subject: [PATCH] ... --- lib/develop/gittools/README.md | 80 ++++++++++++++++++++- lib/develop/gittools/play.v | 126 +++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 lib/develop/gittools/play.v diff --git a/lib/develop/gittools/README.md b/lib/develop/gittools/README.md index 090ccde3..d2807609 100644 --- a/lib/develop/gittools/README.md +++ b/lib/develop/gittools/README.md @@ -1,6 +1,84 @@ # Git Tools Module -### Get a specific path starting from url +## GitTools HeroScript + +### `!!git.define` + +Configure or retrieve a `GitStructure`, if not set will use the default + +```heroscript +!!git.define + coderoot:'/tmp/code' //when we overrule the location, the default is ~/code + light:true //depth of git clone is 1 + log:true + debug:false //give more error reporting + offline:false //makes sure will not try to get to internet, but do all locally + ssh_key_path:'' //if a specific ssh key is needed + reload:false //if set then will remove cache and load full status, this is slow ! +``` + +### `!!git.clone` + +Clones a Git repository from a specified URL into the configured coderoot. + +```heroscript +!!git.clone + url: 'https://github.com/freeflowuniverse/test_repo.git' + pull: true // Optional: if true, pulls latest changes after cloning + reset: false // Optional: if true, resets the repository before cloning/pulling + light: true // Optional: if true, clones only the last history (default: is from git structure as defined above) + recursive: false // Optional: if true, also clones submodules (default: false) +``` + +### `!!git.repo_action` + +Performs various Git operations on an existing repository, the filter matches more than 1 repo, gives error if none found + +```heroscript +!!git.repo_action + filter: 'freeflowuniverse/test_repo' + action: 'pull' // pull, commit, push, reset, branch_create, branch_switch, tag_create, tag_switch, delete + message: 'feat: Added new feature' // Optional: for 'commit' action + branchname: 'feature-branch' // Optional: for 'branch_create' or 'branch_switch' actions + tagname: 'v1.0.0' // Optional: for 'tag_create' or 'tag_switch' actions + submodules: true // Optional: for 'pull' action, if true, also updates submodules + error_ignore: false // Optional: if true, ignores errors during the action and continue for the next repo +``` + +**Parameters:** + +- `filter` (string, **required**): A substring to filter repositories by name or relative path. This can match multiple repositories. +- `action` (string, **required**): The Git operation to perform. Valid values: + - `pull`: Pulls latest changes from the remote. + - `commit`: Commits staged changes. Requires `message`. + - `push`: Pushes local commits to the remote. + - `reset`: Resets all local changes (hard reset). + - `branch_create`: Creates a new branch. Requires `branchname`. + - `branch_switch`: Switches to an existing branch. Requires `branchname`. + - `tag_create`: Creates a new tag. Requires `tagname`. + - `tag_switch`: Switches to an existing tag. Requires `tagname`. + - `delete`: Deletes the local repository. + +### `!!git.list` + +Lists known Git repositories managed by the `gittools` module. + +```heroscript +!!git.list + filter: 'my_project' // Optional: filter by repository name or path + reload: true //if true then will check the status of those repo's against the remote's +``` + +### `!!git.reload` + +Forces a reload of all Git repositories in the cache, re-scanning the `coderoot` and updating their statuses. + +```heroscript +!!git.reload + filter: 'my_project' // Optional: filter by repository name or path +``` + +## Get a specific path starting from url below is powerful command, will get the repo, put on right location, you can force a pull or even reset everything diff --git a/lib/develop/gittools/play.v b/lib/develop/gittools/play.v new file mode 100644 index 00000000..f4623aa8 --- /dev/null +++ b/lib/develop/gittools/play.v @@ -0,0 +1,126 @@ +module gittools + +import freeflowuniverse.herolib.core.playbook { PlayBook } +import freeflowuniverse.herolib.ui.console +import freeflowuniverse.herolib.develop.gittools + +@[params] +pub struct PlayArgs { +pub mut: + heroscript string + heroscript_path string + plbook ?PlayBook + reset bool +} + +pub fn play(args_ PlayArgs) ! { + mut args := args_ + mut plbook := args.plbook or { + playbook.new(text: args.heroscript, path: args.heroscript_path)! + } + + // Initialize GitStructure + mut gs := gittools.new()! + + // Handle !!git.clone action + clone_actions := plbook.find(filter: 'git.clone')! + for action in clone_actions { + mut p := action.params + url := p.get('url')! + coderoot := p.get_default('coderoot', '')! + sshkey := p.get_default('sshkey', '')! + light := p.get_default_true('light') + recursive := p.get_default_false('recursive') + + mut clone_args := gittools.GitCloneArgs{ + url: url + sshkey: sshkey + recursive: recursive + } + if coderoot.len > 0 { + gs = gittools.new(coderoot: coderoot, light: light)! + } else { + gs.config_!.light = light // Update light setting on existing gs + } + gs.clone(clone_args)! + } + + // Handle !!git.repo_action + repo_actions := plbook.find(filter: 'git.repo_action')! + for action in repo_actions { + mut p := action.params + name := p.get('name')! + account := p.get('account')! + provider := p.get('provider')! + action_type := p.get('action')! + message := p.get_default('message', '')! + branchname := p.get_default('branchname', '')! + tagname := p.get_default('tagname', '')! + submodules := p.get_default_false('submodules') + + mut repo := gs.get_repo(name: name, account: account, provider: provider)! + + match action_type { + 'pull' { + repo.pull(submodules: submodules)! + } + 'commit' { + repo.commit(message)! + } + 'push' { + repo.push()! + } + 'reset' { + repo.reset()! + } + 'branch_create' { + repo.branch_create(branchname)! + } + 'branch_switch' { + repo.branch_switch(branchname)! + } + 'tag_create' { + repo.tag_create(tagname)! + } + 'tag_switch' { + repo.tag_switch(tagname)! + } + 'delete' { + repo.delete()! + } + else { + return error('Unknown git.repo_action: ${action_type}') + } + } + } + + // Handle !!git.list + list_actions := plbook.find(filter: 'git.list')! + for action in list_actions { + mut p := action.params + filter_str := p.get_default('filter', '')! + name := p.get_default('name', '')! + account := p.get_default('account', '')! + provider := p.get_default('provider', '')! + status_update := p.get_default_false('status_update') + + gs.repos_print( + filter: filter_str + name: name + account: account + provider: provider + status_update: status_update + )! + } + + // Handle !!git.reload_cache + reload_cache_actions := plbook.find(filter: 'git.reload_cache')! + for action in reload_cache_actions { + mut p := action.params + coderoot := p.get_default('coderoot', '')! + if coderoot.len > 0 { + gs = gittools.new(coderoot: coderoot)! + } + gs.load(true)! // Force reload + } +} \ No newline at end of file