summary refs log tree commit diff stats
path: root/tools/atlas
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2023-03-21 15:24:57 +0100
committerGitHub <noreply@github.com>2023-03-21 15:24:57 +0100
commitd84b02f0e08bad3ddfa288e080e5ee485b58479e (patch)
tree0e289884c356496e786ac84e335629d0e424eea8 /tools/atlas
parentc814c4d993675551ecf388b6a583c471a1b8bc5e (diff)
downloadNim-d84b02f0e08bad3ddfa288e080e5ee485b58479e.tar.gz
atlas tool: 'update' command (#21557)
Diffstat (limited to 'tools/atlas')
-rw-r--r--tools/atlas/atlas.md6
-rw-r--r--tools/atlas/atlas.nim33
2 files changed, 36 insertions, 3 deletions
diff --git a/tools/atlas/atlas.md b/tools/atlas/atlas.md
index ee770cd62..61ca28ff0 100644
--- a/tools/atlas/atlas.md
+++ b/tools/atlas/atlas.md
@@ -79,3 +79,9 @@ in its description (or name or list of tags).
 ### Install <proj.nimble>
 
 Use the .nimble file to setup the project's dependencies.
+
+### Update [filter]
+
+Update every package in the workspace that has a remote URL that
+matches `filter` if a filter is given. The package is only updated
+if there are no uncommitted changes.
diff --git a/tools/atlas/atlas.nim b/tools/atlas/atlas.nim
index 274e94517..dfa60856e 100644
--- a/tools/atlas/atlas.nim
+++ b/tools/atlas/atlas.nim
@@ -9,9 +9,11 @@
 ## Simple tool to automate frequent workflows: Can "clone"
 ## a Nimble dependency and its dependencies recursively.
 
-import std/[parseopt, strutils, os, osproc, unicode, tables, sets, json, jsonutils]
+import std/[parseopt, strutils, os, osproc, tables, sets, json, jsonutils]
 import parse_requires, osutils, packagesjson
 
+from unicode import nil
+
 const
   Version = "0.2"
   Usage = "atlas - Nim Package Cloner Version " & Version & """
@@ -25,6 +27,8 @@ Command:
   search keyw keywB...  search for package that contains the given keywords
   extract file.nimble   extract the requirements and custom commands from
                         the given Nimble file
+  update [filter]       update every package in the workspace that has a remote
+                        URL that matches `filter` if a filter is given
 
 Options:
   --keepCommits         do not perform any `git checkouts`
@@ -146,7 +150,7 @@ proc toDepRelation(s: string): DepRelation =
   of ">": strictlyGreater
   else: normal
 
-proc isCleanGit(c: var AtlasContext; dir: string): string =
+proc isCleanGit(c: var AtlasContext): string =
   result = ""
   let (outp, status) = exec(c, GitDiff, [])
   if outp.len != 0:
@@ -264,7 +268,7 @@ proc checkoutCommit(c: var AtlasContext; w: Dependency) =
     if w.commit.len == 0 or cmpIgnoreCase(w.commit, "head") == 0:
       gitPull(c, w.name)
     else:
-      let err = isCleanGit(c, dir)
+      let err = isCleanGit(c)
       if err != "":
         warn c, w.name, err
       else:
@@ -448,6 +452,27 @@ proc installDependencies(c: var AtlasContext; nimbleFile: string) =
   let paths = cloneLoop(c, work)
   patchNimCfg(c, paths, if c.cfgHere: getCurrentDir() else: findSrcDir(c))
 
+proc updateWorkspace(c: var AtlasContext; filter: string) =
+  for kind, file in walkDir(c.workspace):
+    if kind == pcDir and dirExists(file / ".git"):
+      c.withDir file:
+        let pkg = PackageName(file)
+        let (remote, _) = osproc.execCmdEx("git remote -v")
+        if filter.len == 0 or filter in remote:
+          let diff = isCleanGit(c)
+          if diff != "":
+            warn(c, pkg, "has uncommitted changes; skipped")
+          else:
+            let (branch, _) = osproc.execCmdEx("git rev-parse --abbrev-ref HEAD")
+            if branch.strip.len > 0:
+              let (output, exitCode) = osproc.execCmdEx("git pull origin " & branch.strip)
+              if exitCode != 0:
+                error c, pkg, output
+              else:
+                message(c, "[Hint] ", pkg, "successfully updated")
+            else:
+              error c, pkg, "could not fetch current branch name"
+
 proc main =
   var action = ""
   var args: seq[string] = @[]
@@ -525,6 +550,8 @@ proc main =
   of "search", "list":
     updatePackages(c)
     search getPackages(c.workspace), args
+  of "update":
+    updateWorkspace(c, if args.len == 0: "" else: args[0])
   of "extract":
     singleArg()
     if fileExists(args[0]):