Skip to content

Instantly share code, notes, and snippets.

@tsibley
Created February 3, 2025 19:27
Show Gist options
  • Save tsibley/90a17aff04cca11f811c1a12c789e422 to your computer and use it in GitHub Desktop.
Save tsibley/90a17aff04cca11f811c1a12c789e422 to your computer and use it in GitHub Desktop.
def pathogen_version_for_setup(name_version_url: str) -> "PathogenVersion":
# XXX FIXME docstring
"""
TKTK
"""
name, version, url = spec = PathogenSpec.parse(name_version_url)
if not name:
raise UserError(f"""
No name specified in {name_version_url!r}.
All pathogen setups must be given a name, e.g. as in <name>[@<version>[=<url>]].
""")
if disallowed := set([os.path.sep, os.path.altsep]) & set(name):
raise UserError(f"""
Disallowed character(s) {"".join(disallowed)!r} in name {name!r}.
""")
if url and not version:
raise UserError(f"""
URL specified without version in {name_version_url!r}.
A version must be specified when a setup URL is specified,
e.g. as in <name>@<version>=<url>.
""")
# Valid forms:
# <name>
# <name>@<version>
# <name>@<version>=<url>
assert (name and not version and not url) \
or (name and version and not url) \
or (name and version and url)
if not version:
version = github_repo_latest_ref(f"nextstrain/{name}")
if not version:
raise UserError(f"""
No version specified in {name_version_url!r}.
There's no default version intuitable, so a version must be
specified, e.g. as in {name}@<version>.
""")
if not url:
url = github_repo_ref_zipball_url(f"nextstrain/{name}", version)
if not url:
raise UserError(f"""
No setup URL specified in {name_version_url!r}.
A default URL can not be determined, so a setup URL must be
specified explicitly, e.g. as in {name}@{version}=<url>.
""")
if url.scheme != "https":
raise UserError(f"""
URL scheme is {url.scheme!r}, not {"https"!r}.
Pathogen setup URLs must be https://.
""")
assert name
assert version
assert url
return PathogenVersion(name, version, url)
def pathogen_version(name_version: str) -> "PathogenVersion":
# XXX FIXME docstring
"""
TKTK
"""
name, version, url = spec = PathogenSpec.parse(name_version)
if not name:
raise UserError(f"""
No pathogen name specified in {name_version!r}.
""")
if disallowed := set([os.path.sep, os.path.altsep]) & set(name):
raise UserError(f"""
Disallowed character(s) {"".join(disallowed)!r} in name {name!r}.
""")
if url:
raise UserError(f"""
URL specified in {name_version!r}.
Pathogen setup URLs may only be specified for `nextstrain setup`.
""")
# Valid forms:
# <name>
# <name>@<version>
assert (name and not version and not url) \
or (name and version and not url)
if not version:
# XXX FIXME: function name
version = pathogen_default_version(name, implicit = True)
if not version:
if versions := pathogen_versions(name):
raise UserError(f"""
No version specified in {name_version!r}.
There's no default version set (or intuitable), so a version
must be specified, e.g. as in {name}@<version>.
Existing versions of {name!r} you have set up are:
{{versions}}
Hint: You can set a default version for {name!r} by running:
nextstrain setup --set-default {shquote(f"{name}@<version>")}
if you don't want to specify an explicit version every time.
""", versions = indent("\n".join(f"{name}@{v}" for v in versions), " "))
else:
raise UserError(f"""
No pathogen setup exists for {name_version!r}.
Did you set it up yet?
Hint: to set it up, run `nextstrain setup {shquote(name_version)}`.
""")
assert name
assert version
pathogen = PathogenVersion(name, version)
if not pathogen.path.is_dir():
if versions := pathogen_versions(name):
raise UserError(f"""
No pathogen setup exists for {name_version!r}{f" in {str(pathogen.path)!r}" if DEBUGGING else ""}.
Existing versions of {name!r} you have set up are:
{{versions}}
Did you mean one of those?
""", versions = indent("\n".join(f"{name}@{v}" for v in versions), " "))
else:
raise UserError(f"""
No pathogen setup exists for {name_version!r}{f" in {str(pathogen.path)!r}" if DEBUGGING else ""}.
Did you set it up yet?
Hint: to set it up, run `nextstrain setup {shquote(name_version)}`.
""")
return pathogen
class PathogenVersion:
# XXX FIXME docstring
"""
TKTK
"""
name: str
version: str
_url: Optional[URL]
_setup_receipt: Optional[dict]
def __init__(self, name: str, version: str, url: URL = None):
assert name
assert not set([os.path.sep, os.path.altsep]) & set(name)
assert version
assert isinstance(url, (URL, type(None))
self.name = name
self.version = version
self._url = url
@property
def url(self) -> Optional[URL]:
if self._url is None and self.setup_receipt:
if url := self.setup_receipt.get("url"):
self._url = URL(url)
return self._url
@property
def setup_receipt(self) -> Optional[dict]
if self._setup_receipt is None and self.setup_receipt_path.exists():
with self.setup_receipt_path.open(encoding = "utf-8") as f:
self._setup_receipt = json.load(f)
assert isinstance(self._setup_receipt, dict)
return self._setup_receipt
@property
def setup_receipt_path(self) -> Path:
return self.path.with_suffix(self.path.suffix + ".json")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment