Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions nix_update/eval.nix
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ in
rev = pkg.src.rev or null;
tag = pkg.src.tag or null;
hash = pkg.src.outputHash or null;
commit_sha = pkg.commitSha or null;
commit_date = pkg.commitDate or null;
fod_subpackage = pkg.outputHash or null;
go_modules = pkg.goModules.outputHash or null;
go_modules_old = pkg.go-modules.outputHash or null;
Expand Down
2 changes: 2 additions & 0 deletions nix_update/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class Package:
rev: str | None
tag: str | None
hash: str | None
commit_sha: str | None
commit_date: str | None
fod_subpackage: str | None
go_modules: str | None
go_modules_old: str | None
Expand Down
97 changes: 81 additions & 16 deletions nix_update/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import fileinput
from copy import deepcopy
from dataclasses import dataclass
from datetime import UTC
from pathlib import Path
from typing import TYPE_CHECKING

Expand All @@ -18,6 +20,71 @@
from .options import Options


@dataclass
class ReplacementContext:
"""Context for applying version replacements to a file."""

old_version: str
new_version: str
old_rev_tag: str | None
version_string_in_declaration: bool


def apply_line_replacements(
line: str,
line_number: int,
package: Package,
context: ReplacementContext,
) -> str:
"""Apply version, rev, commitSha, and commitDate replacements to a line."""
modified_line = line
# Update rev/tag if present
if (
context.old_rev_tag is not None
and package.new_version
and package.new_version.rev
):
modified_line = modified_line.replace(
context.old_rev_tag,
package.new_version.rev,
)
# Update commitSha if present
if (
package.commit_sha is not None
and package.new_version
and package.new_version.rev is not None
):
modified_line = modified_line.replace(
f'"{package.commit_sha}"',
f'"{package.new_version.rev}"',
)
# Update commitDate if present
if (
package.commit_date is not None
and package.new_version
and package.new_version.commit_date is not None
):
new_commit_date_str = (
package.new_version.commit_date.astimezone(UTC)
.isoformat()
.replace("+00:00", "Z")
)
modified_line = modified_line.replace(
f'"{package.commit_date}"',
f'"{new_commit_date_str}"',
)
# Update version string
if not context.version_string_in_declaration or (
package.version_position is not None
and package.version_position.line == line_number
):
modified_line = modified_line.replace(
f'"{context.old_version}"',
f'"{context.new_version}"',
)
return modified_line


def replace_version(package: Package) -> bool:
if package.new_version is None:
msg = "Package new_version is None, cannot replace version"
Expand All @@ -33,29 +100,27 @@ def replace_version(package: Package) -> bool:

if changed:
info(f"Update {old_version} -> {new_version} in {package.filename}")
version_string_in_version_declaration = False
version_string_in_declaration = False
if package.version_position is not None:
with Path(package.filename).open() as f:
for i, line in enumerate(f, 1):
if package.version_position.line == i:
version_string_in_version_declaration = old_version in line
version_string_in_declaration = old_version in line
break
context = ReplacementContext(
old_version=old_version,
new_version=new_version,
old_rev_tag=old_rev_tag,
version_string_in_declaration=version_string_in_declaration,
)
with fileinput.FileInput(package.filename, inplace=True) as f:
for i, original_line in enumerate(f, 1):
modified_line = original_line
if old_rev_tag is not None and package.new_version.rev:
modified_line = modified_line.replace(
old_rev_tag,
package.new_version.rev,
)
if not version_string_in_version_declaration or (
package.version_position is not None
and package.version_position.line == i
):
modified_line = modified_line.replace(
f'"{old_version}"',
f'"{new_version}"',
)
modified_line = apply_line_replacements(
line=original_line,
line_number=i,
package=package,
context=context,
)
print(modified_line, end="")
else:
info(f"Not updating version, already {old_version}")
Expand Down
12 changes: 10 additions & 2 deletions nix_update/version/bitbucket.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

from datetime import datetime
from typing import TYPE_CHECKING

from .http import fetch_json
Expand Down Expand Up @@ -32,5 +33,12 @@ def fetch_bitbucket_snapshots(url: ParseResult, branch: str) -> list[Version]:
versions = fetch_bitbucket_versions(url)
latest_version = versions[0].number if versions else "0"

date = ref["date"][:10] # to YYYY-MM-DD
return [Version(f"{latest_version}-unstable-{date}", rev=ref["hash"])]
date = ref["date"]
commit_date = datetime.fromisoformat(ref["date"])
return [
Version(
f"{latest_version}-unstable-{date[:10]}",
rev=ref["hash"],
commit_date=commit_date,
),
]
12 changes: 10 additions & 2 deletions nix_update/version/gitea.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import re
from datetime import datetime
from http import HTTPStatus
from typing import TYPE_CHECKING
from urllib import request
Expand Down Expand Up @@ -64,5 +65,12 @@ def fetch_gitea_snapshots(url: ParseResult, branch: str) -> list[Version]:
versions = fetch_gitea_versions(url)
latest_version = versions[0].number if versions else "0"

date = commit["commit"]["committer"]["date"][:10]
return [Version(f"{latest_version}-unstable-{date}", rev=commit["sha"])]
date = commit["commit"]["committer"]["date"]
commit_date = datetime.fromisoformat(date)
return [
Version(
f"{latest_version}-unstable-{date[:10]}",
rev=commit["sha"],
commit_date=commit_date,
),
]
19 changes: 17 additions & 2 deletions nix_update/version/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import re
import urllib.request
import xml.etree.ElementTree as ET
from datetime import datetime
from http import HTTPStatus
from typing import Any
from urllib.parse import ParseResult, unquote, urlparse
Expand Down Expand Up @@ -114,7 +115,16 @@ def fetch_github_versions_from_releases(
except json.JSONDecodeError:
info("unable to parse github response, ignoring")
return []
return [Version(r["tag_name"], r["prerelease"]) for r in releases]
return [
Version(
number=r["tag_name"],
prerelease=r["prerelease"],
commit_date=datetime.fromisoformat(r["created_at"])
if r.get("created_at")
else None,
)
for r in releases
]


def fetch_github_versions_from_feed(
Expand Down Expand Up @@ -195,8 +205,13 @@ def fetch_github_snapshots(
url = urlparse(link.attrib["href"])
commit = url.path.rsplit("/", maxsplit=1)[-1]
date = updated.text.split("T", maxsplit=1)[0]
commit_datetime = datetime.fromisoformat(updated.text)
return [
Version(f"{version}-unstable-{date}", rev=commit)
Version(
f"{version}-unstable-{date}",
rev=commit,
commit_date=commit_datetime,
)
for version in version_numbers
]

Expand Down
14 changes: 8 additions & 6 deletions nix_update/version/gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ def fetch_gitlab_snapshots(url: ParseResult, branch: str) -> list[Version]:
latest_version = versions[0].number if versions else "0"

for commit in commits:
commit_date = datetime.strptime(
commit["committed_date"],
"%Y-%m-%dT%H:%M:%S.000%z",
)
commit_date -= commit_date.utcoffset() # type: ignore[operator]
commit_date = datetime.fromisoformat(commit["committed_date"])
date = commit_date.strftime("%Y-%m-%d")
return [Version(f"{latest_version}-unstable-{date}", rev=commit["id"])]
return [
Version(
f"{latest_version}-unstable-{date}",
rev=commit["id"],
commit_date=commit_date,
),
]
return []
6 changes: 5 additions & 1 deletion nix_update/version/sourcehut.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ def snapshot_from_entry(entry: Element, url: ParseResult) -> Version:
msg = f"No link found in atom feed {url}"
raise VersionError(msg)
rev = node.text.split("/")[-1]
return Version(f"{latest_version}-unstable-{date_str}", rev=rev)
return Version(
f"{latest_version}-unstable-{date_str}",
rev=rev,
commit_date=parsed,
)


def fetch_sourcehut_versions(url: ParseResult) -> list[Version]:
Expand Down
5 changes: 5 additions & 0 deletions nix_update/version/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

from dataclasses import dataclass
from enum import StrEnum, auto
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from datetime import datetime


@dataclass
Expand All @@ -10,6 +14,7 @@ class Version:
prerelease: bool | None = None
rev: str | None = None
tag: str | None = None
commit_date: datetime | None = None


class VersionPreference(StrEnum):
Expand Down
Loading