Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nFPM backend for building system packages (only the nfpm core bits) #19308

Merged
merged 200 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
200 commits
Select commit Hold shift + click to select a range
0473c1e
Add TraverseIfNotPackageTarget
cognifloyd Jun 8, 2023
2343cd3
Add test for TraverseIfNotPackageTarget
cognifloyd Jun 8, 2023
08c00f8
fmt
cognifloyd Jun 14, 2023
ec81f0a
Stub nFPM backend targets: nfpm_*_package
cognifloyd Apr 27, 2023
a899c11
Add nFPM common fields: arch, platform
cognifloyd Apr 27, 2023
2ee0cd8
Add nFPM common fields: version
cognifloyd Apr 27, 2023
bf8ed64
Add nFPM version fields
cognifloyd Apr 27, 2023
2d2320b
Add nFPM homepage and license fields
cognifloyd Apr 27, 2023
8d6bcd9
Make mypy happy with help_text and enum usage
cognifloyd Apr 27, 2023
1a4eb3f
Add stub files to hold the packager-specific nFPM metadata fields
cognifloyd Apr 27, 2023
01e7935
Add nFPM 'maintainer'/'packager' fields
cognifloyd Apr 27, 2023
d48c62a
Add nFPM 'pkgbase' field for Archlinux packages
cognifloyd Apr 28, 2023
5f83871
Add misc nFPM fields for rpm packages
cognifloyd Apr 28, 2023
100cb63
Add nFPM fields for deb 'section' and 'priority'
cognifloyd Apr 28, 2023
060c115
Add nFPM field for deb 'triggers'
cognifloyd Apr 28, 2023
e9580bf
Add nFPM subsystem
cognifloyd Apr 15, 2023
202694a
add nfpm_alias to nfpm backend fields w/ _NfpmField Protocol for use
cognifloyd Apr 29, 2023
0a29012
Separate tuples of nfpm target fields from target for reuse
cognifloyd Apr 29, 2023
fb277e3
Add nfpm package_name field
cognifloyd Apr 29, 2023
00ca211
Add nfpm package field sets
cognifloyd Apr 29, 2023
f2d4256
Initial nfpm.yaml config generation
cognifloyd Apr 29, 2023
54cc8ed
add rule to generate nfpm.yaml
cognifloyd Apr 29, 2023
a78d99c
Refactor: move nfpm fields files into subpackage
cognifloyd Apr 29, 2023
8f4c2ba
Drop pointless re-lookup of value
cognifloyd Apr 29, 2023
c151c5b
stub nFPM package relationship fields (replaces, provides, depends, ...)
cognifloyd Apr 29, 2023
39b0ea8
include description field in nFPM field set
cognifloyd Apr 29, 2023
b8a18ae
Add documentation for nfpm deb package relationship fields
cognifloyd Apr 29, 2023
9625959
Add documentation for nfpm rpm package relationship fields
cognifloyd May 1, 2023
4a0def1
Add documentation for nfpm apk package relationship fields
cognifloyd May 2, 2023
f74a963
Misc help string improvements for nfpm backend
cognifloyd May 5, 2023
0509d47
Add documentation for nfpm archlinux package relationship fields
cognifloyd May 5, 2023
470d0e6
Drop whitespace at end of lines
cognifloyd May 5, 2023
4403067
Add nFPM compression fields for rpm and deb
cognifloyd May 5, 2023
b9c7b68
misc cleanups
cognifloyd May 5, 2023
152464a
make mypy happy
cognifloyd May 5, 2023
d4e73ce
Move nfpm fields applicable to all targets to nfpm.fields.all
cognifloyd May 5, 2023
fcddf2b
Rename nfpm.field_set -> nfpm.field_sets
cognifloyd May 5, 2023
d5c1efd
Drop _NfpmField protocol (make config gen more robust)
cognifloyd May 6, 2023
fa9ae70
Add NfpmDependencies field
cognifloyd May 8, 2023
4d7a4b7
Add NfpmRpmGhostContents field
cognifloyd May 9, 2023
419fa83
Model nfpm_content_{file,symlink,dir}{,s} targets
cognifloyd May 12, 2023
14edeba
always disable_globbing in nFPM contents
cognifloyd May 13, 2023
889afdc
fix quote typos
cognifloyd May 13, 2023
a58ccbe
Document nFPM src+dst fields
cognifloyd May 17, 2023
266940c
Add 'source' field for 'nfpm_content_file' target
cognifloyd May 17, 2023
a4e21e0
typo
cognifloyd May 17, 2023
87044db
document the nfpm file_info fields
cognifloyd May 17, 2023
1a675fc
Document nFPM content_type field
cognifloyd May 21, 2023
efee429
Allow nfpm file_mode to be specified as a string
cognifloyd May 18, 2023
c6c3ee0
clean up some docstrings
cognifloyd May 18, 2023
a6a2e19
clean up some nfpm content_type field docstring
cognifloyd May 24, 2023
126c710
Add basic docs for remaining nfpm content fields
cognifloyd May 24, 2023
631c376
Add basic docs for nfpm content targets
cognifloyd May 24, 2023
47e7deb
mypy cleanups
cognifloyd May 24, 2023
77be12a
Begin rules to gather nfpm contents
cognifloyd May 25, 2023
f46a371
Clean up some help_text/softwrap strings
cognifloyd May 25, 2023
b05648f
Simplify nFPM target field lists
cognifloyd May 26, 2023
c543c3b
Mark nFPM dst fields as required
cognifloyd May 26, 2023
a041e88
Use more succict TypedDict def
cognifloyd May 26, 2023
2d2417a
Merge branch 'cognifloyd/package-deps-traversal' into 'cognifloyd/nfpm'
cognifloyd Jun 14, 2023
b9e1a14
Get transitive targets to generate nfpm config
cognifloyd May 26, 2023
8c78955
populate nfpm.yaml contents array
cognifloyd May 26, 2023
849f5ab
Handle OctalInt representation in nfpm.yaml
cognifloyd May 26, 2023
f6aa76e
Move nfpm content yaml types
cognifloyd May 26, 2023
da7d12d
use NfpmContent type in rpm field
cognifloyd May 26, 2023
0759760
Cleanup TODO
cognifloyd May 26, 2023
dc41d85
clarify assumption comment
cognifloyd May 26, 2023
2062359
Make the list of field set types reusable
cognifloyd May 28, 2023
0527a70
Rename RequestNfpmPackageConfig -> NfpmPackageConfigRequest
cognifloyd May 28, 2023
9dd2bf4
add default_file_extension to NfpmPackageFieldSet
cognifloyd May 28, 2023
d5d76b0
Move nfpm.generate_config_rules -> nfpm.util_rules.generate_config
cognifloyd Jun 14, 2023
03e4206
Add logic to sort nfpm package deps by type
cognifloyd Jun 17, 2023
d110941
Begin building nfpm sandbox creation logic
cognifloyd Jun 17, 2023
daf7b14
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Oct 31, 2023
190c286
fmt & tailor
cognifloyd Nov 1, 2023
3c066f1
Be more consistent in msg formatting
cognifloyd Nov 1, 2023
4a94840
Add validation for NfpmContentFile target fields
cognifloyd Nov 1, 2023
aae8533
Update nFPM to v2.34.0
cognifloyd Nov 1, 2023
a56a7d3
collect/relocate nfpm_content_file sources in nfpm sandbox
cognifloyd Nov 2, 2023
868ead0
Handle nfpm_content_files generator including overrides
cognifloyd Nov 3, 2023
f5f7af1
Finish nFPM sandbox generation
cognifloyd Nov 3, 2023
124d80f
Move transitive_deps calculation into sandbox rule
cognifloyd Nov 3, 2023
20affbf
Refactor some fields for better reuse
cognifloyd Nov 3, 2023
fe17876
Handle nfpm_content_symlinks generator including overrides
cognifloyd Nov 3, 2023
1021c6c
Handle nfpm_content_dirs generator including overrides
cognifloyd Nov 3, 2023
0a398f6
Finish nfpm_content_file handling in config generation rule
cognifloyd Nov 3, 2023
6b7a179
Misc cleanup
cognifloyd Nov 4, 2023
8d6f50e
Extract COMMON_NFPM_PACKAGE_FIELDS
cognifloyd Nov 6, 2023
f312f7b
Add NfpmOutputPathField
cognifloyd Nov 6, 2023
b229a72
Add packager var to nFPM field_sets
cognifloyd Nov 6, 2023
78e506e
Drop NfpmPackageFieldSet.default_file_extension
cognifloyd Nov 6, 2023
d7c83a3
add package_nfpm_package rule
cognifloyd Nov 6, 2023
6c8d5f9
Improve documentation for nfpm arch and platform fields
cognifloyd Nov 6, 2023
c6070da
Add support for deb predepends field
cognifloyd Nov 6, 2023
5a2eebc
Add support for rpm prefixes field
cognifloyd Nov 6, 2023
bee5421
Add max value for NfpmContentFileModeField
cognifloyd Nov 6, 2023
96ee6f7
Add link to upstream nFPM issue about SOURCE_DATE_EPOCH
cognifloyd Nov 6, 2023
30174d0
fix: isort
cognifloyd Nov 7, 2023
80c3a49
Improve docs for nFPM maintainer/packager fields
cognifloyd Nov 7, 2023
8a2deb8
Partially implement nFPM sandbox validation
cognifloyd Nov 7, 2023
5f624e2
Finish nfpm sandbox validation
cognifloyd Nov 8, 2023
81fc0d9
whitespace fix
cognifloyd Nov 8, 2023
cd98f6d
Add scripts field to nfpm package targets
cognifloyd Nov 8, 2023
2eddd8f
Document scripts fields of nfpm package targets
cognifloyd Nov 8, 2023
98b968b
Improve docs for scripts fields of nfpm package targets
cognifloyd Nov 8, 2023
8700dbd
type hint field values where None is not valid
cognifloyd Nov 9, 2023
f04ae14
type fixes for errors caught by mypy
cognifloyd Nov 9, 2023
0b820da
Fix copy pasta in nFPM target_types_rules
cognifloyd Nov 9, 2023
9a16431
Clarify order of Getting nFPM rules
cognifloyd Nov 9, 2023
b008080
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Nov 9, 2023
376cbcd
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Nov 9, 2023
f0d9929
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Jun 23, 2024
71bb26a
register nfpm backend
cognifloyd Jun 23, 2024
95405b2
nFPM: improve nFPM field docs
cognifloyd Jun 23, 2024
076ef71
add test_nfpm_content_file_validate
cognifloyd Jun 27, 2024
9ff9f7d
add test_generate_nfpm_config
cognifloyd Jun 29, 2024
56cdd6c
flake8
cognifloyd Jun 29, 2024
1b0fe6e
BUILD
cognifloyd Jun 30, 2024
54f38c7
fix/fmt
cognifloyd Jun 30, 2024
b4147e7
flake8
cognifloyd Jun 30, 2024
aa63155
isort
cognifloyd Jun 30, 2024
8b8122e
fix issues identified in nfpm field_sets_tests
cognifloyd Jun 30, 2024
de873cc
fix nfpm target_types_test
cognifloyd Jun 30, 2024
07610b3
add more nfpm target_types_test cases
cognifloyd Jun 30, 2024
af366fe
mypy
cognifloyd Jun 30, 2024
57a8649
refactor to make logic more testable
cognifloyd Jul 1, 2024
a480e71
nfpm: test sandbox dep categorization
cognifloyd Jul 1, 2024
d1f7428
flake8
cognifloyd Jul 1, 2024
f7769c6
run nfpm/util_rules tests
cognifloyd Jul 1, 2024
63c192e
fix imports
cognifloyd Jul 1, 2024
e09df99
fix nfpm target registration
cognifloyd Jul 1, 2024
b9a9004
try to fix rule graph
cognifloyd Jul 2, 2024
279d63b
nfpm: move target_types list for reuse in tests
cognifloyd Jul 2, 2024
d65451a
separate package rule per field set type
cognifloyd Jul 2, 2024
dca83e6
nfpm: stub integration test
cognifloyd Jul 2, 2024
01cc68f
nfpm: register subsystem rules
cognifloyd Jul 2, 2024
b4bfedc
flake8
cognifloyd Jul 2, 2024
ad661c5
nfpm: register subsystem rules for integration test
cognifloyd Jul 2, 2024
30e3e97
nfpm: register process rules
cognifloyd Jul 2, 2024
5c30091
nfpm: fix rule registration
cognifloyd Jul 2, 2024
21ad11b
nfpm: normalize Fields compute_value(raw_value) type hints
cognifloyd Jul 3, 2024
4ca41a8
fmt
cognifloyd Jul 2, 2024
2d34fd0
nfpm: add support for SOURCE_DATE_EPOCH and nfpm.yaml:mtime
cognifloyd Jul 3, 2024
5c16ff5
nfpm: add suport for rpm verify scripts
cognifloyd Jul 3, 2024
6bbfd66
nfpm: add TODOs about new IPK-type packaging format
cognifloyd Jul 3, 2024
f0daa81
nfpm: update to nfpm 2.37.1 (09 May 2024)
cognifloyd Jul 3, 2024
2bee818
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Jul 27, 2024
53eeda2
pants migrate-call-by-name src/python/pants/backend/{experimental/,}n…
cognifloyd Jul 27, 2024
d63bb97
pants fix fmt src/python/pants/backend/nfpm/::
cognifloyd Jul 27, 2024
3f9b638
fix mypy identified issues with the migration
cognifloyd Jul 27, 2024
07ebd1e
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Jul 27, 2024
f8afb71
nfpm: Add OctalInt representer to SafeDumper
cognifloyd Aug 8, 2024
15910a8
nfpm: Add field_set.extension for use in tests
cognifloyd Aug 8, 2024
3989b13
nfpm: Use full path for src/source
cognifloyd Aug 8, 2024
f8b1dd0
nfpm: Fix file mode parsing with "-" char
cognifloyd Aug 8, 2024
4d1e0a1
nfpm: Fix default mtime to include Z (required by nFPM)
cognifloyd Aug 8, 2024
13ca4fa
nfpm: Fix _SrcDstSequenceField validation
cognifloyd Aug 8, 2024
61c3058
nfpm: Expand integration tests
cognifloyd Aug 8, 2024
b4d8fa2
nfpm: Add normalized_value property to scripts field
cognifloyd Aug 8, 2024
29f95d9
nfpm: Add dependency inference for scripts field
cognifloyd Aug 8, 2024
781c2e0
nfpm: fmt
cognifloyd Aug 9, 2024
dda934b
nfpm: add missing 'from future import __annotations__'
cognifloyd Aug 9, 2024
91e1bf7
nfpm: add package scripts dep inference test
cognifloyd Aug 9, 2024
a148786
nfpm: fmt
cognifloyd Aug 9, 2024
c1fce24
nfpm: add filemode calculation tests
cognifloyd Aug 9, 2024
1c59deb
nfpm: add test for populate_nfpm_content_sandbox rule
cognifloyd Aug 9, 2024
2c36f24
nfpm: reorder test cases in test_populate_nfpm_content_sandbox
cognifloyd Aug 9, 2024
eb3991f
nfpm: add test codegen cases to test_populate_nfpm_content_sandbox
cognifloyd Aug 9, 2024
f962bac
nfpm: add package build cases to test_populate_nfpm_content_sandbox
cognifloyd Aug 9, 2024
ea9bbfd
nfpm: minor refactor
cognifloyd Aug 9, 2024
bd9d948
nfpm: use utf-8 explicitly
cognifloyd Aug 9, 2024
1f5c137
nfpm: fmt
cognifloyd Aug 9, 2024
63b89b2
nfpm: add test for generate_nfpm_yaml rule
cognifloyd Aug 9, 2024
937e809
nfpm: add release notes and misc docstring updates
cognifloyd Aug 9, 2024
03225f2
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Aug 9, 2024
4c1fbe4
nfpm: update to nFPM v2.38.0
cognifloyd Aug 9, 2024
bca1389
nfpm: migrate-call-by-name on newer code
cognifloyd Aug 10, 2024
99f900b
nfpm: drop old TODOs
cognifloyd Aug 10, 2024
32b6ab1
nfpm: add mtime field to nfpm_*_package targets
cognifloyd Aug 10, 2024
5d0ce9c
nfpm: add [nfpm].default_mtime option
cognifloyd Aug 12, 2024
99eee41
nfpm: drop apk, archlinux, rpm; keep only deb
cognifloyd Aug 13, 2024
d41a201
nfpm: drop deb packager to focus on core bits
cognifloyd Aug 13, 2024
3d2a19c
nfpm: simplify OctalInt registration in yaml.SafeDumper
cognifloyd Aug 13, 2024
425480c
nfpm: use type[...] instead of Type[...] in type hints
cognifloyd Aug 13, 2024
242a47b
nfpm: use UPPER_SNAKE for constants
cognifloyd Aug 13, 2024
74e90b2
nfpm: use frozenset for _FILEMODE_CHARS constant
cognifloyd Aug 13, 2024
89215a8
Add StringStringTupleSequenceField
cognifloyd Aug 13, 2024
d97c1c4
Make more generic TupleSequenceField instead of StringStringTupleSequ…
cognifloyd Aug 13, 2024
78c383a
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Aug 13, 2024
1f61628
Add TupleSequenceField
cognifloyd Aug 13, 2024
9a7c390
Add TupleSequenceField test
cognifloyd Aug 13, 2024
726c62a
nfpm: skip tests that can't run w/o nfpm_*_targets
cognifloyd Aug 13, 2024
3a329fa
Merge branch 'cognifloyd/tuple-sequence-field' into cognifloyd/nfpm
cognifloyd Aug 13, 2024
eb958e0
nfpm: drop more deb-references from docstrings
cognifloyd Aug 13, 2024
3e1a88d
nfpm: drop tests that cannot run w/o nfpm_*_package targets
cognifloyd Aug 13, 2024
8ff5209
nfpm: refactor nfpm content dict calculation to use field sets
cognifloyd Aug 13, 2024
cbdb47c
nfpm: finish logic around nfpm content field sets
cognifloyd Aug 13, 2024
a6c4655
nfpm: fix usage of FieldSetsPerTarget
cognifloyd Aug 13, 2024
dd4b083
Merge branch 'main' into cognifloyd/nfpm
cognifloyd Aug 13, 2024
22da064
nfpm: style uppercase constants
cognifloyd Aug 13, 2024
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
1 change: 1 addition & 0 deletions docs/docs/using-pants/key-concepts/backends.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ The list of all backends (both stable and experimental) is also available via `p
| `pants.backend.experimental.kotlin` | Enables core Kotlin support | [Kotlin](../../jvm/kotlin.mdx) |
| `pants.backend.experimental.kotlin.debug_goals` | Enables additional goals for introspecting Kotlin targets | [Kotlin](../../jvm/kotlin.mdx) |
| `pants.backend.experimental.kotlin.lint.ktlint` | Enables ktlint, an anti-bikeshedding linter with built-in formatter: [https://pinterest.github.io/ktlint/](https://pinterest.github.io/ktlint/) | [Kotlin](../../jvm/kotlin.mdx) |
| `pants.backend.experimental.nfpm` | Enables support for building `apk`, `archlinux`, `deb`, and `rpm` packages via [`nFPM`](https://nfpm.goreleaser.com/) | [`nfpm`](../../../reference/subsystems/nfpm.mdx) |
| `pants.backend.experimental.openapi` | Enables core OpenAPI support: [https://swagger.io/specification/](https://swagger.io/specification/) | [`openapi`](../../../reference/subsystems/openapi.mdx) |
| `pants.backend.experimental.openapi.codegen.java` | Enables generating Java from OpenAPI | |
| `pants.backend.experimental.openapi.lint.openapi_format` | Enables openapi-format: [https://github.com/thim81/openapi-format](https://github.com/thim81/openapi-format) | |
Expand Down
35 changes: 35 additions & 0 deletions docs/notes/2.23.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,41 @@ The `output_path` field present on targets which can be packaged by `pants packa

