Skip to content

Commit

Permalink
Remove install/no-install/ignore duplication
Browse files Browse the repository at this point in the history
Pre-populate the installation lists with common patterns.  Thie removes
the need to copy-paste essentially the same `ignore.list` and
`no-install.list`.
  • Loading branch information
elprans committed Oct 11, 2024
1 parent 542bd23 commit 5a6463c
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 17 deletions.
109 changes: 93 additions & 16 deletions metapkg/packages/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,14 @@ def get_requirements(self) -> list[poetry_dep.Dependency]:
def get_build_requirements(self) -> list[poetry_dep.Dependency]:
return []

def get_license_files_pattern(self) -> str:
return "{LICENSE*,COPYING,NOTICE,COPYRIGHT}"
def get_license_files_patterns(self) -> list[str]:
return [
"LICENSE*",
"LICENCE*",
"COPYING",
"NOTICE",
"COPYRIGHT",
]

def get_prepare_script(self, build: targets.Build) -> str:
return ""
Expand All @@ -146,7 +152,7 @@ def get_build_env(self, build: targets.Build, wd: str) -> Args:
def get_build_install_script(self, build: targets.Build) -> str:
script = ""

licenses = self.get_license_files_pattern()
licenses = self.get_license_files_patterns()
if licenses:
sdir = build.get_source_dir(self, relative_to="pkgbuild")
legaldir = build.get_install_path(self, "legal").relative_to("/")
Expand All @@ -155,10 +161,11 @@ def get_build_install_script(self, build: targets.Build) -> str:
/ legaldir
)
prefix = str(lic_dest / self.name)
licenses_pattern = "{" + ",".join(licenses) + "}"
script += textwrap.dedent(
f"""\
mkdir -p "{lic_dest}"
for _lic_src in "{sdir}"/{licenses}; do
for _lic_src in "{sdir}"/{licenses_pattern}; do
if [ -e "$_lic_src" ]; then
cp "$_lic_src" "{prefix}-$(basename "$_lic_src")"
fi
Expand All @@ -185,40 +192,88 @@ def _get_file_list_script(
listname: str,
*,
entries: list[str],
imply_parents: bool,
) -> str:
if entries:
script = self.write_file_list_script(build, listname, entries)
script = self.write_file_list_script(
build, listname, entries, imply_parents
)
else:
script = ""

return script

def get_file_install_entries(self, build: targets.Build) -> list[str]:
entries = []
if self.get_license_files_pattern():
entries.append("{legaldir}/*")
for shlib in self.get_shlibs(build):
shlib_fn = build.target.get_shlib_filename(shlib)
entries.append(f"{{libdir}}/{shlib_fn}*")
for lic_pattern in self.get_license_files_patterns():
entries.append(f"{{legaldir}}/{{name}}-{lic_pattern}")
return entries

def get_install_list_script(self, build: targets.Build) -> str:
entries = self.get_file_install_entries(build)
entries += [
str(p.relative_to("/")) for p in self.get_service_scripts(build)
]
return self._get_file_list_script(build, "install", entries=entries)
return self._get_file_list_script(
build,
"install",
entries=entries,
imply_parents=True,
)

def get_file_no_install_entries(self, build: targets.Build) -> list[str]:
return []
return [
# Never install static libraries or libtool stuff
"{libdir}/*.a",
"{libdir}/*.la",
]

def get_no_install_list_script(self, build: targets.Build) -> str:
entries = self.get_file_no_install_entries(build)
return self._get_file_list_script(build, "no_install", entries=entries)
return self._get_file_list_script(
build,
"no_install",
entries=entries,
imply_parents=False,
)

def get_file_ignore_entries(self, build: targets.Build) -> list[str]:
return []
return [
# ignore binaries by default, packages can opt-in with
# explicit entries in install.list
"{bindir}/*",
# autoconf, pkg-config and CMake stuff are not useful
"{datadir}/aclocal/**",
"{libdir}/aclocal/**",
"{datadir}/cmake/**",
"{libdir}/cmake/**",
"{datadir}/pkgconfig/**",
"{libdir}/pkgconfig/**",
# likewise, include files
"{includedir}/**",
# And the documentation
"{mandir}/**",
"{docdir}/**",
"{infodir}/**",
"{datadir}/gtk-doc/**",
"{bundlemandir}/**",
"{bundledocdir}/**",
"{bundleinfodir}/**",
"{bundledatadir}/gtk-doc",
"{bundledatadir}/gtk-doc/**",
]

def get_ignore_list_script(self, build: targets.Build) -> str:
entries = self.get_file_ignore_entries(build)
return self._get_file_list_script(build, "ignore", entries=entries)
return self._get_file_list_script(
build,
"ignore",
entries=entries,
imply_parents=True,
)

def get_private_libraries(self, build: targets.Build) -> list[str]:
return []
Expand Down Expand Up @@ -284,7 +339,11 @@ def get_root_install_subdir(
raise NotImplementedError

def write_file_list_script(
self, build: targets.Build, listname: str, entries: list[str]
self,
build: targets.Build,
listname: str,
entries: list[str],
imply_parents: bool,
) -> str:
installdest = build.get_build_install_dir(self, relative_to="pkgbuild")

Expand All @@ -298,6 +357,7 @@ def write_file_list_script(
"legal",
"doc",
"man",
"info",
):
path = build.get_install_path(self, aspect) # type: ignore
paths[f"{aspect}dir"] = path.relative_to("/")
Expand All @@ -324,16 +384,25 @@ def write_file_list_script(
patterns = {patterns}
matches = set()
for pattern in patterns:
if pattern.endswith('/**'):
pattern += "/*"
for p in tmp.glob(pattern):
if p.exists():
print(p.relative_to(tmp))
rel_p = p.relative_to(tmp)
matches.add(rel_p)
if {imply_parents}:
matches.update(rel_p.parents)
for match in matches:
print(match)
"""
).format(
installdest=str(installdest),
patterns=pprint.pformat(processed_entries),
imply_parents=str(imply_parents),
)

