comparison env/lib/python3.9/site-packages/galaxy/tool_util/deps/mulled/mulled_build_files.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 """Build all composite mulled recipes discovered in TSV files.
2
3 Use mulled-build-channel to build images for single recipes for a whole conda
4 channel. This script instead builds images for combinations of recipes. This
5 script can be given a single TSV file or a directory of TSV files to process.
6
7 Examples:
8
9 Build all recipes discovered in tsv files in a single directory.
10
11 mulled-build-files build
12
13 """
14
15 import collections
16 import glob
17 import os
18 import sys
19
20 from ._cli import arg_parser
21 from .mulled_build import (
22 add_build_arguments,
23 args_to_mull_targets_kwds,
24 BuildExistsException,
25 mull_targets,
26 target_str_to_targets,
27 )
28 KNOWN_FIELDS = ["targets", "image_build", "name_override", "base_image"]
29 FALLBACK_LINE_TUPLE = collections.namedtuple("_Line", "targets image_build name_override base_image")
30
31
32 def main(argv=None):
33 """Main entry-point for the CLI tool."""
34 parser = arg_parser(argv, globals())
35 add_build_arguments(parser)
36 parser.add_argument('command', metavar='COMMAND', help='Command (build-and-test, build, all)')
37 parser.add_argument('files', metavar="FILES", default=".",
38 help="Path to directory (or single file) of TSV files describing composite recipes.")
39 args = parser.parse_args()
40 for target in generate_targets(args.files):
41 try:
42 ret = mull_targets(
43 target.targets,
44 image_build=target.image_build,
45 name_override=target.name_override,
46 base_image=target.base_image,
47 determine_base_image=False,
48 **args_to_mull_targets_kwds(args)
49 )
50 except BuildExistsException:
51 continue
52 if ret > 0:
53 sys.exit(ret)
54
55
56 def generate_targets(target_source):
57 """Generate all targets from TSV files in specified file or directory."""
58 target_source = os.path.abspath(target_source)
59 if os.path.isdir(target_source):
60 target_source_files = glob.glob(target_source + "/*.tsv")
61 else:
62 target_source_files = [target_source]
63
64 for target_source_file in target_source_files:
65 # If no headers are defined we use the 4 default fields in the order
66 # that has been used in galaxy-tool-util / galaxy-lib < 20.01
67 line_tuple = FALLBACK_LINE_TUPLE
68 with open(target_source_file) as f:
69 for line in f.readlines():
70 if line:
71 line = line.strip()
72 if line.startswith('#'):
73 # headers can define a different column order
74 line_tuple = tuple_from_header(line)
75 else:
76 yield line_to_targets(line, line_tuple)
77
78
79 def tuple_from_header(header):
80 fields = header[1:].split('\t')
81 for field in fields:
82 assert field in KNOWN_FIELDS, f"'{field}' is not one of {KNOWN_FIELDS}"
83 # Make sure tuple contains all fields
84 for field in KNOWN_FIELDS:
85 if field not in fields:
86 fields.append(field)
87 return collections.namedtuple("_Line", "%s" % " ".join(fields))
88
89
90 def line_to_targets(line_str, line_tuple):
91 """Parse a line so that some columns can remain unspecified."""
92 line_parts = line_str.split("\t")
93 n_fields = len(line_tuple._fields)
94 targets_column = line_tuple._fields.index('targets')
95 assert len(line_parts) <= n_fields, f"Too many fields in line [{line_str}], expect at most {n_fields} - targets, image build number, and name override."
96 line_parts += [None] * (n_fields - len(line_parts))
97 line_parts[targets_column] = target_str_to_targets(line_parts[targets_column])
98 return line_tuple(*line_parts)
99
100
101 __all__ = ("main", )
102
103
104 if __name__ == '__main__':
105 main()