summaryrefslogtreecommitdiffstats
path: root/maintainers/scripts
diff options
context:
space:
mode:
authorsternenseemann <sternenseemann@systemli.org>2022-04-05 21:21:42 +0200
committersternenseemann <sternenseemann@systemli.org>2022-04-05 21:21:42 +0200
commitfb2fc3b4a4fc71d53e89c661428ca59abce1706c (patch)
tree847cb4ba60c7a1592458afa229a838595a3a1a20 /maintainers/scripts
parenta964dcad739fe70ed5e01646594aafdfb2be4560 (diff)
parentbef07673d323a9c489a664ba7dee3dd10468a293 (diff)
Merge remote-tracking branch 'origin/master' into haskell-updates
Diffstat (limited to 'maintainers/scripts')
-rwxr-xr-xmaintainers/scripts/dep-licenses.sh2
-rw-r--r--maintainers/scripts/pluginupdate.py187
2 files changed, 105 insertions, 84 deletions
diff --git a/maintainers/scripts/dep-licenses.sh b/maintainers/scripts/dep-licenses.sh
index 28ad22c334fc..816dcf6d7f76 100755
--- a/maintainers/scripts/dep-licenses.sh
+++ b/maintainers/scripts/dep-licenses.sh
@@ -9,7 +9,7 @@ tmp=$(mktemp --tmpdir -d nixpkgs-dep-license.XXXXXX)
exitHandler() {
exitCode=$?
rm -rf "$tmp"
- exit $exitCode
+ return $exitCode
}
trap "exitHandler" EXIT
diff --git a/maintainers/scripts/pluginupdate.py b/maintainers/scripts/pluginupdate.py
index 017e3ac758ac..3cfdb1387053 100644
--- a/maintainers/scripts/pluginupdate.py
+++ b/maintainers/scripts/pluginupdate.py
@@ -8,6 +8,7 @@
# $ nix run nixpkgs.python3Packages.flake8 -c flake8 --ignore E501,E265 update.py
import argparse
+import csv
import functools
import http
import json
@@ -28,7 +29,7 @@ from pathlib import Path
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
from urllib.parse import urljoin, urlparse
from tempfile import NamedTemporaryFile
-from dataclasses import dataclass
+from dataclasses import dataclass, asdict
import git
@@ -85,21 +86,30 @@ def make_request(url: str, token=None) -> urllib.request.Request:
headers["Authorization"] = f"token {token}"
return urllib.request.Request(url, headers=headers)
+
+Redirects = Dict['Repo', 'Repo']
+
class Repo:
def __init__(
- self, uri: str, branch: str, alias: Optional[str]
+ self, uri: str, branch: str
) -> None:
self.uri = uri
'''Url to the repo'''
- self.branch = branch
- self.alias = alias
- self.redirect: Dict[str, str] = {}
+ self._branch = branch
+ # {old_uri: new_uri}
+ self.redirect: Redirects = {}
self.token = "dummy_token"
@property
def name(self):
return self.uri.split('/')[-1]
+ @property
+ def branch(self):
+ return self._branch or "HEAD"
+
+ def __str__(self) -> str:
+ return f"{self.uri}"
def __repr__(self) -> str:
return f"Repo({self.name}, {self.uri})"
@@ -109,6 +119,7 @@ class Repo:
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
def latest_commit(self) -> Tuple[str, datetime]:
+ log.debug("Latest commit")
loaded = self._prefetch(None)
updated = datetime.strptime(loaded['date'], "%Y-%m-%dT%H:%M:%S%z")
@@ -124,6 +135,7 @@ class Repo:
return loaded
def prefetch(self, ref: Optional[str]) -> str:
+ print("Prefetching")
loaded = self._prefetch(ref)
return loaded["sha256"]
@@ -137,21 +149,22 @@ class Repo:
class RepoGitHub(Repo):
def __init__(
- self, owner: str, repo: str, branch: str, alias: Optional[str]
+ self, owner: str, repo: str, branch: str
) -> None:
self.owner = owner
self.repo = repo
self.token = None
'''Url to the repo'''
- super().__init__(self.url(""), branch, alias)
- log.debug("Instantiating github repo %s/%s", self.owner, self.repo)
+ super().__init__(self.url(""), branch)
+ log.debug("Instantiating github repo owner=%s and repo=%s", self.owner, self.repo)
@property
def name(self):
return self.repo
def url(self, path: str) -> str:
- return urljoin(f"https://github.com/{self.owner}/{self.name}/", path)
+ res = urljoin(f"https://github.com/{self.owner}/{self.repo}/", path)
+ return res
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
def has_submodules(self) -> bool:
@@ -168,6 +181,7 @@ class RepoGitHub(Repo):
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
def latest_commit(self) -> Tuple[str, datetime]:
commit_url = self.url(f"commits/{self.branch}.atom")
+ log.debug("Sending request to %s", commit_url)
commit_req = make_request(commit_url, self.token)
with urllib.request.urlopen(commit_req, timeout=10) as req:
self._check_for_redirect(commit_url, req)
@@ -191,12 +205,9 @@ class RepoGitHub(Repo):
new_owner, new_name = (
urllib.parse.urlsplit(response_url).path.strip("/").split("/")[:2]
)
- end_line = "\n" if self.alias is None else f" as {self.alias}\n"
- plugin_line = "{owner}/{name}" + end_line
- old_plugin = plugin_line.format(owner=self.owner, name=self.name)
- new_plugin = plugin_line.format(owner=new_owner, name=new_name)
- self.redirect[old_plugin] = new_plugin
+ new_repo = RepoGitHub(owner=new_owner, repo=new_name, branch=self.branch)
+ self.redirect[self] = new_repo
def prefetch(self, commit: str) -> str:
@@ -207,9 +218,9 @@ class RepoGitHub(Repo):
return sha256
def prefetch_github(self, ref: str) -> str:
- data = subprocess.check_output(
- ["nix-prefetch-url", "--unpack", self.url(f"archive/{ref}.tar.gz")]
- )
+ cmd = ["nix-prefetch-url", "--unpack", self.url(f"archive/{ref}.tar.gz")]
+ log.debug("Running %s", cmd)
+ data = subprocess.check_output(cmd)
return data.strip().decode("utf-8")
def as_nix(self, plugin: "Plugin") -> str:
@@ -239,21 +250,38 @@ class PluginDesc:
else:
return self.alias
+ def __lt__(self, other):
+ return self.repo.name < other.repo.name
+
+ @staticmethod
+ def load_from_csv(config: FetchConfig, row: Dict[str, str]) -> 'PluginDesc':
+ branch = row["branch"]
+ repo = make_repo(row['repo'], branch.strip())
+ repo.token = config.github_token
+ return PluginDesc(repo, branch.strip(), row["alias"])
+
+
+ @staticmethod
+ def load_from_string(config: FetchConfig, line: str) -> 'PluginDesc':
+ branch = "HEAD"
+ alias = None
+ uri = line
+ if " as " in uri:
+ uri, alias = uri.split(" as ")
+ alias = alias.strip()
+ if "@" in uri:
+ uri, branch = uri.split("@")
+ repo = make_repo(uri.strip(), branch.strip())
+ repo.token = config.github_token
+ return PluginDesc(repo, branch.strip(), alias)
+@dataclass
class Plugin:
- def __init__(
- self,
- name: str,
- commit: str,
- has_submodules: bool,
- sha256: str,
- date: Optional[datetime] = None,
- ) -> None:
- self.name = name
- self.commit = commit
- self.has_submodules = has_submodules
- self.sha256 = sha256
- self.date = date
+ name: str
+ commit: str
+ has_submodules: bool
+ sha256: str
+ date: Optional[datetime] = None
@property
def normalized_name(self) -> str:
@@ -270,6 +298,17 @@ class Plugin:
return copy
+def load_plugins_from_csv(config: FetchConfig, input_file: Path,) -> List[PluginDesc]:
+ log.debug("Load plugins from csv %s", input_file)
+ plugins = []
+ with open(input_file, newline='') as csvfile:
+ log.debug("Writing into %s", input_file)
+ reader = csv.DictReader(csvfile,)
+ for line in reader:
+ plugin = PluginDesc.load_from_csv(config, line)
+ plugins.append(plugin)
+
+ return plugins
class Editor:
"""The configuration of the update script."""
@@ -298,14 +337,8 @@ class Editor:
return get_current_plugins(self)
def load_plugin_spec(self, config: FetchConfig, plugin_file) -> List[PluginDesc]:
- plugins = []
- with open(plugin_file) as f:
- for line in f:
- if line.startswith("#"):
- continue
- plugin = parse_plugin_line(config, line)
- plugins.append(plugin)
- return plugins
+ '''CSV spec'''
+ return load_plugins_from_csv(config, plugin_file)
def generate_nix(self, plugins, outfile: str):
'''Returns nothing for now, writes directly to outfile'''
@@ -316,11 +349,11 @@ class Editor:
_prefetch = functools.partial(prefetch, cache=cache)
def update() -> dict:
- plugin_names = self.load_plugin_spec(config, input_file)
+ plugins = self.load_plugin_spec(config, input_file)
try:
pool = Pool(processes=config.proc)
- results = pool.map(_prefetch, plugin_names)
+ results = pool.map(_prefetch, plugins)
finally:
cache.store()
@@ -423,6 +456,7 @@ def get_current_plugins(editor: Editor) -> List[Plugin]:
data = json.loads(out)
plugins = []
for name, attr in data.items():
+ print("get_current_plugins: name %s" % name)
p = Plugin(name, attr["rev"], attr["submodules"], attr["sha256"])
plugins.append(p)
return plugins
@@ -431,7 +465,7 @@ def get_current_plugins(editor: Editor) -> List[Plugin]:
def prefetch_plugin(
p: PluginDesc,
cache: "Optional[Cache]" = None,
-) -> Tuple[Plugin, Dict[str, str]]:
+) -> Tuple[Plugin, Redirects]:
repo, branch, alias = p.repo, p.branch, p.alias
name = alias or p.repo.name
commit = None
@@ -454,11 +488,6 @@ def prefetch_plugin(
)
-def fetch_plugin_from_pluginline(config: FetchConfig, plugin_line: str) -> Plugin:
- plugin, _ = prefetch_plugin(parse_plugin_line(config, plugin_line))
- return plugin
-
-
def print_download_error(plugin: str, ex: Exception):
print(f"{plugin}: {ex}", file=sys.stderr)
ex_traceback = ex.__traceback__
@@ -468,14 +497,14 @@ def print_download_error(plugin: str, ex: Exception):
]
print("\n".join(tb_lines))
-
def check_results(
- results: List[Tuple[PluginDesc, Union[Exception, Plugin], Dict[str, str]]]
-) -> Tuple[List[Tuple[PluginDesc, Plugin]], Dict[str, str]]:
+ results: List[Tuple[PluginDesc, Union[Exception, Plugin], Redirects]]
+) -> Tuple[List[Tuple[PluginDesc, Plugin]], Redirects]:
''' '''
failures: List[Tuple[str, Exception]] = []
plugins = []
- redirects: Dict[str, str] = {}
+ # {old: new} plugindesc
+ redirects: Dict[Repo, Repo] = {}
for (pdesc, result, redirect) in results:
if isinstance(result, Exception):
failures.append((pdesc.name, result))
@@ -495,31 +524,17 @@ def check_results(
sys.exit(1)
-def make_repo(uri, branch, alias) -> Repo:
+def make_repo(uri: str, branch) -> Repo:
'''Instantiate a Repo with the correct specialization depending on server (gitub spec)'''
# dumb check to see if it's of the form owner/repo (=> github) or https://...
- res = uri.split('/')
- if len(res) <= 2:
- repo = RepoGitHub(res[0], res[1], branch, alias)
+ res = urlparse(uri)
+ if res.netloc in [ "github.com", ""]:
+ res = res.path.strip('/').split('/')
+ repo = RepoGitHub(res[0], res[1], branch)
else:
- repo = Repo(uri.strip(), branch, alias)
+ repo = Repo(uri.strip(), branch)
return repo
-def parse_plugin_line(config: FetchConfig, line: str) -> PluginDesc:
- branch = "HEAD"
- alias = None
- uri = line
- if " as " in uri:
- uri, alias = uri.split(" as ")
- alias = alias.strip()
- if "@" in uri:
- uri, branch = uri.split("@")
-
- repo = make_repo(uri.strip(), branch.strip(), alias)
- repo.token = config.github_token
-
- return PluginDesc(repo, branch.strip(), alias)
-
def get_cache_path(cache_file_name: str) -> Optional[Path]:
xdg_cache = os.environ.get("XDG_CACHE_HOME", None)
@@ -585,27 +600,27 @@ def prefetch(
return (pluginDesc, e, {})
+
def rewrite_input(
config: FetchConfig,
input_file: Path,
deprecated: Path,
- redirects: Dict[str, str] = None,
- append: Tuple = (),
+ # old pluginDesc and the new
+ redirects: Dict[PluginDesc, PluginDesc] = {},
+ append: List[PluginDesc] = [],
):
- with open(input_file, "r") as f:
- lines = f.readlines()
+ plugins = load_plugins_from_csv(config, input_file,)
- lines.extend(append)
+ plugins.extend(append)
if redirects:
- lines = [redirects.get(line, line) for line in lines]
cur_date_iso = datetime.now().strftime("%Y-%m-%d")
with open(deprecated, "r") as f:
deprecations = json.load(f)
for old, new in redirects.items():
- old_plugin = fetch_plugin_from_pluginline(config, old)
- new_plugin = fetch_plugin_from_pluginline(config, new)
+ old_plugin, _ = prefetch_plugin(old)
+ new_plugin, _ = prefetch_plugin(new)
if old_plugin.normalized_name != new_plugin.normalized_name:
deprecations[old_plugin.normalized_name] = {
"new": new_plugin.normalized_name,
@@ -615,10 +630,14 @@ def rewrite_input(
json.dump(deprecations, f, indent=4, sort_keys=True)
f.write("\n")
- lines = sorted(lines, key=str.casefold)
-
with open(input_file, "w") as f:
- f.writelines(lines)
+ log.debug("Writing into %s", input_file)
+ # fields = dataclasses.fields(PluginDesc)
+ fieldnames = ['repo', 'branch', 'alias']
+ writer = csv.DictWriter(f, fieldnames, dialect='unix', quoting=csv.QUOTE_NONE)
+ writer.writeheader()
+ for plugin in sorted(plugins):
+ writer.writerow(asdict(plugin))
def commit(repo: git.Repo, message: str, files: List[Path]) -> None:
@@ -660,9 +679,11 @@ def update_plugins(editor: Editor, args):
)
for plugin_line in args.add_plugins:
- editor.rewrite_input(fetch_config, args.input_file, editor.deprecated, append=(plugin_line + "\n",))
+ pdesc = PluginDesc.load_from_string(fetch_config, plugin_line)
+ append = [ pdesc ]
+ editor.rewrite_input(fetch_config, args.input_file, editor.deprecated, append=append)
update()
- plugin = fetch_plugin_from_pluginline(fetch_config, plugin_line)
+ plugin, _ = prefetch_plugin(pdesc, )
if autocommit:
commit(
nixpkgs_repo,