thousands-france-27863
02/20/2023, 12:09 PMpoetry version type=patch (patch can be “major”, “minor” or “patch).
This in turn will modify the pyproject.toml version number.
I created this rule:
@rule
async def get_project_version_file_view(
target: ProjectVersionTarget,
) -> ProjectVersionFileView:
pex = await Get(
Pex,
PexRequest(
output_filename="poetry.pex",
internal_only=True,
requirements=PexRequirements(["poetry"]),
main=ConsoleScript("poetry"),
),
)
result = await Get(
FallibleProcessResult,
PexProcess(
pex,
argv=["version"],
description="get poetry version",
working_directory=".",
),
)
<http://logger.info|logger.info>(result.stdout.decode())
<http://logger.info|logger.info>(result.stderr.decode())
return ProjectVersionFileView(path="path", version=result.stdout.decode())
Whoever, it does look like it can’t find the pyproject.toml file as I get this error:
Poetry could not find a pyproject.toml file in /private/var/folders/0g/7yz8qfln279gr8gtr874hbvr1wzvx2/T/pants-sandbox-BxA03N or its parents
Is there a way to ensure that pyproject.toml file is there? In this use case I am only looking to get the version from the command, but I would like to update the version passing arguments.
Mentioning this to know if I am doing something not intended and getting down a rabbit hole.
Thanks in advance for your help!happy-kitchen-89482
02/20/2023, 2:28 PM--keep-sandboxes=on_failure, which will print the location of the sandbox of the failed process so you can look inside it.happy-kitchen-89482
02/20/2023, 2:28 PMhappy-kitchen-89482
02/20/2023, 2:29 PMProjectVersionTarget?happy-kitchen-89482
02/20/2023, 2:30 PMPexProcess, so it's running in a mostly empty sandbox (other than the poetry pex)happy-kitchen-89482
02/20/2023, 2:30 PMhappy-kitchen-89482
02/20/2023, 2:30 PMhappy-kitchen-89482
02/20/2023, 2:31 PMhappy-kitchen-89482
02/20/2023, 2:32 PMhappy-kitchen-89482
02/20/2023, 2:32 PMhappy-kitchen-89482
02/20/2023, 2:33 PMpants bump-version path/to/pyproject.toml ?thousands-france-27863
02/20/2023, 2:34 PMclass ProjectVersionTarget(Target):
alias = "versioned_project"
description = "A versioned project target where the pyproject.toml version is updated via the `poetry version ..` command"
core_fields = (*COMMON_TARGET_FIELDS, BumpVersionTypeField)
tags = ["bump", "versioned"]
help = "This target indicates this project will update the pyproject.toml version by using the `poetry version $(type)` command, where the type can be `major`, `minor` or `patch` (default)"
So the BUILD file uses this macro (as I got a few pyproject.toml) :
# flake8: noqa: F821
def poetry_distribution(name, **kwargs):
resources(name="package_data", sources=["pyproject.toml", "README.md"])
versioned_project(
name=f"{name}_version",
tags=["version", "bump"],
)
python_distribution(
name="dist",
dependencies=[":package_data", f"src/python/{name}/src", "//:root"],
repositories=["<https://nexus3.tl.pplaws.com/repository/pypi-ppl/>"],
provides=python_artifact(name=f"{name}"),
generate_setup=False,
)thousands-france-27863
02/20/2023, 2:37 PMthousands-france-27863
02/20/2023, 2:38 PMthousands-france-27863
02/20/2023, 2:47 PM./pants bump-version :: type=patch with the --changed-since=main so only the projects that changed get their version updated.thousands-france-27863
02/20/2023, 2:49 PM./pants bump-version that prints what each pyproject.toml version (with the poetry version command, will do. As that validates the pyproject.toml file is there and the command is reading it for each of the pyproject.toml I gotfast-nail-55400
02/20/2023, 7:03 PMfast-nail-55400
02/20/2023, 7:04 PMresources target generated for the pyproject.toml by the poetry_distribution macro?fast-nail-55400
02/20/2023, 7:06 PMbump-version goal rule, add a targets: Targets parameter to receive the targets to operate on. This will be set regardless of whether the goal was invoked with explicit targets or via --changed-sincefast-nail-55400
02/20/2023, 7:06 PMresource targets: [tgt for tgt in targets if tgt.has_field(ResourceSourceField)]fast-nail-55400
02/20/2023, 7:07 PMResourceSourceField to find the ones with a pyproject.toml as the sourcefast-nail-55400
02/20/2023, 7:07 PMDigest using the HydrateSourcesRequest typefast-nail-55400
02/20/2023, 7:08 PMfast-nail-55400
02/20/2023, 7:10 PMDigest type to represent a filesystem treefast-nail-55400
02/20/2023, 7:27 PMDigest with the modified filesfast-nail-55400
02/20/2023, 7:29 PMWorkspace type and its write_digest method to write the output back out to the repositoryfast-nail-55400
02/20/2023, 7:29 PMgo-generate custom goal and how it invokes go generate and then writes the outputs back to the repositorythousands-france-27863
02/20/2023, 7:35 PMfast-nail-55400
02/20/2023, 7:36 PMgo-generate custom goal is implemented in https://github.com/pantsbuild/pants/blob/2b7c89e8a3fe565fb47921392353cb677aa98400/src/python/pants/backend/go/goals/generate.pythousands-france-27863
02/24/2023, 3:08 PM# flake8: noqa: F821
def poetry_distribution(name, **kwargs):
resources(name="package_data", sources=["pyproject.toml", "README.md"])
versioned_project(
name=f"{name}_version",
tags=["version", "bump"],
source="pyproject.toml"
)
python_distribution(
name="dist",
dependencies=[":package_data", f"src/python/{name}/src", "//:root"],
repositories=["<https://nexus3.tl.pplaws.com/repository/pypi-ppl/>"],
provides=python_artifact(name=f"{name}"),
generate_setup=False,
)
I know you mentioned reusing the resources but will probably do that on a next version.The classes that define the target/goal:
class BumpVersionTypeField(StringField):
help = "Type of version increase. Can be major, minor or patch"
alias = "type"
default = "patch"
valid_choices = ("major", "minor", "patch")
description = "Type of version increase. Can be major, minor or patch"
required = False
class ProjectVersionTarget(Target):
alias = "versioned_project"
description = "A versioned project target where the pyproject.toml version is updated via the `poetry version ..` command"
core_fields = (*COMMON_TARGET_FIELDS, BumpVersionTypeField, SingleSourceField)
tags = ["bump", "versioned"]
help = "This target indicates this project will update the pyproject.toml vesrion by using the `poetry version $(type)` command, where the type can be `major`, `minor` or `patch` (default)"
class ProjectVersionSubsystem(GoalSubsystem):
name = "bump-version"
help = (
"Show representation of the project version from the `poetry version` command."
)
class ProjectVersionGoal(Goal):
subsystem_cls = ProjectVersionSubsystem
The goal_rule is:
@goal_rule
async def goal_show_project_version(
console: Console,
targets: Targets,
workspace: Workspace
) -> ProjectVersionGoal:
projectVersionTargets = [tgt for tgt in targets if tgt.alias == ProjectVersionTarget.alias]
results = await MultiGet(
Get(Digest, ProjectVersionTarget, tgt)
for tgt in projectVersionTargets
)
output_digest = await Get(Digest, MergeDigests([r for r in results]))
workspace.write_digest(output_digest)
return ProjectVersionGoal(exit_code=0)
and my rule looks like this:
@rule
async def get_project_version_file_view(
target: ProjectVersionTarget,
) -> Digest:
sources = await Get(HydratedSources, HydrateSourcesRequest(target[SourcesField]))
pex = await Get(
Pex,
PexRequest(
output_filename="poetry.pex",
internal_only=True,
interpreter_constraints=InterpreterConstraints(["==3.9.*"]),
requirements=PexRequirements(["poetry"]),
main=ConsoleScript("poetry"),
),
)
result = await Get(
ProcessResult,
PexProcess(
pex,
argv=["version", "patch"],
input_digest=sources.snapshot.digest,
description="get poetry version",
working_directory=target.residence_dir,
level=LogLevel.DEBUG,
),
)
<http://logger.info|logger.info>(result.stdout.decode())
<http://logger.info|logger.info>(result.stderr.decode())
return result.output_digest
The code seems to do what it says on the tin, whoever is not saving back the files on my file system.
Further info on structure is in here:
https://github.com/pantsbuild/pants/issues/18179
Help please!! 😄
Also, the most interesting part I learned is the been able to debug with this command
PANTS_DEBUG=1 ./pants bump-version :: --keep-sandboxes=always --no-pantsd
I will be happy to put a PR to update the documentation, whoever do you prefer it I add a new page in https://www.pantsbuild.org/docs/common-plugin-tasks or this one https://www.pantsbuild.org/docs/plugins-overview ? I think the former might make more sense.fast-nail-55400
02/24/2023, 4:56 PMoutput_files or output_directories on the Process (in this case the PexProcess wrapper) otherwise Pants will not capture outputsfast-nail-55400
02/24/2023, 4:56 PMresult.output_digest will be the empty digestfast-nail-55400
02/24/2023, 4:58 PMDigest to a Snapshot : snapshot = await Get(Snapshot, digest, result.output_digest)fast-nail-55400
02/24/2023, 4:58 PMsnapshot.filesthousands-france-27863
02/25/2023, 9:16 PMfast-nail-55400
02/25/2023, 9:53 PMworkspace.write_digest because the Process was not configured to capture any output from running the pex.thousands-france-27863
02/27/2023, 1:12 PMthousands-france-27863
02/28/2023, 11:48 AM./pants bump-version --changed-since=main --changed-dependees=transitive
I might be wrong, but should I have extended the pythonSource target instead of creating a new one? Can I “link” them somehow? Thanks in advancehappy-kitchen-89482
02/28/2023, 3:23 PM