···1{ fetchFromGitHub, sourceData }:
23-# Using fetchFromGitHub from their mirror because it's a lot faster than their git server
4-# If you want you could fetchgit from "https://git.FreeBSD.org/src.git" instead.
5# The update script still pulls directly from git.freebsd.org
006fetchFromGitHub {
7 owner = "freebsd";
8 repo = "freebsd-src";
9 inherit (sourceData) rev hash;
10-11- # The GitHub export excludes some files in the git source
12- # that were marked `export-ignore`.
13- # A normal git checkout will keep those files,
14- # matching the update script
15- forceFetchGit = true;
16}
···1{ fetchFromGitHub, sourceData }:
23+# Using fetchFromGitHub from their mirror because we cannot use git during bootstrap
4+# If you want you could fetchurl from "https://cgit.FreeBSD.org/src" instead.
5# The update script still pulls directly from git.freebsd.org
6+# Note that hashes with `forceFetchGit = true` may be different due to `export-ignore`
7+# directives in gitattributes files.
8fetchFromGitHub {
9 owner = "freebsd";
10 repo = "freebsd-src";
11 inherit (sourceData) rev hash;
00000012}
+28-33
pkgs/os-specific/bsd/freebsd/update.py
···11import re
12import subprocess
13import sys
014import tempfile
15import typing
16import urllib.request
1718_QUERY_VERSION_PATTERN = re.compile('^([A-Z]+)="(.+)"$')
19-_RELEASE_PATCH_PATTERN = re.compile('^RELEASE-p([0-9]+)$')
20BASE_DIR = os.path.dirname(os.path.abspath(__file__))
21MIN_VERSION = packaging.version.Version("13.0.0")
22MAIN_BRANCH = "main"
···3233def request_supported_refs() -> list[str]:
34 # Looks pretty shady but I think this should work with every version of the page in the last 20 years
35- r = re.compile("^h\d$", re.IGNORECASE)
36 soup = bs4.BeautifulSoup(
37 urllib.request.urlopen("https://www.freebsd.org/security"), features="lxml"
38 )
···45 return list(df["Branch"])
464748-def query_version(repo: git.Repo) -> dict[str, typing.Any]:
49 # This only works on FreeBSD 13 and later
50 text = (
51 subprocess.check_output(
52- ["bash", os.path.join(repo.working_dir, "sys", "conf", "newvers.sh"), "-v"]
53 )
54 .decode("utf-8")
55 .strip()
···86 print(f"{ref_name}: revision still {rev.hexsha}, skipping")
87 return old_versions[ref_name]
8889- repo.git.checkout(rev)
90- print(f"{ref_name}: checked out {rev.hexsha}")
000009192- full_hash = (
93- subprocess.check_output(["nix", "hash", "path", "--sri", repo.working_dir])
94- .decode("utf-8")
95- .strip()
96- )
97- print(f"{ref_name}: hash is {full_hash}")
9899- version = query_version(repo)
100- print(f"{ref_name}: version is {version['version']}")
101102 return {
103 "rev": rev.hexsha,
···115 print(f"Selected temporary directory {temp_dir.name}")
116117 if len(sys.argv) >= 2:
118- orig_repo = git.Repo(sys.argv[1])
119- print(f"Fetching updates on {orig_repo.git_dir}")
120- orig_repo.remote("origin").fetch()
121 else:
122 print("Cloning source repo")
123- orig_repo = git.Repo.clone_from(
124- "https://git.FreeBSD.org/src.git", to_path=os.path.join(temp_dir.name, "orig")
125 )
126127 supported_refs = request_supported_refs()
128 print(f"Supported refs are: {' '.join(supported_refs)}")
129130- print("Doing git crimes, do not run `git worktree prune` until after script finishes!")
131- workdir = os.path.join(temp_dir.name, "work")
132- git.cmd.Git(orig_repo.git_dir).worktree("add", "--orphan", workdir)
133-134- # Have to create object before removing .git otherwise it will complain
135- repo = git.Repo(workdir)
136- repo.git.set_persistent_git_options(git_dir=repo.git_dir)
137- # Remove so that nix hash doesn't see the file
138- os.remove(os.path.join(workdir, ".git"))
139-140- print(f"Working in directory {repo.working_dir} with git directory {repo.git_dir}")
141-142143 try:
144 with open(os.path.join(BASE_DIR, "versions.json"), "r") as f:
···191 )
192 versions[fullname] = result
193194-195 with open(os.path.join(BASE_DIR, "versions.json"), "w") as out:
196 json.dump(versions, out, sort_keys=True, indent=2)
197 out.write("\n")
198199-if __name__ == '__main__':
0200 main()
···11import re
12import subprocess
13import sys
14+import tarfile
15import tempfile
16import typing
17import urllib.request
1819_QUERY_VERSION_PATTERN = re.compile('^([A-Z]+)="(.+)"$')
20+_RELEASE_PATCH_PATTERN = re.compile("^RELEASE-p([0-9]+)$")
21BASE_DIR = os.path.dirname(os.path.abspath(__file__))
22MIN_VERSION = packaging.version.Version("13.0.0")
23MAIN_BRANCH = "main"
···3334def request_supported_refs() -> list[str]:
35 # Looks pretty shady but I think this should work with every version of the page in the last 20 years
36+ r = re.compile(r"^h\d$", re.IGNORECASE)
37 soup = bs4.BeautifulSoup(
38 urllib.request.urlopen("https://www.freebsd.org/security"), features="lxml"
39 )
···46 return list(df["Branch"])
474849+def query_version(work_dir: str) -> dict[str, typing.Any]:
50 # This only works on FreeBSD 13 and later
51 text = (
52 subprocess.check_output(
53+ ["bash", os.path.join(work_dir, "sys", "conf", "newvers.sh"), "-v"]
54 )
55 .decode("utf-8")
56 .strip()
···87 print(f"{ref_name}: revision still {rev.hexsha}, skipping")
88 return old_versions[ref_name]
8990+ tar_content = io.BytesIO()
91+ repo.archive(tar_content, rev, format="tar")
92+ tar_content.seek(0)
93+94+ with tempfile.TemporaryDirectory(dir="/tmp") as work_dir:
95+ file = tarfile.TarFile(fileobj=tar_content)
96+ file.extractall(path=work_dir, filter="data")
9798+ full_hash = (
99+ subprocess.check_output(["nix", "hash", "path", "--sri", work_dir])
100+ .decode("utf-8")
101+ .strip()
102+ )
103+ print(f"{ref_name}: hash is {full_hash}")
104105+ version = query_version(work_dir)
106+ print(f"{ref_name}: version is {version['version']}")
107108 return {
109 "rev": rev.hexsha,
···121 print(f"Selected temporary directory {temp_dir.name}")
122123 if len(sys.argv) >= 2:
124+ repo = git.Repo(sys.argv[1])
125+ print(f"Fetching updates on {repo.git_dir}")
126+ repo.remote("origin").fetch()
127 else:
128 print("Cloning source repo")
129+ repo = git.Repo.clone_from(
130+ "https://git.FreeBSD.org/src.git", to_path=temp_dir.name
131 )
132133 supported_refs = request_supported_refs()
134 print(f"Supported refs are: {' '.join(supported_refs)}")
135136+ print(f"git directory {repo.git_dir}")
00000000000137138 try:
139 with open(os.path.join(BASE_DIR, "versions.json"), "r") as f:
···186 )
187 versions[fullname] = result
1880189 with open(os.path.join(BASE_DIR, "versions.json"), "w") as out:
190 json.dump(versions, out, sort_keys=True, indent=2)
191 out.write("\n")
192193+194+if __name__ == "__main__":
195 main()