scriptfile_name = f"_gen_{listname}_list_{self.unique_name}.py"
Expand Down Expand Up @@ -1358,9 +1427,9 @@ def get_build_install_script(self, build: targets.Build) -> str:
find = build.sh_get_command("find")
sed = build.sh_get_command("sed")
destdir = self.sh_get_make_install_destdir(build, "$(pwd)")
libdir = build.get_install_path(self, "lib")
libdir = self.get_install_path(build, "lib")
re_libdir = re.escape(str(libdir))
includedir = build.get_install_path(self, "include")
includedir = self.get_install_path(build, "include")
re_includedir = re.escape(str(includedir))
prefix = build.get_install_prefix(self)
re_prefix = re.escape(str(prefix))
Expand Down Expand Up @@ -1414,6 +1483,7 @@ def get_configure_args(
"--datarootdir": build.get_install_path(self, "data"),
"--docdir": build.get_install_path(self, "doc"),
"--mandir": build.get_install_path(self, "man"),
"--infodir": build.get_install_path(self, "info"),
}

def configure_dependency(
Expand Down Expand Up @@ -1491,10 +1561,12 @@ def get_configure_args(
"--bindir": build.get_install_path(self, "bin"),
"--sbindir": build.get_install_path(self, "bin"),
"--libdir": build.get_install_path(self, "lib"),
"--localstatedir": build.get_install_path(self, "localstate"),
"--includedir": build.get_install_path(self, "include"),
# Meson does not support --docdir
# "--docdir": build.get_install_path(self, "doc"),
"--mandir": build.get_install_path(self, "man"),
"--infodir": build.get_install_path(self, "info"),
"-Ddefault_library": "shared",
}

Expand Down Expand Up @@ -1652,6 +1724,11 @@ def get_configure_script(self, build: targets.Build) -> str:
f'CACHE PATH "Output directory for man pages")'
)

config.append(
f'set(CMAKE_INSTALL_INFODIR "{build.get_rel_install_path(self, "info")}" '
f'CACHE PATH "Output directory for info pages")'
)

config.extend(
[
f'set(CMAKE_USER_MAKE_RULES_OVERRIDE "{build_rules_path}" '
Expand Down
13 changes: 12 additions & 1 deletion metapkg/packages/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,11 +540,22 @@ def get_install_list_script(self, build: targets.Build) -> str:
if not record.exists():
raise RuntimeError(f'no wheel RECORD for {pkgname}')
entries = set()
with open(record) as f:
for entry in f:
filename = entry.split(',')[0]
install_path = (sitepackages / filename).resolve()
print(install_path.relative_to('/'))
rel_install_path = install_path.relative_to('/')
if rel_install_path.parent.name == "bin":
# Avoid installing entry point scripts,
# have packages opt-in explicitly.
continue
entries.add(rel_install_path)
entries.update(rel_install_path.parents)
for entry in sorted(entries):
print(entry)
"""
)

Expand Down
3 changes: 3 additions & 0 deletions metapkg/targets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"data",
"doc",
"man",
"info",
"include",
"lib",
"runstate",
Expand Down Expand Up @@ -667,6 +668,8 @@ def get_install_path(
return root / "usr" / "share" / "doc" / root_subdir / "licenses"
elif aspect == "doc":
return root / "usr" / "share" / "doc" / root_subdir
elif aspect == "info":
return root / "usr" / "share" / "info"
elif aspect == "man":
return root / "usr" / "share" / "man"
elif aspect == "bin":
Expand Down
2 changes: 2 additions & 0 deletions metapkg/targets/generic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ def get_install_path(
return prefix / "licenses"
elif aspect == "doc":
return prefix / "doc" / root_subdir
elif aspect == "info":
return prefix / "info"
elif aspect == "man":
return prefix / "man"
elif aspect == "bin":
Expand Down
2 changes: 2 additions & 0 deletions metapkg/targets/macos/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,8 @@ def get_install_path(
return root / "share" / root_subdir
elif aspect == "doc":
return root / "share" / "doc" / root_subdir
elif aspect == "info":
return root / "share" / "info"
elif aspect == "man":
return root / "share" / "man"
else:
Expand Down

0 comments on commit 5a6463c

Please sign in to comment.