|
6 | 6 | """
|
7 | 7 |
|
8 | 8 | import collections
|
9 |
| -import glob |
10 |
| -import itertools as it |
11 | 9 | import logging
|
12 | 10 | import os
|
13 | 11 | import re
|
14 |
| -import warnings |
15 |
| - |
16 |
| -import yaml |
17 | 12 |
|
18 | 13 | from codebasin import CompileCommand, util
|
19 | 14 |
|
@@ -75,109 +70,6 @@ def extract_include_files(argv):
|
75 | 70 | return includes
|
76 | 71 |
|
77 | 72 |
|
78 |
| -def expand_path(pattern): |
79 |
| - """ |
80 |
| - Return all valid and existing paths matching a specified pattern. |
81 |
| - """ |
82 |
| - paths = glob.glob(pattern, recursive=True) |
83 |
| - if paths == []: |
84 |
| - log.warning( |
85 |
| - "Couldn't find files matching '%s' -- ignoring it.", |
86 |
| - pattern, |
87 |
| - ) |
88 |
| - return [os.path.realpath(path) for path in filter(util.valid_path, paths)] |
89 |
| - |
90 |
| - |
91 |
| -def flatten(nested_list): |
92 |
| - """ |
93 |
| - Flatten an arbitrarily nested list. |
94 |
| - Nesting may occur when anchors are used inside a YAML list. |
95 |
| - """ |
96 |
| - flattened = [] |
97 |
| - for item in nested_list: |
98 |
| - if isinstance(item, list): |
99 |
| - flattened.extend(flatten(item)) |
100 |
| - else: |
101 |
| - flattened.append(item) |
102 |
| - return flattened |
103 |
| - |
104 |
| - |
105 |
| -def load_codebase(config, rootdir, *, exclude_patterns=None): |
106 |
| - """ |
107 |
| - Load the code base definition into a Python object. |
108 |
| - Return a dict of files and platform names. |
109 |
| - """ |
110 |
| - # Ensure expected values are present, or provide defaults |
111 |
| - cfg_codebase = config["codebase"] |
112 |
| - if not cfg_codebase: |
113 |
| - raise RuntimeError("Empty 'codebase' section found in config file!") |
114 |
| - if "files" not in cfg_codebase: |
115 |
| - raise RuntimeError("No 'files' section found in codebase definition!") |
116 |
| - if "platforms" not in cfg_codebase or cfg_codebase["platforms"] == []: |
117 |
| - raise RuntimeError( |
118 |
| - "Empty 'platforms' section found in codebase definition!", |
119 |
| - ) |
120 |
| - |
121 |
| - codebase = {} |
122 |
| - |
123 |
| - codebase["platforms"] = cfg_codebase["platforms"] |
124 |
| - |
125 |
| - if "exclude_files" in cfg_codebase: |
126 |
| - codebase["exclude_files"] = frozenset( |
127 |
| - it.chain( |
128 |
| - *( |
129 |
| - expand_path(os.path.join(rootdir, f)) |
130 |
| - for f in cfg_codebase["exclude_files"] |
131 |
| - ), |
132 |
| - ), |
133 |
| - ) |
134 |
| - warnings.warn( |
135 |
| - "'exclude_files' is deprecated. Use 'exclude_pattern' instead.", |
136 |
| - ) |
137 |
| - else: |
138 |
| - codebase["exclude_files"] = frozenset([]) |
139 |
| - |
140 |
| - if "exclude_patterns" in cfg_codebase: |
141 |
| - codebase["exclude_patterns"] = cfg_codebase["exclude_patterns"] |
142 |
| - else: |
143 |
| - codebase["exclude_patterns"] = [] |
144 |
| - |
145 |
| - if exclude_patterns: |
146 |
| - codebase["exclude_patterns"] += exclude_patterns |
147 |
| - |
148 |
| - if cfg_codebase["files"]: |
149 |
| - codebase["files"] = list( |
150 |
| - it.chain( |
151 |
| - *( |
152 |
| - expand_path(os.path.join(rootdir, f)) |
153 |
| - for f in cfg_codebase["files"] |
154 |
| - ), |
155 |
| - ), |
156 |
| - ) |
157 |
| - if not codebase["files"]: |
158 |
| - raise RuntimeError( |
159 |
| - "Codebase configuration contains no valid files. " |
160 |
| - + "Check regular expressions and working directory.", |
161 |
| - ) |
162 |
| - |
163 |
| - codebase["files"] = list( |
164 |
| - set(codebase["files"]).difference(codebase["exclude_files"]), |
165 |
| - ) |
166 |
| - if not codebase["files"]: |
167 |
| - raise RuntimeError( |
168 |
| - "Codebase configuration contains no valid files " |
169 |
| - + "after processing 'exclude_files'.", |
170 |
| - ) |
171 |
| - else: |
172 |
| - codebase["files"] = list([]) |
173 |
| - log.warning( |
174 |
| - "No files specified in codebase configuration. " |
175 |
| - + "Determining files automatically from platform configurations.", |
176 |
| - ) |
177 |
| - |
178 |
| - return codebase |
179 |
| - |
180 |
| - |
181 | 73 | _importcfg = None
|
182 | 74 |
|
183 | 75 |
|
@@ -500,146 +392,3 @@ def load_database(dbpath, rootdir):
|
500 | 392 | )
|
501 | 393 |
|
502 | 394 | return configuration
|
503 |
| - |
504 |
| - |
505 |
| -def load_platform(config, rootdir, platform_name): |
506 |
| - """ |
507 |
| - Load the platform specified by platform_name into a Python object. |
508 |
| - Return a list of compilation commands, where each command is |
509 |
| - represented as a compilation database entry. |
510 |
| - """ |
511 |
| - # Ensure expected values are present, or provide defaults |
512 |
| - cfg_platform = config[platform_name] |
513 |
| - if not cfg_platform: |
514 |
| - raise RuntimeError( |
515 |
| - "Could not find definition for platform " |
516 |
| - + f"'{platform_name}' in config file!", |
517 |
| - ) |
518 |
| - if "files" not in cfg_platform and "commands" not in cfg_platform: |
519 |
| - raise RuntimeError( |
520 |
| - "Need 'files' or 'commands' section in " |
521 |
| - + f"definition of platform {platform_name}!", |
522 |
| - ) |
523 |
| - if "files" not in cfg_platform: |
524 |
| - if "defines" in cfg_platform or "include_paths" in cfg_platform: |
525 |
| - log.warning( |
526 |
| - "Extra 'defines' or 'include_paths' in definition " |
527 |
| - + f"of platform {platform_name}.", |
528 |
| - ) |
529 |
| - else: |
530 |
| - if "defines" not in cfg_platform: |
531 |
| - cfg_platform["defines"] = [] |
532 |
| - if "include_paths" not in cfg_platform: |
533 |
| - cfg_platform["include_paths"] = [] |
534 |
| - |
535 |
| - # Combine manually specified files, defines and includes |
536 |
| - # into configuration entries |
537 |
| - configuration = [] |
538 |
| - if "files" in cfg_platform: |
539 |
| - include_paths = [ |
540 |
| - os.path.realpath(os.path.join(rootdir, f)) |
541 |
| - for f in flatten(cfg_platform["include_paths"]) |
542 |
| - ] |
543 |
| - |
544 |
| - # Strip optional -D prefix from defines |
545 |
| - defines = [ |
546 |
| - d[2:] if d.startswith("-D") else d |
547 |
| - for d in flatten(cfg_platform["defines"]) |
548 |
| - ] |
549 |
| - |
550 |
| - for f in flatten(cfg_platform["files"]): |
551 |
| - for path in expand_path(os.path.join(rootdir, f)): |
552 |
| - configuration += [ |
553 |
| - { |
554 |
| - "file": path, |
555 |
| - "defines": defines, |
556 |
| - "include_paths": include_paths, |
557 |
| - "include_files": [], |
558 |
| - }, |
559 |
| - ] |
560 |
| - |
561 |
| - # Add configuration entries from a compilation database |
562 |
| - if "commands" in cfg_platform: |
563 |
| - dbpath = os.path.realpath( |
564 |
| - os.path.join(rootdir, cfg_platform["commands"]), |
565 |
| - ) |
566 |
| - configuration += load_database(dbpath, rootdir) |
567 |
| - |
568 |
| - # Ensure that the platform actually specifies valid files |
569 |
| - if not configuration: |
570 |
| - raise RuntimeError( |
571 |
| - f"Platform '{platform_name!s}' contains no valid files -- " |
572 |
| - + "regular expressions and/or working directory may be incorrect.", |
573 |
| - ) |
574 |
| - |
575 |
| - return configuration |
576 |
| - |
577 |
| - |
578 |
| -def load( |
579 |
| - config_file, |
580 |
| - rootdir, |
581 |
| - *, |
582 |
| - exclude_patterns=None, |
583 |
| - filtered_platforms=None, |
584 |
| -): |
585 |
| - """ |
586 |
| - Load the configuration file into Python objects. |
587 |
| - Return a (codebase, platform configuration) tuple of dicts. |
588 |
| - """ |
589 |
| - if os.path.isfile(config_file): |
590 |
| - with util.safe_open_read_nofollow(config_file, "r") as f: |
591 |
| - config = yaml.safe_load(f) |
592 |
| - else: |
593 |
| - raise RuntimeError(f"Could not open {config_file!s}.") |
594 |
| - |
595 |
| - # Validate config against a schema |
596 |
| - util._validate_yaml(config, schema_name="config") |
597 |
| - |
598 |
| - # Read codebase definition |
599 |
| - if "codebase" in config: |
600 |
| - codebase = load_codebase( |
601 |
| - config, |
602 |
| - rootdir, |
603 |
| - exclude_patterns=exclude_patterns, |
604 |
| - ) |
605 |
| - else: |
606 |
| - raise RuntimeError("Missing 'codebase' section in config file!") |
607 |
| - |
608 |
| - log.info("Platforms: %s", ", ".join(codebase["platforms"])) |
609 |
| - |
610 |
| - # Limit the set of platforms in the codebase if requested. |
611 |
| - if filtered_platforms: |
612 |
| - for p in filtered_platforms: |
613 |
| - if p not in codebase["platforms"]: |
614 |
| - raise RuntimeError( |
615 |
| - f"Platform {p} requested on the command line " |
616 |
| - + "does not exist in the configuration file.", |
617 |
| - ) |
618 |
| - codebase["platforms"] = filtered_platforms |
619 |
| - |
620 |
| - # Read each platform definition and populate platform configuration |
621 |
| - # If files was empty, populate it with the files we find here |
622 |
| - populate_files = not codebase["files"] |
623 |
| - found_files = set(codebase["files"]) |
624 |
| - configuration = collections.defaultdict(list) |
625 |
| - for platform_name in codebase["platforms"]: |
626 |
| - plat = load_platform(config, rootdir, platform_name) |
627 |
| - if populate_files: |
628 |
| - files = frozenset([p["file"] for p in plat]) |
629 |
| - found_files.update(files) |
630 |
| - configuration[platform_name] = plat |
631 |
| - |
632 |
| - if len(found_files) == 0: |
633 |
| - raise RuntimeError( |
634 |
| - "No files found. Check regular expressions and working directory.", |
635 |
| - ) |
636 |
| - |
637 |
| - codebase["files"] = list(found_files.difference(codebase["exclude_files"])) |
638 |
| - if not codebase["files"]: |
639 |
| - raise RuntimeError("No files remain after processing 'exclude_files'.") |
640 |
| - |
641 |
| - # Store the rootdir in the codebase for use later in exclude() |
642 |
| - if "rootdir" not in codebase: |
643 |
| - codebase["rootdir"] = os.path.realpath(rootdir) |
644 |
| - |
645 |
| - return codebase, configuration |
0 commit comments