### Backends

#### NEW: nFPM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you plan on having an example-nfpm repository users could look at? No need to develop it now or even reference it if you have one, but might be good to keep in mind as a follow-on.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hadn't thought about that. I think a section in the documentation might be useful as well, but I don't know when I can tackle something like that.


A new experimental `pants.backend.experimental.nfpm` backend was added to support building system packages with [`nFPM`](https://nfpm.goreleaser.com/). nFPM describes itself as:

> **nFPM is Not FPM** - a zero dependencies, simple `deb`, `rpm`, `apk`, `ipk`, and arch linux packager written in Go.

This backend does not have any package types yet.

To use the `nFPM` backend, enable `pants.backend.experimental.nfpm` in your `pants.toml`, and create an `nfpm_*_package` target that depends on `nfpm_content_*` targets. This backend constructs the `nfpm.yaml` file that `nFPM` relies on to build packages. All `nfpm.yaml` fields (that make sense within pants) can be configured via the `nfpm_*_package` and `nfpm_content_*` targets.

This backend has extensive help documentation. Please use `pants help` to learn about the fields on these targets.

Learn general info about nFPM and available targets:
```
$ pants help backends | grep -A6 pants.backend.experimental.nfpm
$ pants help nfpm
$ pants help tools | grep -A3 nfpm
$ pants help targets | grep -A1 nfpm_
```

Learn about the nFPM package targets and their fields:
```
# Not available yet.
```

Learn about the nFPM package content targets and their fields:
```
$ pants help nfpm_content_files
$ pants help nfpm_content_file
$ pants help nfpm_content_dirs
$ pants help nfpm_content_dir
$ pants help nfpm_content_symlinks
$ pants help nfpm_content_symlink
```

#### BUILD

Support for parametrizing grouped parametrizations. (e.g. `**parametrize(resolve=parametrize("a", "b"), ...)`). This works for `___defaults__` as well, as long as it is specified per target type rather than using `all`.
Expand Down
4 changes: 4 additions & 0 deletions src/python/pants/backend/experimental/nfpm/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

python_sources()
Empty file.
28 changes: 28 additions & 0 deletions src/python/pants/backend/experimental/nfpm/register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

"""Create apk, archlinux, deb, and rpm system packages.

See https://nfpm.goreleaser.com/ for details on nFPM, including these descriptions of it:
- nFPM is "effing simple package management"
- "nFPM is Not FPM--a zero dependencies, simple deb, rpm, apk, and arch linux packager written in Go."
""" # TODO: include ipk in this docstring once support is added.

from pants.backend.nfpm.dependency_inference import rules as nfpm_dependency_inference_rules
from pants.backend.nfpm.rules import rules as nfpm_rules
from pants.backend.nfpm.subsystem import rules as nfpm_subsystem_rules
from pants.backend.nfpm.target_types import target_types as nfpm_target_types
from pants.backend.nfpm.target_types_rules import rules as nfpm_target_type_rules


def target_types():
return nfpm_target_types()


def rules():
return [
*nfpm_subsystem_rules(),
*nfpm_target_type_rules(),
*nfpm_dependency_inference_rules(),
*nfpm_rules(),
]
6 changes: 6 additions & 0 deletions src/python/pants/backend/nfpm/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

python_sources()

python_tests(name="tests")
Empty file.
41 changes: 41 additions & 0 deletions src/python/pants/backend/nfpm/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import annotations

from typing import TypedDict

import yaml


class OctalInt(int):
# noinspection PyUnusedLocal
@staticmethod
def represent_octal(dumper: yaml.representer.BaseRepresenter, data: int) -> yaml.Node:
# YAML 1.2 octal: 0o7777 (py: f"0o{data:o}" or f"{data:#o}" or oct(data))
# YAML 1.1 octal: 07777 (py: f"0{data:o}")
# Both octal reprs are supported by `gopkg.in/yaml.v3` which parses YAML in nFPM.
# See: https://github.com/go-yaml/yaml/tree/v3.0.1#compatibility
# PyYAML only supports reading YAML 1.1, so we use that.
return yaml.ScalarNode("tag:yaml.org,2002:int", f"0{data:o}")


# This is an unfortunate import-time side effect: PyYAML does registration globally.
yaml.SafeDumper.add_representer(OctalInt, OctalInt.represent_octal)


class NfpmFileInfo(TypedDict, total=False):
# nFPM allows these to be None or missing.
# Each of the fields has a default, so in practice, these won't be None.
owner: str | None
group: str | None
mode: OctalInt | None
mtime: str | None


class NfpmContent(TypedDict, total=False):
src: str
dst: str
type: str
packager: str
file_info: NfpmFileInfo
56 changes: 56 additions & 0 deletions src/python/pants/backend/nfpm/dependency_inference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2024 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import annotations

from dataclasses import dataclass

from pants.backend.nfpm.fields.scripts import NfpmPackageScriptsField
from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior
from pants.base.specs import FileLiteralSpec, RawSpecs
from pants.engine.internals.specs_rules import resolve_addresses_from_raw_specs
from pants.engine.rules import collect_rules, rule
from pants.engine.target import FieldSet, InferDependenciesRequest, InferredDependencies
from pants.engine.unions import UnionRule
from pants.util.logging import LogLevel


@dataclass(frozen=True)
class NfpmPackageScriptsInferenceFieldSet(FieldSet):
required_fields = (NfpmPackageScriptsField,)

scripts: NfpmPackageScriptsField


class InferNfpmPackageScriptsDependencies(InferDependenciesRequest):
infer_from = NfpmPackageScriptsInferenceFieldSet


@rule(
desc=f"Infer dependencies based on nfpm `{NfpmPackageScriptsField.alias}` field.",
level=LogLevel.DEBUG,
)
async def infer_nfpm_package_scripts_dependencies(
request: InferNfpmPackageScriptsDependencies,
) -> InferredDependencies:
scripts: NfpmPackageScriptsField = request.field_set.scripts
scripts_paths = tuple(scripts.normalized_value.values())
if not scripts_paths:
return InferredDependencies(())

resolved_scripts_addresses = await resolve_addresses_from_raw_specs(
RawSpecs(
file_literals=tuple(FileLiteralSpec(script_path) for script_path in scripts_paths),
unmatched_glob_behavior=GlobMatchErrorBehavior.error,
description_of_origin="nfpm package scripts field dependency inference",
)
)

return InferredDependencies(resolved_scripts_addresses)


def rules():
return [
*collect_rules(),
UnionRule(InferDependenciesRequest, InferNfpmPackageScriptsDependencies),
]
Loading
Loading