def adjust_download_specs(self, specs: List[str]) -> List[str]: # For downloads, wildcards not permitted. for spec in specs: validate_spec(spec) if spec == "*" or spec == "latest": raise error.UsageError("invalid wild SPEC: {}".format(spec)) return dist.require_specs(specs)
def main() -> None: parser = make_parser() args = parser.parse_args() common.set_max_verbosity(common.VERBOSITY_INFO + args.verbose - args.quiet) try: cmd = args.subparser_name if args.readme: readme() elif cmd is None: raise error.UsageError("missing OPERATION (try --help)") elif cmd == "crate": romt.crate.Main(args).run() elif cmd == "rustup": romt.rustup.Main(args).run() elif cmd == "toolchain": romt.toolchain.Main(args).run() elif cmd == "serve": romt.serve.Main(args).run() except error.Error as e: common.eprint(e) sys.exit(1) except KeyboardInterrupt: common.eprint("Keyboard interrupt")
def adjust_download_specs(self, specs: List[str]) -> List[str]: # For downloads, require explicit date and channel. for spec in specs: date, channel = parse_spec(spec) if "*" in (date, channel) or date == "latest": raise error.UsageError("invalid wild SPEC: {}".format(spec)) return dist.require_specs(specs)
def get_origin_bundle_path(self) -> Path: """Path for repo's remote "origin" URL""" url = get_origin_url(self.get_repo()) parsed = urllib.parse.urlparse(url) if parsed.scheme or parsed.netloc: raise error.UsageError( "INDEX remote ``origin`` must have ``url`` as a local file") else: path = Path(url) if self.args.bundle_path and (path.resolve() != Path( self.args.bundle_path).resolve()): raise error.UsageError( "BUNDLE_PATH must match ``url`` for INDEX's ``origin`` remote") return path
def expand_wild_spec(self, spec: str) -> List[str]: specs = [] # type: List[str] date, channel = parse_spec(spec) if "*" in (date, channel) or date == "latest": if channel == "*": channel_patterns = set("nightly beta stable".split()) else: channel_patterns = set([channel]) if date in ("*", "latest"): dates = common.reversed_date_dir_names(self.dest_path) else: dates = [date] for d in dates: channels = channel_patterns.intersection( self.channels_in_dest_date(d)) specs.extend("{}-{}".format(channel, d) for channel in channels) if date == "latest" and specs: break else: specs.append(spec) if not specs: raise error.UsageError("no matches for wild SPEC {}".format( repr(spec))) return specs
def _get_start(self) -> str: start = self.args.start if start is None: raise error.UsageError("missing START") elif start == "0": start = "" return start
def _init_common(index_path: Path, origin_location: str, crates_root_path: Path) -> git.Repo: if index_path.is_dir(): raise error.UsageError("index directory {} already exists".format( repr(str(index_path)))) common.iprint("create index repository at {}:".format(repr( str(index_path)))) index_path.mkdir(parents=True) repo = git.Repo.init(str(index_path)) common.iprint(" remote add origin {}".format(origin_location)) repo.create_remote("origin", origin_location) # Setup "HEAD" to new "working" branch. working = git.Reference(repo, "refs/heads/working") repo.head.set_reference(working) # Setup default remote and merge branch for "working". with repo.config_writer() as writer: writer.set_value('branch "working"', "remote", "origin") writer.set_value('branch "working"', "merge", "refs/heads/master") if not crates_root_path.is_dir(): common.iprint("create crates directory at {}:".format( repr(str(crates_root_path)))) crates_root_path.mkdir(parents=True) return repo
def cmd_fixup(self) -> None: for spec in self.adjust_wild_specs(self.specs): common.iprint("Fixup: {}".format(spec)) version = self.version_from_spec(spec, download=False) version_path = self.artifact_version_path(version) # Artifacts are arranged as: <version_path>/<target>/<artifact> # If no artifacts exist for any targets, claim the version # is not present. artifacts = list(version_path.glob("*/*")) if not artifacts: raise error.UsageError( "version {} not present".format(version)) self._fixup_version(version) # Copy rustup/archive/<stable_version>/ to rustup/dist/. stable_version = self.get_release_stable_version(download=False) archive_version_path = self.dest_path_from_rel_path( "archive/{}".format(stable_version)) if not archive_version_path.is_dir(): raise error.MissingDirectoryError(str(archive_version_path)) dist_path = self.dest_path_from_rel_path("dist") if dist_path.is_dir(): shutil.rmtree(str(dist_path)) common.iprint("[copytree] {} -> {}".format(archive_version_path, dist_path)) shutil.copytree(str(archive_version_path), str(dist_path))
def get_origin_url(repo: git.Repo) -> str: origin = git.remote.Remote(repo, "origin") urls = list(origin.urls) if len(urls) == 1: return urls[0] else: raise error.UsageError( "INDEX remote ``origin`` must have exactly one ``URL``")
def require_targets( targets: List[str], *, default: Optional[str] = None ) -> List[str]: if not targets: if default is None: raise error.UsageError("missing required TARGET; try --target") targets = [default] return targets
def get_bundle_path(self) -> Path: if self.args.bundle_path: path = Path(self.args.bundle_path) elif self.args.index: path = get_index_path(self.args.index) / INDEX_BUNDLE_NAME else: raise error.UsageError("missing BUNDLE_PATH") # Use .absolute() because git operations change the working directory. return path.absolute()
def parse_spec(spec: str) -> Tuple[str, str]: """parse spec into (date, channel). Forms with channel: <channel> <channel>-YYYY-MM-DD <channel>-latest <channel>-* *-YYYY-MM-DD *-latest *-* Forms with only date: YYYY-MM-DD latest * Where: - <channel> is one of: nightly, beta, stable, X.Y.Z - Single ``*`` represents date, not channel; equivalent to ``*-*``. """ # Single "*" is treated as wildcard for date, not channel. if spec == "*": return "*", "*" channel_rex = r""" (?P<channel> nightly | beta | stable | \* | (?: \d+\.\d+\.\d+ ) ) """ date_rex = r""" (?P<date> \d\d\d\d-\d\d-\d\d | latest | \* ) """ m = re.match(r"{} (?: - {})? $".format(channel_rex, date_rex), spec, re.VERBOSE) if m: channel = m.group("channel") date = m.group("date") or "" return date, channel m = re.match(r"{} $".format(date_rex), spec, re.VERBOSE) if m: date = m.group("date") return date, "*" raise error.UsageError("invalid SPEC {}".format(repr(spec)))
def adjust_targets(self, manifest: Manifest, base_targets: List[str]) -> List[str]: possible_targets = set(p.target for p in manifest.gen_packages()) targets = set() for target in base_targets: if target == "all": targets.update(possible_targets) elif target == "*": targets.update(self.downloaded_targets(manifest)) elif target not in possible_targets: raise error.UsageError( "target {} not found in manifest".format(repr(target))) else: targets.add(target) return sorted(targets)
def expand_wild_spec(self, spec: str) -> List[str]: specs = [] # type: List[str] validate_spec(spec) if spec == "*": specs.extend(self.downloaded_versions()) elif spec == "latest": found_versions = self.downloaded_versions() if found_versions: specs.append(found_versions[0]) else: specs.append(spec) if not specs: raise error.UsageError("no matches for wild SPEC {}".format( repr(spec))) return specs
def validate_spec(spec: str) -> str: """parse spec into (date, channel). SPEC is one of: <version> stable latest * Where: - <version> is: X.Y.Z - Multiple SPEC options may be given. - Each SPEC option will be split at commas and whitespace. """ if spec in ("*", "latest", "stable") or common.is_version(spec): return spec raise error.UsageError("invalid SPEC {}".format(repr(spec)))
def get_start_branch_name(self) -> str: start = self._get_start() if start == "": raise error.UsageError("START may not be 0 or empty") return start
def get_crates_root_path(crates_root: str) -> Path: path = Path(crates_root) if not path.is_dir(): raise error.UsageError( "{} is not a valid crates directory".format(path)) return path
def get_archive_path(self) -> Path: if not self.args.archive: raise error.UsageError("missing archive name") return Path(self.args.archive)
def verify_commands(commands: List[str], valid_commands: List[str]) -> None: for command in commands: if command not in valid_commands: raise error.UsageError("invalid COMMAND {}".format(repr(command)))
def require_specs(specs: List[str]) -> List[str]: if not specs: raise error.UsageError("missing required SPEC; try --select") return specs
def get_index_path(index: str) -> Path: path = Path(index) if not path.is_dir(): raise error.UsageError( "{} is not a valid index directory".format(path)) return path