mirror of
https://github.com/Mic92/nix-update.git
synced 2024-11-03 21:04:49 +03:00
Merge branch 'master' into unstable
This commit is contained in:
commit
f0490e7196
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@ -6,8 +6,8 @@ jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: cachix/install-nix-action@v16
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cachix/install-nix-action@v18
|
||||
- name: build
|
||||
run: NIX_PATH=nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixpkgs-unstable.tar.gz nix-build
|
||||
- name: Run tests
|
||||
|
13
README.md
13
README.md
@ -6,12 +6,14 @@ designed to work with nixpkgs but also other package sets.
|
||||
## Features
|
||||
|
||||
- automatically figure out the latest version of packages from:
|
||||
- crates.io
|
||||
- github.com
|
||||
- gitlab.com or other instances that uses fetchFromGitLab
|
||||
- pypi
|
||||
- rubygems.org
|
||||
- update buildRustPackage's cargoSha256
|
||||
- update buildGoModule's vendorSha256/modSha256
|
||||
- update buildRustPackage's cargoHash/cargoSha256 and cargoSetupHook's cargoDeps
|
||||
- update buildGoModule's vendorHash/vendorSha256
|
||||
- update buildNpmPackage's npmDepsHash and npmConfigHook's npmDeps
|
||||
- build and run the resulting package (see `--build`,
|
||||
`--run` or `--shell`
|
||||
- commit updated files (see `--commit` flag)
|
||||
@ -91,6 +93,13 @@ a regex can be used
|
||||
$ nix-update jq --version-regex 'jq-(.*)'
|
||||
```
|
||||
|
||||
By default `nix-update` will locate the file that needs to be patched using the `src` attribute of a derivation.
|
||||
In some cases this heurestic is wrong. One can override the behavior like that:
|
||||
|
||||
``` console
|
||||
$ nix-update hello --override-filename pkgs/applications/misc/hello/default.nix
|
||||
```
|
||||
|
||||
With the `--shell`, `--build`, `--test` and `--run` flags the update can be
|
||||
tested. Additionally, the `--review` flag can be used to
|
||||
initiate a run of [nixpkgs-review](https://github.com/Mic92/nixpkgs-review), which will ensure all
|
||||
|
@ -1,10 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
|
||||
import sys
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
|
||||
)
|
||||
|
||||
from nix_update import main # NOQA
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
11
default.nix
11
default.nix
@ -12,22 +12,25 @@ python3.pkgs.buildPythonApplication rec {
|
||||
python3.pkgs.pytest
|
||||
python3.pkgs.black
|
||||
python3.pkgs.flake8
|
||||
python3.pkgs.isort
|
||||
glibcLocales
|
||||
mypy
|
||||
# technically not a test input, but we need it for development in PATH
|
||||
nixUnstable
|
||||
nix-prefetch
|
||||
pkgs.nixVersions.stable or nix_2_4
|
||||
];
|
||||
checkPhase = ''
|
||||
echo -e "\x1b[32m## run black\x1b[0m"
|
||||
LC_ALL=en_US.utf-8 black --check .
|
||||
LC_ALL=en_US.utf-8 black --check . bin/nix-update
|
||||
echo -e "\x1b[32m## run flake8\x1b[0m"
|
||||
flake8 nix_update
|
||||
echo -e "\x1b[32m## run mypy\x1b[0m"
|
||||
mypy --no-warn-unused-ignores --strict nix_update tests
|
||||
|
||||
echo -e "\x1b[32m## run isort\x1b[0m"
|
||||
isort . --check-only
|
||||
'';
|
||||
makeWrapperArgs = [
|
||||
"--prefix PATH" ":" (lib.makeBinPath [ nixUnstable nix-prefetch nixpkgs-fmt nixpkgs-review ])
|
||||
"--prefix PATH" ":" (lib.makeBinPath [ pkgs.nixVersions.stable or nix_2_4 nixpkgs-fmt nixpkgs-review ])
|
||||
];
|
||||
shellHook = ''
|
||||
# workaround because `python setup.py develop` breaks for me
|
||||
|
12
flake.lock
12
flake.lock
@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1614513358,
|
||||
"narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=",
|
||||
"lastModified": 1652776076,
|
||||
"narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "5466c5bbece17adaab2d82fae80b46e807611bf3",
|
||||
"rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -17,11 +17,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1617519343,
|
||||
"narHash": "sha256-WBLhtXFEyPXMEMg0c8NUf7p7JmEGlJ6i+x/LWvaoHx4=",
|
||||
"lastModified": 1652946078,
|
||||
"narHash": "sha256-Bgrzfc+RepxbRjQP1xR8Kluz8CMiyAykouFdzkoptns=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "db23e436b273855043fbad6097d6c45dbb37d035",
|
||||
"rev": "7af10ab660287104c6a3b679914a6a5e9e9587e8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -4,11 +4,11 @@ import sys
|
||||
import tempfile
|
||||
from typing import NoReturn, Optional
|
||||
|
||||
from .version.version import VersionPreference
|
||||
from .eval import Package
|
||||
from .eval import Package, eval_attr
|
||||
from .options import Options
|
||||
from .update import update
|
||||
from .utils import run
|
||||
from .version.version import VersionPreference
|
||||
|
||||
|
||||
def die(msg: str) -> NoReturn:
|
||||
@ -16,7 +16,7 @@ def die(msg: str) -> NoReturn:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def parse_args() -> Options:
|
||||
def parse_args(args: list[str]) -> Options:
|
||||
parser = argparse.ArgumentParser()
|
||||
help = "File to import rather than default.nix. Examples, ./release.nix"
|
||||
parser.add_argument("-f", "--file", default="./.", help=help)
|
||||
@ -53,22 +53,29 @@ def parse_args() -> Options:
|
||||
parser.add_argument(
|
||||
"--version", nargs="?", help="Version to update to", default="stable"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--override-filename",
|
||||
nargs="?",
|
||||
help="Set filename where nix-update will update version/hash",
|
||||
default=None,
|
||||
)
|
||||
parser.add_argument("attribute", help="Attribute name within the file evaluated")
|
||||
args = parser.parse_args()
|
||||
a = parser.parse_args(args)
|
||||
return Options(
|
||||
import_path=args.file,
|
||||
build=args.build,
|
||||
commit=args.commit,
|
||||
write_commit_message=args.write_commit_message,
|
||||
run=args.run,
|
||||
shell=args.shell,
|
||||
version=args.version,
|
||||
version_preference=VersionPreference.from_str(args.version),
|
||||
attribute=args.attribute,
|
||||
test=args.test,
|
||||
version_regex=args.version_regex,
|
||||
review=args.review,
|
||||
format=args.format,
|
||||
import_path=a.file,
|
||||
build=a.build,
|
||||
commit=a.commit,
|
||||
write_commit_message=a.write_commit_message,
|
||||
run=a.run,
|
||||
shell=a.shell,
|
||||
version=a.version,
|
||||
version_preference=VersionPreference.from_str(a.version),
|
||||
attribute=a.attribute,
|
||||
test=a.test,
|
||||
version_regex=a.version_regex,
|
||||
review=a.review,
|
||||
format=a.format,
|
||||
override_filename=a.override_filename,
|
||||
)
|
||||
|
||||
|
||||
@ -83,8 +90,7 @@ def nix_shell(options: Options) -> None:
|
||||
|
||||
|
||||
def git_has_diff(git_dir: str, package: Package) -> bool:
|
||||
run(["git", "-C", git_dir, "add", package.filename], stdout=None)
|
||||
diff = run(["git", "-C", git_dir, "diff", "--staged"])
|
||||
diff = run(["git", "-C", git_dir, "diff", "--", package.filename])
|
||||
return len(diff.stdout) > 0
|
||||
|
||||
|
||||
@ -96,12 +102,16 @@ def format_commit_message(package: Package) -> str:
|
||||
and new_version.startswith("v")
|
||||
):
|
||||
new_version = new_version[1:]
|
||||
return f"{package.attribute}: {package.old_version} -> {new_version}"
|
||||
msg = f"{package.attribute}: {package.old_version} -> {new_version}"
|
||||
if package.changelog:
|
||||
msg += f"\n\nChangelog: {package.changelog}"
|
||||
return msg
|
||||
|
||||
|
||||
def git_commit(git_dir: str, package: Package) -> None:
|
||||
msg = format_commit_message(package)
|
||||
new_version = package.new_version
|
||||
run(["git", "-C", git_dir, "add", package.filename], stdout=None)
|
||||
if new_version and package.old_version != new_version.number:
|
||||
run(
|
||||
["git", "-C", git_dir, "commit", "--verbose", "--message", msg], stdout=None
|
||||
@ -139,7 +149,7 @@ def validate_git_dir(import_path: str) -> str:
|
||||
if os.path.isdir(import_path):
|
||||
git_dir = find_git_root(import_path)
|
||||
else:
|
||||
git_dir = find_git_root(os.path.basename(import_path))
|
||||
git_dir = find_git_root(os.path.dirname(import_path))
|
||||
|
||||
if git_dir is None:
|
||||
die(f"Could not find a git repository relative to {import_path}")
|
||||
@ -153,7 +163,7 @@ def validate_git_dir(import_path: str) -> str:
|
||||
|
||||
|
||||
def nix_run(options: Options) -> None:
|
||||
cmd = ["nix", "shell", "--experimental-features", "nix-command"]
|
||||
cmd = ["nix", "shell", "--extra-experimental-features", "nix-command"]
|
||||
run(
|
||||
cmd + ["-f", options.import_path, options.attribute],
|
||||
stdout=None,
|
||||
@ -165,17 +175,13 @@ def nix_build(options: Options) -> None:
|
||||
cmd = [
|
||||
"nix",
|
||||
"build",
|
||||
"--experimental-features",
|
||||
"--extra-experimental-features",
|
||||
"nix-command",
|
||||
"-f",
|
||||
options.import_path,
|
||||
options.attribute,
|
||||
]
|
||||
run(
|
||||
cmd,
|
||||
stdout=None,
|
||||
check=True,
|
||||
)
|
||||
run(cmd, stdout=None)
|
||||
|
||||
|
||||
def nix_test(package: Package) -> None:
|
||||
@ -187,7 +193,7 @@ def nix_test(package: Package) -> None:
|
||||
tests.append("-A")
|
||||
tests.append(f"{package.attribute}.tests.{t}")
|
||||
cmd = ["nix-build"] + tests
|
||||
run(cmd, check=True)
|
||||
run(cmd, stdout=None)
|
||||
|
||||
|
||||
def nixpkgs_review() -> None:
|
||||
@ -195,20 +201,20 @@ def nixpkgs_review() -> None:
|
||||
"nixpkgs-review",
|
||||
"wip",
|
||||
]
|
||||
run(cmd, check=True)
|
||||
run(cmd, stdout=None)
|
||||
|
||||
|
||||
def nixpkgs_fmt(package: Package, git_dir: Optional[str]) -> None:
|
||||
cmd = ["nixpkgs-fmt", package.filename]
|
||||
run(cmd, check=True)
|
||||
run(cmd, stdout=None)
|
||||
if git_dir is not None:
|
||||
run(["git", "-C", git_dir, "add", package.filename], stdout=None)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
options = parse_args()
|
||||
def main(args: list[str] = sys.argv[1:]) -> None:
|
||||
options = parse_args(args)
|
||||
if not os.path.exists(options.import_path):
|
||||
die(f"path {options.import_path} does not exists")
|
||||
die(f"path {options.import_path} does not exist")
|
||||
|
||||
git_dir = None
|
||||
if options.commit or options.review:
|
||||
@ -245,6 +251,9 @@ def main() -> None:
|
||||
|
||||
if options.commit:
|
||||
assert git_dir is not None
|
||||
if package.changelog:
|
||||
# If we have a changelog we will re-eval the package in case it has changed
|
||||
package.changelog = eval_attr(options).changelog
|
||||
git_commit(git_dir, package)
|
||||
|
||||
if options.write_commit_message is not None:
|
||||
|
@ -1,11 +1,11 @@
|
||||
import json
|
||||
from dataclasses import dataclass, InitVar, field
|
||||
from typing import List, Optional, Dict, Any
|
||||
from dataclasses import InitVar, dataclass, field
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from .errors import UpdateError
|
||||
from .options import Options
|
||||
from .version.version import Version, VersionPreference
|
||||
from .utils import run
|
||||
from .version.version import Version, VersionPreference
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -24,11 +24,13 @@ class Package:
|
||||
line: int
|
||||
urls: Optional[List[str]]
|
||||
url: Optional[str]
|
||||
changelog: Optional[str]
|
||||
rev: str
|
||||
hash: Optional[str]
|
||||
mod_sha256: Optional[str]
|
||||
vendor_hash: Optional[str]
|
||||
vendor_sha256: Optional[str]
|
||||
cargo_sha256: Optional[str]
|
||||
cargo_deps: Optional[str]
|
||||
npm_deps: Optional[str]
|
||||
tests: List[str]
|
||||
|
||||
raw_version_position: InitVar[Optional[Dict[str, Any]]]
|
||||
@ -67,10 +69,12 @@ def eval_expression(import_path: str, attr: str) -> str:
|
||||
url = pkg.src.url or null;
|
||||
rev = pkg.src.rev or null;
|
||||
hash = pkg.src.outputHash or null;
|
||||
mod_sha256 = pkg.modSha256 or null;
|
||||
vendor_hash = pkg.vendorHash or null;
|
||||
vendor_sha256 = pkg.vendorSha256 or null;
|
||||
cargo_sha256 = pkg.cargoHash or pkg.cargoSha256 or null;
|
||||
cargo_deps = (pkg.cargoDeps or null).outputHash or null;
|
||||
npm_deps = (pkg.npmDeps or null).outputHash or null;
|
||||
tests = builtins.attrNames (pkg.passthru.tests or {{}});
|
||||
changelog = pkg.meta.changelog or null;
|
||||
}})"""
|
||||
|
||||
|
||||
@ -81,7 +85,7 @@ def eval_attr(opts: Options) -> Package:
|
||||
"eval",
|
||||
"--json",
|
||||
"--impure",
|
||||
"--experimental-features",
|
||||
"--extra-experimental-features",
|
||||
"nix-command",
|
||||
"--expr",
|
||||
expr,
|
||||
@ -89,6 +93,8 @@ def eval_attr(opts: Options) -> Package:
|
||||
res = run(cmd)
|
||||
out = json.loads(res.stdout)
|
||||
package = Package(attribute=opts.attribute, **out)
|
||||
if opts.override_filename is not None:
|
||||
package.filename = opts.override_filename
|
||||
if opts.version_preference != VersionPreference.SKIP and package.old_version == "":
|
||||
raise UpdateError(
|
||||
f"Nix's builtins.parseDrvName could not parse the version from {package.name}"
|
||||
|
@ -1,8 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
from typing import Optional
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from .utils import run
|
||||
|
||||
|
||||
def old_version_from_diff(
|
||||
@ -39,10 +38,8 @@ def old_version_from_diff(
|
||||
def old_version_from_git(
|
||||
filename: str, linenumber: int, new_version: str
|
||||
) -> Optional[str]:
|
||||
proc = subprocess.run(
|
||||
proc = run(
|
||||
["git", "diff", "--color=never", "--word-diff=porcelain", "--", filename],
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
assert proc.stdout is not None
|
||||
if len(proc.stdout) == 0:
|
||||
|
@ -1,5 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
from .version.version import VersionPreference
|
||||
|
||||
|
||||
@ -10,6 +11,7 @@ class Options:
|
||||
version_preference: VersionPreference = VersionPreference.STABLE
|
||||
version_regex: str = "(.*)"
|
||||
import_path: str = "./."
|
||||
override_filename: Optional[str] = None
|
||||
commit: bool = False
|
||||
write_commit_message: Optional[str] = None
|
||||
shell: bool = False
|
||||
|
@ -1,15 +1,16 @@
|
||||
import fileinput
|
||||
from typing import List, Optional, Dict
|
||||
import subprocess
|
||||
import tempfile
|
||||
from typing import Dict, Optional
|
||||
|
||||
from .errors import UpdateError
|
||||
from .eval import Package, eval_attr
|
||||
from .git import old_version_from_git
|
||||
from .options import Options
|
||||
from .utils import info, run
|
||||
from .version import fetch_latest_version
|
||||
from .version.version import Version, VersionPreference
|
||||
from .git import old_version_from_git
|
||||
from .version.version import Version, VersionPreference
|
||||
|
||||
|
||||
def replace_version(package: Package) -> bool:
|
||||
@ -50,13 +51,13 @@ def to_sri(hashstr: str) -> str:
|
||||
|
||||
cmd = [
|
||||
"nix",
|
||||
"--experimental-features",
|
||||
"--extra-experimental-features",
|
||||
"nix-command",
|
||||
"hash",
|
||||
"to-sri",
|
||||
f"{prefix}{hashstr}",
|
||||
]
|
||||
proc = subprocess.run(cmd, stdout=subprocess.PIPE, check=True, text=True)
|
||||
proc = run(cmd)
|
||||
return proc.stdout.rstrip("\n")
|
||||
|
||||
|
||||
@ -69,18 +70,34 @@ def replace_hash(filename: str, current: str, target: str) -> None:
|
||||
print(line, end="")
|
||||
|
||||
|
||||
def nix_prefetch(cmd: List[str]) -> str:
|
||||
def nix_prefetch(expr: str) -> str:
|
||||
extra_env: Dict[str, str] = {}
|
||||
tempdir: Optional[tempfile.TemporaryDirectory[str]] = None
|
||||
if extra_env.get("XDG_RUNTIME_DIR") is None:
|
||||
tempdir = tempfile.TemporaryDirectory()
|
||||
extra_env["XDG_RUNTIME_DIR"] = tempdir.name
|
||||
try:
|
||||
res = run(["nix-prefetch"] + cmd, extra_env=extra_env)
|
||||
res = run(
|
||||
[
|
||||
"nix-build",
|
||||
"--expr",
|
||||
f'let src = {expr}; in (src.overrideAttrs or (f: src // f src)) (_: {{ outputHash = ""; outputHashAlgo = "sha256"; }})',
|
||||
],
|
||||
extra_env=extra_env,
|
||||
stderr=subprocess.PIPE,
|
||||
check=False,
|
||||
)
|
||||
stderr = res.stderr.strip()
|
||||
got = ""
|
||||
for line in stderr.split("\n"):
|
||||
line = line.strip()
|
||||
if line.startswith("got:"):
|
||||
got = line.split("got:")[1].strip()
|
||||
break
|
||||
finally:
|
||||
if tempdir:
|
||||
tempdir.cleanup()
|
||||
return res.stdout.strip()
|
||||
return got
|
||||
|
||||
|
||||
def disable_check_meta(opts: Options) -> str:
|
||||
@ -88,26 +105,28 @@ def disable_check_meta(opts: Options) -> str:
|
||||
|
||||
|
||||
def update_src_hash(opts: Options, filename: str, current_hash: str) -> None:
|
||||
expr = f"(import {opts.import_path} {disable_check_meta(opts)}).{opts.attribute}"
|
||||
target_hash = nix_prefetch([expr])
|
||||
expr = (
|
||||
f"(import {opts.import_path} {disable_check_meta(opts)}).{opts.attribute}.src"
|
||||
)
|
||||
target_hash = nix_prefetch(expr)
|
||||
replace_hash(filename, current_hash, target_hash)
|
||||
|
||||
|
||||
def update_mod256_hash(opts: Options, filename: str, current_hash: str) -> None:
|
||||
expr = f"{{ sha256 }}: (import {opts.import_path} {disable_check_meta(opts)}).{opts.attribute}.go-modules.overrideAttrs (_: {{ modSha256 = sha256; }})"
|
||||
target_hash = nix_prefetch([expr])
|
||||
def update_go_modules_hash(opts: Options, filename: str, current_hash: str) -> None:
|
||||
expr = f"(import {opts.import_path} {disable_check_meta(opts)}).{opts.attribute}.go-modules"
|
||||
target_hash = nix_prefetch(expr)
|
||||
replace_hash(filename, current_hash, target_hash)
|
||||
|
||||
|
||||
def update_go_vendor_hash(opts: Options, filename: str, current_hash: str) -> None:
|
||||
expr = f"{{ sha256 }}: (import {opts.import_path} {disable_check_meta(opts)}).{opts.attribute}.go-modules.overrideAttrs (_: {{ vendorSha256 = sha256; }})"
|
||||
target_hash = nix_prefetch([expr])
|
||||
def update_cargo_deps_hash(opts: Options, filename: str, current_hash: str) -> None:
|
||||
expr = f"(import {opts.import_path} {disable_check_meta(opts)}).{opts.attribute}.cargoDeps"
|
||||
target_hash = nix_prefetch(expr)
|
||||
replace_hash(filename, current_hash, target_hash)
|
||||
|
||||
|
||||
def update_cargo_sha256_hash(opts: Options, filename: str, current_hash: str) -> None:
|
||||
expr = f"{{ sha256 }}: (import {opts.import_path} {disable_check_meta(opts)}).{opts.attribute}.cargoDeps.overrideAttrs (_: {{ inherit sha256; }})"
|
||||
target_hash = nix_prefetch([expr])
|
||||
def update_npm_deps_hash(opts: Options, filename: str, current_hash: str) -> None:
|
||||
expr = f"(import {opts.import_path} {disable_check_meta(opts)}).{opts.attribute}.npmDeps"
|
||||
target_hash = nix_prefetch(expr)
|
||||
replace_hash(filename, current_hash, target_hash)
|
||||
|
||||
|
||||
@ -163,13 +182,16 @@ def update(opts: Options) -> Package:
|
||||
|
||||
# if no package.hash was provided we just update the other hashes unconditionally
|
||||
if update_hash or not package.hash:
|
||||
if package.vendor_sha256:
|
||||
update_go_vendor_hash(opts, package.filename, package.vendor_sha256)
|
||||
# legacy go module checksums
|
||||
elif package.mod_sha256:
|
||||
update_mod256_hash(opts, package.filename, package.mod_sha256)
|
||||
if package.vendor_hash and package.vendor_sha256 == "_unset":
|
||||
update_go_modules_hash(opts, package.filename, package.vendor_hash)
|
||||
|
||||
if package.cargo_sha256:
|
||||
update_cargo_sha256_hash(opts, package.filename, package.cargo_sha256)
|
||||
if package.vendor_sha256 and package.vendor_hash == "_unset":
|
||||
update_go_modules_hash(opts, package.filename, package.vendor_sha256)
|
||||
|
||||
if package.cargo_deps:
|
||||
update_cargo_deps_hash(opts, package.filename, package.cargo_deps)
|
||||
|
||||
if package.npm_deps:
|
||||
update_npm_deps_hash(opts, package.filename, package.npm_deps)
|
||||
|
||||
return package
|
||||
|
@ -2,7 +2,7 @@ import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import IO, Any, Callable, List, Optional, Union, Dict
|
||||
from typing import IO, Any, Callable, Dict, List, Optional, Union
|
||||
|
||||
HAS_TTY = sys.stdout.isatty()
|
||||
ROOT = Path(os.path.dirname(os.path.realpath(__file__)))
|
||||
@ -26,6 +26,7 @@ def run(
|
||||
command: List[str],
|
||||
cwd: Optional[Union[Path, str]] = None,
|
||||
stdout: Union[None, int, IO[Any]] = subprocess.PIPE,
|
||||
stderr: Union[None, int, IO[Any]] = None,
|
||||
check: bool = True,
|
||||
extra_env: Dict[str, str] = {},
|
||||
) -> "subprocess.CompletedProcess[str]":
|
||||
@ -33,5 +34,5 @@ def run(
|
||||
env = os.environ.copy()
|
||||
env.update(extra_env)
|
||||
return subprocess.run(
|
||||
command, cwd=cwd, check=check, text=True, stdout=stdout, env=env
|
||||
command, cwd=cwd, check=check, text=True, stdout=stdout, stderr=stderr, env=env
|
||||
)
|
||||
|
@ -1,16 +1,17 @@
|
||||
from functools import partial
|
||||
from urllib.parse import urlparse, ParseResult
|
||||
from typing import List, Callable, Optional
|
||||
import re
|
||||
from functools import partial
|
||||
from typing import Callable, List, Optional
|
||||
from urllib.parse import ParseResult, urlparse
|
||||
|
||||
from ..errors import VersionError
|
||||
from .crate import fetch_crate_versions
|
||||
from .github import fetch_github_versions, fetch_github_snapshots
|
||||
from .gitlab import fetch_gitlab_versions, fetch_gitlab_snapshots
|
||||
from .pypi import fetch_pypi_versions
|
||||
from .rubygems import fetch_rubygem_versions
|
||||
from .savannah import fetch_savannah_versions
|
||||
from .sourcehut import fetch_sourcehut_versions
|
||||
from .version import VersionPreference, Version
|
||||
from .version import Version, VersionPreference
|
||||
|
||||
# def find_repology_release(attr) -> str:
|
||||
# resp = urllib.request.urlopen(f"https://repology.org/api/v1/projects/{attr}/")
|
||||
@ -22,6 +23,7 @@ from .version import VersionPreference, Version
|
||||
# return None
|
||||
|
||||
fetchers: List[Callable[[ParseResult], List[Version]]] = [
|
||||
fetch_crate_versions,
|
||||
fetch_pypi_versions,
|
||||
fetch_github_versions,
|
||||
fetch_gitlab_versions,
|
||||
|
19
nix_update/version/crate.py
Normal file
19
nix_update/version/crate.py
Normal file
@ -0,0 +1,19 @@
|
||||
import json
|
||||
import urllib.request
|
||||
from typing import List
|
||||
from urllib.parse import ParseResult
|
||||
|
||||
from ..utils import info
|
||||
from .version import Version
|
||||
|
||||
|
||||
def fetch_crate_versions(url: ParseResult) -> List[Version]:
|
||||
if url.netloc != "crates.io":
|
||||
return []
|
||||
parts = url.path.split("/")
|
||||
package = parts[4]
|
||||
crate_url = f"https://crates.io/api/v1/crates/{package}/versions"
|
||||
info(f"fetch {crate_url}")
|
||||
resp = urllib.request.urlopen(crate_url)
|
||||
data = json.loads(resp.read())
|
||||
return [Version(version["num"]) for version in data["versions"]]
|
@ -1,13 +1,13 @@
|
||||
import re
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ET
|
||||
from xml.etree.ElementTree import Element
|
||||
from typing import List
|
||||
from urllib.parse import ParseResult, urlparse
|
||||
from xml.etree.ElementTree import Element
|
||||
|
||||
from .version import Version
|
||||
from ..errors import VersionError
|
||||
from ..utils import info
|
||||
from .version import Version
|
||||
|
||||
|
||||
def version_from_entry(entry: Element) -> Version:
|
||||
|
@ -5,9 +5,9 @@ from datetime import datetime
|
||||
from typing import List
|
||||
from urllib.parse import ParseResult, quote_plus
|
||||
|
||||
from .version import Version
|
||||
from ..errors import VersionError
|
||||
from ..utils import info
|
||||
from .version import Version
|
||||
|
||||
GITLAB_API = re.compile(
|
||||
r"http(s)?://(?P<domain>[^/]+)/api/v4/projects/(?P<project_id>[^/]*)/repository/archive.tar.gz\?sha=(?P<version>.+)"
|
||||
|
@ -3,8 +3,8 @@ import urllib.request
|
||||
from typing import List
|
||||
from urllib.parse import ParseResult
|
||||
|
||||
from .version import Version
|
||||
from ..utils import info
|
||||
from .version import Version
|
||||
|
||||
|
||||
def fetch_pypi_versions(url: ParseResult) -> List[Version]:
|
||||
|
@ -1,12 +1,11 @@
|
||||
import json
|
||||
import urllib.request
|
||||
from typing import List
|
||||
from urllib.parse import ParseResult
|
||||
import json
|
||||
|
||||
from .version import Version
|
||||
from ..errors import VersionError
|
||||
|
||||
from ..utils import info
|
||||
from .version import Version
|
||||
|
||||
|
||||
def fetch_rubygem_versions(url: ParseResult) -> List[Version]:
|
||||
|
@ -1,13 +1,12 @@
|
||||
import re
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ET
|
||||
from typing import List, Optional
|
||||
from urllib.parse import ParseResult, urljoin, urlparse
|
||||
import xml.etree.ElementTree as ET
|
||||
from xml.etree.ElementTree import Element
|
||||
|
||||
from .version import Version
|
||||
from ..utils import info
|
||||
|
||||
from .version import Version
|
||||
|
||||
filename_regex = re.compile(r"-(\d+(?:\.\d+)*(?:-[^-.]+)?)\.tar\.[^.]+$")
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ET
|
||||
from xml.etree.ElementTree import Element
|
||||
from typing import List
|
||||
from urllib.parse import ParseResult, urlparse
|
||||
from xml.etree.ElementTree import Element
|
||||
|
||||
from .version import Version
|
||||
from ..errors import VersionError
|
||||
from ..utils import info
|
||||
from .version import Version
|
||||
|
||||
|
||||
def version_from_entry(entry: Element) -> Version:
|
||||
|
@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum, auto
|
||||
from typing import Optional
|
||||
|
@ -41,6 +41,9 @@ restructuredtext = true
|
||||
strict = true[wheel]
|
||||
universal = 1
|
||||
|
||||
[isort]
|
||||
profile=black
|
||||
|
||||
[pycodestyle]
|
||||
max-line-length = 88
|
||||
# E203 conflicts with black
|
||||
|
@ -1,7 +1,8 @@
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
|
||||
with pkgs;
|
||||
pkgs.mkShell {
|
||||
|
||||
mkShellNoCC {
|
||||
buildInputs = [
|
||||
(import ./. { }).passthru.env
|
||||
];
|
||||
|
@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Type, Iterator
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import Iterator, Type
|
||||
|
||||
import pytest
|
||||
|
||||
TEST_ROOT = Path(__file__).parent.resolve()
|
||||
sys.path.append(str(TEST_ROOT.parent))
|
||||
@ -20,11 +20,23 @@ class Helpers:
|
||||
|
||||
@staticmethod
|
||||
@contextmanager
|
||||
def testpkgs() -> Iterator[Path]:
|
||||
def testpkgs(init_git: bool = False) -> Iterator[Path]:
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
shutil.copytree(
|
||||
Helpers.root().joinpath("testpkgs"), tmpdirname, dirs_exist_ok=True
|
||||
)
|
||||
if init_git:
|
||||
os.environ["GIT_AUTHOR_NAME"] = "nix-update"
|
||||
os.environ["GIT_AUTHOR_EMAIL"] = "nix-update@example.com"
|
||||
os.environ["GIT_COMMITTER_NAME"] = "nix-update"
|
||||
os.environ["GIT_COMMITTER_EMAIL"] = "nix-update@example.com"
|
||||
|
||||
subprocess.run(["git", "-C", tmpdirname, "init"], check=True)
|
||||
subprocess.run(["git", "-C", tmpdirname, "add", "--all"], check=True)
|
||||
subprocess.run(
|
||||
["git", "-C", tmpdirname, "commit", "-m", "first commit"],
|
||||
check=True,
|
||||
)
|
||||
yield Path(tmpdirname)
|
||||
|
||||
|
||||
|
27
tests/test_crate.py
Normal file
27
tests/test_crate.py
Normal file
@ -0,0 +1,27 @@
|
||||
import subprocess
|
||||
|
||||
import conftest
|
||||
|
||||
from nix_update.options import Options
|
||||
from nix_update.update import update
|
||||
|
||||
|
||||
def test_update(helpers: conftest.Helpers) -> None:
|
||||
with helpers.testpkgs() as path:
|
||||
opts = Options(attribute="crate", import_path=str(path))
|
||||
update(opts)
|
||||
version = subprocess.run(
|
||||
[
|
||||
"nix",
|
||||
"eval",
|
||||
"--raw",
|
||||
"--extra-experimental-features",
|
||||
"nix-command",
|
||||
"-f",
|
||||
path,
|
||||
"crate.version",
|
||||
],
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
assert version.stdout.strip() >= "8.5.2"
|
@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from pathlib import Path
|
||||
from nix_update.git import old_version_from_diff
|
||||
|
||||
import conftest
|
||||
|
||||
from nix_update.git import old_version_from_diff
|
||||
|
||||
TEST_ROOT = Path(__file__).parent.resolve()
|
||||
|
||||
|
||||
|
27
tests/test_npm.py
Normal file
27
tests/test_npm.py
Normal file
@ -0,0 +1,27 @@
|
||||
import subprocess
|
||||
|
||||
import conftest
|
||||
|
||||
from nix_update.options import Options
|
||||
from nix_update.update import update
|
||||
|
||||
|
||||
def test_update(helpers: conftest.Helpers) -> None:
|
||||
with helpers.testpkgs() as path:
|
||||
opts = Options(attribute="npm", import_path=str(path))
|
||||
update(opts)
|
||||
version = subprocess.run(
|
||||
[
|
||||
"nix",
|
||||
"eval",
|
||||
"--raw",
|
||||
"--extra-experimental-features",
|
||||
"nix-command",
|
||||
"-f",
|
||||
path,
|
||||
"npm.version",
|
||||
],
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
assert version.stdout.strip() > "10.8.6"
|
@ -1,27 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from nix_update.options import Options
|
||||
from nix_update.update import update
|
||||
import subprocess
|
||||
|
||||
import conftest
|
||||
|
||||
from nix_update import main
|
||||
|
||||
def test_update(helpers: conftest.Helpers) -> None:
|
||||
with helpers.testpkgs() as path:
|
||||
opts = Options(attribute="pypi", import_path=str(path))
|
||||
update(opts)
|
||||
|
||||
def test_main(helpers: conftest.Helpers) -> None:
|
||||
with helpers.testpkgs(init_git=True) as path:
|
||||
main(["--file", str(path), "--commit", "pypi"])
|
||||
version = subprocess.run(
|
||||
[
|
||||
"nix",
|
||||
"eval",
|
||||
"--raw",
|
||||
"--experimental-features",
|
||||
"--extra-experimental-features",
|
||||
"nix-command",
|
||||
"-f",
|
||||
path,
|
||||
"pypi.version",
|
||||
],
|
||||
check=True,
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
).stdout.strip()
|
||||
assert version >= "3.0.1"
|
||||
commit = subprocess.run(
|
||||
["git", "-C", path, "log", "-1"],
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
check=True,
|
||||
).stdout.strip()
|
||||
print(commit)
|
||||
assert version in commit
|
||||
assert "pypi" in commit
|
||||
assert (
|
||||
f"https://github.com/Mic92/python-mpd2/blob/{version}/doc/changes.rst"
|
||||
in commit
|
||||
)
|
||||
assert version.stdout.strip() >= "3.0.1"
|
||||
|
@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
|
||||
import conftest
|
||||
|
||||
from nix_update.options import Options
|
||||
from nix_update.update import update
|
||||
import subprocess
|
||||
import conftest
|
||||
|
||||
|
||||
def test_update(helpers: conftest.Helpers) -> None:
|
||||
@ -15,7 +15,7 @@ def test_update(helpers: conftest.Helpers) -> None:
|
||||
"nix",
|
||||
"eval",
|
||||
"--raw",
|
||||
"--experimental-features",
|
||||
"--extra-experimental-features",
|
||||
"nix-command",
|
||||
"-f",
|
||||
path,
|
||||
|
@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
|
||||
import conftest
|
||||
|
||||
from nix_update.options import Options
|
||||
from nix_update.update import update
|
||||
import subprocess
|
||||
import conftest
|
||||
|
||||
|
||||
def test_update(helpers: conftest.Helpers) -> None:
|
||||
@ -15,7 +15,7 @@ def test_update(helpers: conftest.Helpers) -> None:
|
||||
"nix",
|
||||
"eval",
|
||||
"--raw",
|
||||
"--experimental-features",
|
||||
"--extra-experimental-features",
|
||||
"nix-command",
|
||||
"-f",
|
||||
path,
|
||||
|
13
tests/testpkgs/crate.nix
Normal file
13
tests/testpkgs/crate.nix
Normal file
@ -0,0 +1,13 @@
|
||||
{ rustPlatform, fetchCrate }:
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "fd-find";
|
||||
version = "8.0.0";
|
||||
|
||||
src = fetchCrate {
|
||||
inherit pname version;
|
||||
sha256 = "";
|
||||
};
|
||||
|
||||
cargoSha256 = "";
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
{
|
||||
crate = pkgs.callPackage ./crate.nix {};
|
||||
pypi = pkgs.python3.pkgs.callPackage ./pypi.nix {};
|
||||
sourcehut = pkgs.python3.pkgs.callPackage ./sourcehut.nix {};
|
||||
savanna = pkgs.python3.pkgs.callPackage ./savanna.nix {};
|
||||
npm = pkgs.callPackage ./npm.nix {};
|
||||
}
|
||||
|
18
tests/testpkgs/npm.nix
Normal file
18
tests/testpkgs/npm.nix
Normal file
@ -0,0 +1,18 @@
|
||||
{ lib
|
||||
, fetchFromGitHub
|
||||
, buildNpmPackage
|
||||
}:
|
||||
|
||||
buildNpmPackage rec {
|
||||
pname = "jellyfin-web";
|
||||
version = "10.8.6";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jellyfin";
|
||||
repo = "jellyfin-web";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
}
|
@ -6,7 +6,7 @@ buildPythonPackage rec {
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
|
||||
checkInputs = [
|
||||
@ -16,4 +16,6 @@ buildPythonPackage rec {
|
||||
];
|
||||
|
||||
pytestFlagsArray = [ "mpd/tests.py" ];
|
||||
|
||||
meta.changelog = "https://github.com/Mic92/python-mpd2/blob/${version}/doc/changes.rst";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user