55# You should still set up your module_base before doing this (as we need
66# to write module files.
77
8+ # This script also requires pipelib
9+ # pip install pipelib
10+
811# **ALWAYS** dry run first!
912# python biocontainer-match.py --dry-run
1013# At the root of your depot do:
2225import re
2326import sys
2427
28+ import pipelib .pipeline as pipeline
29+ import pipelib .pipelines as pipelines
30+ import pipelib .steps as step
31+
2532from shpc .logger import logger
2633from shpc .main import get_client
2734from shpc .main .container import ContainerConfig
2835
36+ # A pipeline to process docker tags
37+ steps = (
38+ # Filter out those that look like commits
39+ pipelines .git .RemoveCommits ,
40+ # Scrub commits from version string
41+ step .filters .CleanCommit (),
42+ # Parse versions, return sorted ascending, and taking version major.minor.patch into account
43+ step .container .ContainerTagSort (),
44+ )
45+
46+ p = pipeline .Pipeline (steps )
47+
2948
3049def get_parser ():
3150 parser = argparse .ArgumentParser (
@@ -51,7 +70,6 @@ def get_parser():
5170
5271
5372def main ():
54-
5573 parser = get_parser ()
5674
5775 # If an error occurs while parsing the arguments, the interpreter will exit with value 2
@@ -65,22 +83,34 @@ def main():
6583 depot = os .path .abspath (args .containers )
6684 cli = get_client ()
6785
68- # Keep a record of repos we've seen and don't repeat
69- seen = set ()
70-
7186 # Ensure we start with the populated modules
7287 cli .registry .iter_modules ()
7388
89+ # Organize paths based on container uri
90+ paths = {}
91+
7492 # Find all paths that match the pattern of a name:tag
93+ # Organize by tag so we can later find the newest
7594 for path in os .listdir (depot ):
7695 if not re .search ("^(.*):(.*)$" , path ) or os .path .isdir (path ):
7796 continue
7897 repo , tag = path .split (":" , 1 )
98+ if repo not in paths :
99+ paths [repo ] = set ()
100+ paths [repo ].add (tag )
79101
80- # Don't need to parse twice
81- if repo in seen :
102+ # Find all paths that match the pattern of a name:tag
103+ for repo , tags in paths .items ():
104+ # The updated and transformed items
105+ sorted_tags = p .run (tags , unwrap = False )
106+ if not sorted_tags :
82107 continue
83108
109+ latest = sorted_tags [0 ]
110+ tag = latest ._original
111+ path = f"{ repo } :{ tag } "
112+ print (f"⭐️ Found { len (tags )} for { repo } , latest is { tag } " )
113+
84114 container = f"{ args .namespace } /{ repo } "
85115 tagged = f"{ container } :{ tag } "
86116
@@ -96,7 +126,6 @@ def main():
96126
97127 if args .dry_run :
98128 print (f"Would be installing { path } to { tagged } " )
99- seen .add (repo )
100129 continue
101130
102131 # Note we need to install the correct version but using aliases
@@ -121,7 +150,6 @@ def main():
121150 container_image = path ,
122151 keep_path = True ,
123152 )
124- seen .add (repo )
125153
126154
127155if __name__ == "__main__" :
0 commit comments