Git Product home page Git Product logo

poetry-dynamic-versioning's Introduction

Dynamic versioning plugin for Poetry

This is a Python 3.7+ plugin for Poetry 1.2.0+ and Poetry Core 1.0.0+ to enable dynamic versioning based on tags in your version control system, powered by Dunamai. Many different version control systems are supported, including Git and Mercurial; please refer to the Dunamai page for the full list (and minimum supported version where applicable).

poetry-dynamic-versioning provides a build backend that patches Poetry Core to enable the versioning system in PEP 517 build frontends. When installed with the plugin feature (i.e., poetry-dynamic-versioning[plugin]), it also integrates with the Poetry CLI to trigger the versioning in commands like poetry build.

For Poetry 1.1.x, you can use an older version of poetry-dynamic-versioning (0.17.1 or earlier) that relied on a *.pth import hack, but this is no longer supported, so you should migrate to the standardized plugin and Poetry 1.2.0+.

Installation

If you've previously installed the deprecated poetry-dynamic-versioning-plugin package, be sure to uninstall it before proceeding.

  • Install the plugin using one of the options below:

    • In most cases: poetry self add "poetry-dynamic-versioning[plugin]"
    • If you installed Poetry with Pipx: pipx inject poetry "poetry-dynamic-versioning[plugin]"

    See the Poetry plugin documentation for more information about these options.

  • Run in your project: poetry dynamic-versioning enable

    Or you can update your pyproject.toml manually:

    [tool.poetry-dynamic-versioning]
    enable = true

    Include the plugin in the build-system section of pyproject.toml for interoperability with PEP 517 build frontends:

    [build-system]
    requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.0.0,<2.0.0"]
    build-backend = "poetry_dynamic_versioning.backend"

    This is a thin wrapper around poetry.core.masonry.api.

Poetry still requires the tool.poetry.version field to be present in pyproject.toml, but you are encouraged to use version = "0.0.0" as a standard placeholder.

With the minimal configuration above, the plugin will automatically take effect when you run commands such as poetry build. It will update the version in pyproject.toml, then revert the change when the plugin deactivates.

The default configuration will also update any pre-existing __version__ = "0.0.0" and __version_tuple__ = (0, 0, 0) placeholders in some files. You can configure additional substitution patterns/files as needed (see below).

Configuration

In your pyproject.toml file, you may configure the following options:

  • [tool.poetry-dynamic-versioning]: General options.

    • enable (boolean, default: false): Since the plugin has to be installed globally, this setting is an opt-in per project.

    • vcs (string, default: any): This is the version control system to check for a version. One of: any, git, mercurial, darcs, bazaar, subversion, fossil, pijul.

    • metadata (boolean, default: unset): If true, include the commit hash in the version, and also include a dirty flag if dirty is true. If unset, metadata will only be included if you are on a commit without a version tag. This is ignored when format or format-jinja is used.

    • tagged-metadata (boolean, default: false): If true, include any tagged metadata discovered as the first part of the metadata segment. Has no effect when metadata is set to false. This is ignored when format or format-jinja is used.

    • dirty (boolean, default: false): If true, include a dirty flag in the metadata, indicating whether there are any uncommitted changes. Has no effect when metadata is set to false. This is ignored when format or format-jinja is used.

    • pattern (string): This is a regular expression which will be used to find a tag representing a version. When this is unset, Dunamai's default pattern is used.

      There must be a capture group named base with the main part of the version. Optionally, it may contain another two groups named stage and revision for prereleases, and it may contain a group named tagged_metadata to be used with the tagged-metadata option. There may also be a group named epoch for the PEP 440 concept.

      If the base group is not included, then this will be interpreted as a named preset from the Dunamai Pattern class. This includes: default, default-unprefixed (makes the v prefix optional).

      You can check the default for your installed version of Dunamai by running this command:

      poetry run python -c "import dunamai; print(dunamai.Pattern.Default.regex())"
      

      Remember that backslashes must be escaped (\\) in the TOML file.

    • pattern-prefix (string): This will be inserted after the pattern's start anchor (^). For example, to match tags like some-package-v1.2.3, you can keep the default pattern and set the prefix to some-package-.

    • format (string, default: unset): This defines a custom output format for the version. Available substitutions:

      • {base}
      • {stage}
      • {revision}
      • {distance}
      • {commit}
      • {dirty}
      • {tagged_metadata}
      • {branch}
      • {branch_escaped} which omits any non-letter/number characters
      • {timestamp} of the current commit, which expands to YYYYmmddHHMMSS as UTC

      Example: v{base}+{distance}.{commit}

    • format-jinja (string, default: unset): This defines a custom output format for the version, using a Jinja template. When this is set, format is ignored.

      Available variables:

      • base (string)
      • stage (string or None)
      • revision (integer or None)
      • distance (integer)
      • commit (string)
      • dirty (boolean)
      • tagged_metadata (string or None)
      • version (dunumai.Version)
      • env (dictionary of environment variables)
      • branch (string or None)
      • branch_escaped (string or None)
      • timestamp (string or None)

      Available functions:

      Simple example:

      format-jinja = "{% if distance == 0 %}{{ base }}{% else %}{{ base }}+{{ distance }}.{{ commit }}{% endif %}"

      Complex example:

      format-jinja = """
          {%- if distance == 0 -%}
              {{ serialize_pep440(base, stage, revision) }}
          {%- elif revision is not none -%}
              {{ serialize_pep440(base, stage, revision + 1, dev=distance, metadata=[commit]) }}
          {%- else -%}
              {{ serialize_pep440(bump_version(base), stage, revision, dev=distance, metadata=[commit]) }}
          {%- endif -%}
      """
    • format-jinja-imports (array of tables, default: empty): This defines additional things to import and make available to the format-jinja template. Each table must contain a module key and may also contain an item key. Consider this example:

      format-jinja-imports = [
          { module = "foo" },
          { module = "bar", item = "baz" },
      ]

      This is roughly equivalent to:

      import foo
      from bar import baz

      foo and baz would then become available in the Jinja formatting.

    • style (string, default: unset): One of: pep440, semver, pvp. These are preconfigured output formats. If you set both a style and a format, then the format will be validated against the style's rules. If style is unset, the default output format will follow PEP 440, but a custom format will only be validated if style is set explicitly.

    • latest-tag (boolean, default: false): If true, then only check the latest tag for a version, rather than looking through all the tags until a suitable one is found to match the pattern.

    • bump (boolean, default: false): If true, then increment the last part of the version base by 1, unless the stage is set, in which case increment the revision by 1 or set it to a default of 2 if there was no revision. Does nothing when on a commit with a version tag.

      Example, if there have been 3 commits since the v1.3.1 tag:

      • PEP 440 with bump = false: 1.3.1.post3.dev0+28c1684
      • PEP 440 with bump = true: 1.3.2.dev3+28c1684
    • tag-dir (string, default: tags): This is the location of tags relative to the root. This is only used for Subversion.

    • tag-branch (string, default: unset): Branch on which to find tags, if different than the current branch. This is only used for Git currently.

    • full-commit (boolean, default: false): If true, get the full commit hash instead of the short form. This is only used for Git and Mercurial.

    • strict (boolean, default: false): If true, then fail instead of falling back to 0.0.0 when there are no tags.

    • fix-shallow-repository (boolean, default: false): If true, then automatically try to fix shallow repositories. Currently, this only supports Git and will run git fetch --unshallow.

    • ignore-untracked (boolean, default: false): If true, ignore untracked files when determining whether the repository is dirty.

  • [tool.poetry-dynamic-versioning.substitution]: Insert the dynamic version into additional files other than just pyproject.toml. These changes will be reverted when the plugin deactivates.

    • files (array of strings): Globs for any files that need substitutions. Default: ["*.py", "*/__init__.py", "*/__version__.py", "*/_version.py"]. To disable substitution, set this to an empty list.

    • patterns (array of strings/tables): Regular expressions for the text to replace. Each regular expression must have two capture groups, which are any text to preserve before and after the replaced text.

      String items are interpreted as a regular expression directly. Table items support these keys:

      • value (string): This is the regular expression.
      • mode (string, optional): This controls how the version should be inserted. Options:
        • str (default): Serialize version as-is. The capture groups should already include the surrounding quotation marks.
        • tuple: Serialize 0.1.2.dev0+a.b as 0, 1, 2, "dev0", "a.b". The capture groups should already include the surrounding parentheses.

      Default:

      patterns = [
          "(^__version__\\s*(?::.*?)?=\\s*['\"])[^'\"]*(['\"])",
          { value = "(^__version_tuple__\\s*(?::.*?)?=\\s*\\()[^)]*(\\))", mode = "tuple" },
      ]

      Remember that the backslashes must be escaped (\\) in the TOML file.

    • folders (array of tables, default: empty): List of additional folders to check for substitutions.

      Each table supports these options:

      • path (string, required): Path to the folder.
      • files (array of strings, optional): Override substitution.files for this folder.
      • patterns (array of strings, optional): Override substitution.patterns for this folder.

      If you use an src layout, you may want to keep the default files/patterns and just specify the following:

      folders = [
        { path = "src" }
      ]

      This will check the default file globs (e.g., ./*.py) as well as the same file globs inside of src (e.g., ./src/*.py).

  • [tool.poetry-dynamic-versioning.files] (table, default: empty): This section lets you tweak the behavior for individual files. Each table key is a path to a specific file (no globs) relative to the project root. Each nested table supports these fields:

    If you use these options to generate a file that's ignored by your VCS, but you also want the generated file to be included in the output of poetry build, then you'll need to name the file explicitly in your tool.poetry.include config.

    • persistent-substitution (boolean, optional): If true, then do not revert any substitutions applied to this file. This is primarily useful for editable installs, if you need the version to remain in a file ignored by your VCS.

    • initial-content (string, optional): Set the file content before the substitution phase. The file will be created or overwritten as necessary. Common leading whitespace will be stripped from each line.

    • initial-content-jinja (string, optional): Same as initial-content, but using Jinja formatting. If both options are set, this one takes priority. You can use the same imports from format-jinja-imports and the same variables from format-jinja, with this additional variable:

      • formatted_version (string) - version formatted by either the format or format-jinja option

    Example:

    [tool.poetry-dynamic-versioning.files."package/_version.py"]
    persistent-substitution = true
    initial-content = """
      # These version placeholders will be replaced later during substitution.
      __version__ = "0.0.0"
      __version_tuple__ = (0, 0, 0)
    """
  • [tool.poetry-dynamic-versioning.from-file]: This section lets you read the version from a file instead of the VCS.

    • source (string): If set, read the version from this file. It must be a path relative to the location of pyproject.toml. By default, the plugin will read the entire content of the file, without leading and trailing whitespace.
    • pattern (string): If set, use this regular expression to extract the version from the file. The first capture group must contain the version.

Simple example:

[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
style = "semver"

Environment variables

In addition to the project-specific configuration above, you can apply some global overrides via environment variables.

  • POETRY_DYNAMIC_VERSIONING_BYPASS: Use this to bypass the VCS mechanisms and use a static version instead. The value of the environment variable will be used as the version for the active project and any path/SSH dependencies that also use the plugin. This is mainly for distro package maintainers who need to patch existing releases, without needing access to the original repository.
  • POETRY_DYNAMIC_VERSIONING_OVERRIDE: Use a static version for specific packages only, but leave dynamic versioning enabled otherwise. For example, pkg1 = 0.1.0, pkg2 = 0.2.0 (spaces are optional) would set pkg1 to 0.1.0 and pkg2 to 0.2.0. This only affects packages for which poetry-dynamic-versioning is enabled. When both variables are set, OVERRIDE takes precedence over BYPASS.
  • POETRY_DYNAMIC_VERSIONING_COMMANDS: You can set a comma-separated list of Poetry commands during which to activate the versioning. For example, build,publish will limit the dynamic versioning to those two commands. Similarly, setting POETRY_DYNAMIC_VERSIONING_COMMANDS="" will disable the dynamic versioning altogether, which is useful in isolated environments like Docker where versions may not be computable and not needed anymore.
  • POETRY_DYNAMIC_VERSIONING_COMMANDS_NO_IO: Comma-separated list of Poetry commands during which the plugin should not directly modify files. The plugin will still set the dynamic version in memory so that Poetry itself can write it as needed. Default: version.
  • POETRY_DYNAMIC_VERSIONING_DEBUG: If this is set to 1, then some debug logs will be printed to stderr. Right now, this logs some cases where substitution doesn't find anything to change.

Command line mode

The plugin also has a command line mode for execution on demand. This mode applies the dynamic version to all relevant files and leaves the changes in-place, allowing you to inspect the result. Your configuration will be detected from pyproject.toml as normal, but the enable option is not necessary.

To activate this mode, either use poetry dynamic-versioning (provided by the plugin feature) or poetry-dynamic-versioning (standalone script with default features).

VCS archives

Sometimes, you may only have access to an archive of a repository (e.g., a zip file) without the full history. The plugin can still detect a version in some of these cases. Refer to the Dunamai documentation for more info.

Caveats

All of Dunamai's caveats apply. In addition to those:

  • The dynamic version is not available during poetry run or poetry shell because of a Poetry design choice that prevents the plugin from cleaning up after itself.

  • Regarding PEP 517 support:

    pip wheel . and pip install . will work with new enough Pip versions that default to in-tree builds or support the --use-feature=in-tree-build option. Older versions of Pip will not work because they create an isolated copy of the source code that does not contain the version control history.

    If you want to build wheels of your dependencies, you can do the following, although local path-based dependencies may not work:

    poetry export -f requirements.txt -o requirements.txt --without-hashes
    pip wheel -r requirements.txt
    

poetry-dynamic-versioning's People

Contributors

cburgess avatar cmarqu avatar edgarrmondragon avatar fabaff avatar grawlinson avatar gsemet avatar heimalne avatar mariusvniekerk avatar mtkennerly avatar thenx avatar visch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

poetry-dynamic-versioning's Issues

Handle 'no previous tag' case

Hi,

When there are no previous tag yet on a project, the jinja rendering gets a distance=0 so it always displays "0.0.0".

My recommendation is to get a distance = number of total commit since initial commit so that the versions will be 0.0.1.dev1, 0.0.1.dev2, 0.0.1.dev3...

Controlling dev/post specifiers

Nice plugin... works well.

Is it possible to control when the post specifier and when the dev specifier are incremented? When I'm ahead by N commits from the last tag, I now get x.x.x.postN.dev0. I haven't found a way to get for instance x.x.x.postN, or x.x.x.post1.devN.

Working with docker images

First of all, thank you for this great library!

I'm using poetry to build and install a library in a docker image. As poetry-dynamic-versioning gets some metadata from .git, I have to copy this folder before running poetry install which I usually try to avoid to speed up building time thanks to the docker caching system. Is there a way of passing parameters to poetry-dynamic-versioning so that I don't need to copy the entire .gitfolder during docker build?

Broken subdependency?

This started happening today. The server is equipped with a git version which does not support the --porcelain value.

If I remove poetry-dynamic-versioning==0.10.0 from the pip install command, the issue is gone, and I'm wondering if it can be any of the subdeps of poetry-dynamic-versioning that could be causing this...?

I prefer not to update git at this point in time, if possible. Would it be possible to pin a subdep, if that is causing this?

source venv/bin/activate
pip install poetry==1.0.10 poetry-dynamic-versioning==0.10.0
poetry install -v

Installing dependencies from lock file

[RuntimeError]
The command 'git status --porcelain=v1' returned code 129. Output:
error: option `porcelain' takes no value
usage: git status [<options>] [--] <pathspec>...

    -v, --verbose         be verbose
    -s, --short           show status concisely
    -b, --branch          show branch information
    --porcelain           machine-readable output
    --long                show status in long format (default)
    -z, --null            terminate entries with NUL
    -u, --untracked-files[=<mode>]
                          show untracked files, optional modes: all, normal, no. (Default: all)
    --ignored             show ignored files
    --ignore-submodules[=<when>]
                          ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)
    --column[=<style>]    list untracked files in columns

Fails with just poetry-core

For some reason, doc builds in readthedocs for https://github.com/copier-org/copier started failing recently.

You can see https://readthedocs.org/projects/copier/builds/12592301/ for example.

The relevant configuration in pyproject.toml was:

[build-system]
requires = ["poetry_core>=1.0.0", "poetry-dynamic-versioning"]
build-backend = "poetry.core.masonry.api"

The error was:

/home/docs/checkouts/readthedocs.org/user_builds/copier/envs/317/bin/python -m pip install --upgrade --upgrade-strategy eager --no-cache-dir .[docs]
Processing /home/docs/checkouts/readthedocs.org/user_builds/copier/checkouts/317
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
    Preparing wheel metadata: started
    Preparing wheel metadata: finished with status 'error'
    ERROR: Command errored out with exit status 1:
     command: /home/docs/checkouts/readthedocs.org/user_builds/copier/envs/317/bin/python /home/docs/checkouts/readthedocs.org/user_builds/copier/envs/317/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py prepare_metadata_for_build_wheel /tmp/tmpcl96uht6
         cwd: /tmp/pip-req-build-_madcsdq
    Complete output (12 lines):
    Traceback (most recent call last):
      File "/home/docs/checkouts/readthedocs.org/user_builds/copier/envs/317/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py", line 280, in <module>
        main()
      File "/home/docs/checkouts/readthedocs.org/user_builds/copier/envs/317/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py", line 263, in main
        json_out['return_val'] = hook(**hook_input['kwargs'])
      File "/home/docs/checkouts/readthedocs.org/user_builds/copier/envs/317/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py", line 133, in prepare_metadata_for_build_wheel
        return hook(metadata_directory, config_settings)
      File "/tmp/pip-build-env-ze9az9mi/overlay/lib/python3.8/site-packages/poetry/core/masonry/api.py", line 34, in prepare_metadata_for_build_wheel
        poetry = Factory().create_poetry(Path(".").resolve())
      File "/tmp/pip-build-env-ze9az9mi/overlay/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 287, in alt_poetry_create
        run_mod = _state.original_import_func("poetry.console.commands.run", fromlist=[None])
    ModuleNotFoundError: No module named 'poetry.console'
    ----------------------------------------
ERROR: Command errored out with exit status 1: /home/docs/checkouts/readthedocs.org/user_builds/copier/envs/317/bin/python /home/docs/checkouts/readthedocs.org/user_builds/copier/envs/317/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py prepare_metadata_for_build_wheel /tmp/tmpcl96uht6 Check the logs for full command output.

I have changed it to this, as a workaround to fix the build, but previous config was working fine until recently:

[build-system]
requires = ["poetry>=1.1.0", "poetry-dynamic-versioning"]
build-backend = "poetry.core.masonry.api"

First `poetry install` does not include dynamic version

Using Poetry version 1.1.5, poetry-dynamic-versioning 0.12.6, my pyproject.toml contains:

[tool.poetry]
name = "mylib"
version = "0"

[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
format = "0.1.2+{commit}"

[tool.poetry.dependencies]
poetry-dynamic-versioning = "^0.12.6"

[build-system]
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=0.12.6"]
build-backend = "poetry.core.masonry.api"

When I first clone my repository and poetry install, the installed version of mylib is 0.

Installing the current project: mylib (0)

If I run poetry install again, then the version is correctly set to 0.1.2+<hash>.

No dependencies to install or update                                                                                                      
                                                                                                                                          
Installing the current project: mylib (0.1.2+b0703a2)     

Crashes due to not specified encoding when working with pyproject.toml file

Tested on Windows10 with the following version of poetry-dynamic-versioning:

> pip freeze | grep poetry-dynamic-versioning
poetry-dynamic-versioning==0.12.6

The problem is that poetry-dynamic-versioning does not work if the pyproject.toml file contains non-ASCII characters as in the following sample:

description = "A small but powerful command-line interface to ØMQ."

The pyproject.toml file is in the utf-8 encoding which is AFAIK correct.

The reason for this problem is missing 'encoding' parameter while working with the pyroject.toml file so the default system encoding is used (in this case cp1250). The correct encoding should be utf-8.

I will submit a pull request for this issue soon.

Error message:

(.venv) c:\Work\TTR\zmqcli>poetry-dynamic-versioning.exe
Error processing line 1 of c:\work\ttr\zmqcli\.venv\lib\site-packages\zzz_poetry_dynamic_versioning.pth:

  Traceback (most recent call last):
    File "c:\Users\rhorenov\AppData\Local\Programs\Python\Python39\lib\site.py", line 169, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "c:\work\ttr\zmqcli\.venv\lib\site-packages\poetry_dynamic_versioning\__init__.py", line 506, in activate
      config = get_config()
    File "c:\work\ttr\zmqcli\.venv\lib\site-packages\poetry_dynamic_versioning\__init__.py", line 141, in get_config
      pyproject = tomlkit.parse(pyproject_path.read_text())
    File "c:\Users\rhorenov\AppData\Local\Programs\Python\Python39\lib\pathlib.py", line 1257, in read_text
      return f.read()
    File "c:\Users\rhorenov\AppData\Local\Programs\Python\Python39\lib\encodings\cp1250.py", line 23, in decode
      return codecs.charmap_decode(input,self.errors,decoding_table)[0]
  UnicodeDecodeError: 'charmap' codec can't decode byte 0x98 in position 130: character maps to <undefined>

Remainder of file ignored
Error processing line 1 of c:\work\ttr\zmqcli\.venv\lib\site-packages\zzz_poetry_dynamic_versioning.pth:

  Traceback (most recent call last):
    File "c:\Users\rhorenov\AppData\Local\Programs\Python\Python39\lib\site.py", line 169, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "c:\work\ttr\zmqcli\.venv\lib\site-packages\poetry_dynamic_versioning\__init__.py", line 506, in activate
      config = get_config()
    File "c:\work\ttr\zmqcli\.venv\lib\site-packages\poetry_dynamic_versioning\__init__.py", line 141, in get_config
      pyproject = tomlkit.parse(pyproject_path.read_text())
    File "c:\Users\rhorenov\AppData\Local\Programs\Python\Python39\lib\pathlib.py", line 1257, in read_text
      return f.read()
    File "c:\Users\rhorenov\AppData\Local\Programs\Python\Python39\lib\encodings\cp1250.py", line 23, in decode
      return codecs.charmap_decode(input,self.errors,decoding_table)[0]
  UnicodeDecodeError: 'charmap' codec can't decode byte 0x98 in position 130: character maps to <undefined>

Remainder of file ignored
Error: 'charmap' codec can't decode byte 0x98 in position 130: character maps to <undefined>

How to make dev release auto-bump patch?

Let's say a commit is tagged with 1.0.0. Then I create another commit without tagging it. Now, how can I make my builds say 1.0.1.dev0... by default (like setuptools_scm does) until I actually create another git tag?

I am just wondering about the automatic patch bump, like assuming that the next tag will at least be a patch bump (but since no tagging was made, you don't really know).

Not compatible with recommended poetry install mechanism

I use pyenv pretty heavily to flip around between environments. The only way that this works with poetry is to use this recommended install method through the script install.

If I do this, when I install dynamic versioning I get the following error:

Traceback (most recent call last):
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 119, in _patch_poetry_create
    poetry_factory_module = _state.original_import_func("poetry.factory", fromlist=["Factory"])
ModuleNotFoundError: No module named 'poetry.factory'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/cahurst/.poetry/bin/poetry", line 14, in <module>
    main()
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 162, in alt_poetry_console_main
    _patch_poetry_create()
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 123, in _patch_poetry_create
    poetry_factory_module = _state.original_import_func("poetry.poetry", fromlist=["Poetry"])
  File "/Users/cahurst/.poetry/lib/poetry/poetry.py", line 11, in <module>
    from .json import validate_object
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 173, in alt_import
    module = _state.original_import_func(name, globals, locals, fromlist, level)
  File "/Users/cahurst/.poetry/lib/poetry/json/__init__.py", line 4, in <module>
    import jsonschema
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 173, in alt_import
    module = _state.original_import_func(name, globals, locals, fromlist, level)
  File "/Users/cahurst/.poetry/lib/poetry/_vendor/py3.8/jsonschema/__init__.py", line 33, in <module>
    __version__ = get_distribution(__name__).version
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 481, in get_distribution
    dist = get_provider(dist)
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 357, in get_provider
    return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 900, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/Users/cahurst/.pyenv/versions/3.8.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 786, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'jsonschema' distribution was not found and is required by the application

Is there away around this error? Do I am guessing I need to do something with injecting the library into the segregated poetry build environment.

Issue when used inside a Jenkins pipeline

When attempting to use dynamic versioning manually using the command poetry-dynamic-versioning in a Jenkins pipeline, I get the following error :
[ValueError] invalid literal for int() with base 10: "warning: refname 'v0.0.11' is ambiguous.\n0"

I think it's caused by the following lines : https://github.com/mtkennerly/dunamai/blob/master/dunamai/__init__.py#L338-L339
L338 we retrieve a message which is actually "warning: refname 'v0.0.11' is ambiguous.\n0"
L339 we try to cast that message to an integer.

As for why this warning occur, it's because I use Jenkins and tags to make a release. First I create a git tag (in this case v0.0.11), then I schedule a Jenkins build to do various stuff (among them call poetry-dynamic-versioning). However, during initialization, Jenkins does git checkout -b v0.0.11 8945d639f97f7e5a00364o249f844ee33e93a2e4 so a branch named v0.0.11 is created.

Add an option to bump the version only if not on tag.

Current behavior of generating the version number, regarding the bump setting and being on a commit without a version tag or with a version tag, looks as follows:

  • When on a commit without a version tag and bump = True, version number will be bumped and a .dev with a distance from the version tag and a commit hash will be added.
  • When on a commit without a version tag and bump = False, version number will not be bumped and a .post with a distance from the version tag, a .dev0 and a commit hash will be added
  • When on a commit with a version tag and bump = True, version number will be bumped, no other changes will be made
  • When on a commit with a version tag and bump = False, version number will not be bumped, version used "as is" from the tag.

But there is no option to mix the first and the last behavior (to achieve similar version number generation setuptools-scm has).

Jinja format for bumping version of <distance> steps

Hi,
my workflow bumps base version by N patch-versions, where N is the distance from the last tagged version.

I wrote this macro which does what I need, and wanted to share with you and the users, if this helps.
In my case it works out of the box, but discards any other elements which is not base or distance, which can clearly be a limitation for other people

do you think we could have instead a function which does that (in python)?

If there is a official way to extend your 'plugin', it would be great, so I can add this function just to my extention and keep upstream simple.

[tool.poetry-dynamic-versioning]
  enable = true
  style = "pep440"

  format-jinja = """
{%- macro bump_n_versions(base, distance) -%}
  {%- if distance|int >= 2 -%}
    {%- set bumped_base = bump_version(base) -%}
    {{- bump_n_versions(bumped_base, distance-1) -}}
  {%- elif distance|int == 1 -%}
    {%- set bumped_base = bump_version(base) -%}
    {{- bumped_base -}}
  {%- else -%} {# distance==0 #}
    {{- base -}}
  {%- endif -%}
{%- endmacro -%}

{{- bump_n_versions(base, distance) -}}
"""

Warning/Error not thrown when failed to get git tag information

Ran into an issue where the version was not getting bumped correctly inside docker builds.
It turned out that COPY . . did not copy all the .git files/dirs/subdirs such that doing git tag did not return anything.

I think a warning/error should be thrown in this case.

Version 0.12.1

Query the current version from python REPL?

Hi,

I've got the following in my pyproject.toml:

[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
pattern  = "^(?P<base>\\d+\\.\\d+\\.\\d+)(-?((?P<stage>[a-zA-Z]+)\\.?(?P<revision>\\d+)?))?"
format-jinja = """
    {%- if distance == 0 -%}
        {{- base -}}
    {%- else -%}
        {{- bump_version(base, 2) }}.dev{{ distance }}+g{{ commit }}.d{{ datetime.now().strftime('%Y%m%d%H%M%S') -}}
    {%- endif -%}
"""
format-jinja-imports = [
    { module = "datetime", item = "datetime" }
]

[build-system]
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
build-backend = "poetry.core.masonry.api"

How can I, using only the REPL (and of course with poetry-dynamic-versioning installed in my venv) query for the current version in my git project?

Multiple installations of package when using poetry-dynamic-versioning with path install

Hi!

Let's say I have two projects, "a" and "b";

pyproject.toml:

[tool.poetry]
name = "a"
version = "0.0.0"

[tool.poetry.dependencies]
b = "*"

[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
pattern  = "^(?P<base>\\d+\\.\\d+\\.\\d+)(-?((?P<stage>[a-zA-Z]+)\\.?(?P<revision>\\d+)?))?"
format-jinja = """
    {%- if distance == 0 -%}
        {{- base -}}
    {%- else -%}
        {{- bump_version(base, 2) }}.dev{{ distance - 1 }}+g{{ commit }}.d{{ datetime.now().strftime('%Y%m%d%H%M%S') -}}
    {%- endif -%}
"""
format-jinja-imports = [
    { module = "datetime", item = "datetime" }
]

Then let's say I install the "b" package. All is nice and works fine.

But if I need to do some local development, and temporarily change the toml into the following;

[tool.poetry.dependencies]
b = { path = "/home/fredrik/code/repos/b", develop = true }

...followed by a poetry install... there will be a new package installed in the site-packages of my venv. And for each time I re-run poetry install yet another package of "b" is installed. Basically, the installations cause accumulation of package installations and it seems Python is unable to pick the one I expect it to pick.

I no longer have a screenshot of what it looks like in the site-packages folder, but basically there were multiple package installations of "b" with the datetime string at the end of the folder name. Maybe that is what is causing this to happen (each installation folder has a unique datetime suffix).

I've also seen this accumulation of older versions of a package (using poetry-dynamic-versioning) in venvs created with virtualenv (not venv) in our CI, but that is not using the "path installation" and seem to work fine.

This is all on the latest poetry 1.1.5 with poetry-dynamic-versioning 0.12.4.

Do you think there's something we could do about this?

feature request: revert or not revert

While it's right there in your docs that any changes made to versions get reverted at exit, I'm having trouble figuring out the use case for this behavior. I want to be able to tag the revision then run "poetry version" then the tag gets propagated to pyproject.toml and my source code.

One can enable this by making a "revert" flag in the configuration, which if set false the files do not get reverted.

def deactivate() -> None:
config = get_config()
if "revert" in config:
if not config["revert"]:
return

pip wheel alternative

I have a bit of a problem with this issue in production. We use git links in pyproject.toml:

[tool.poetry.dependencies]
pkg1 = { git = "ssh://SERVER/repo" }

The version in pyproject is untouched, and left at 0.0.0, since we apply versioning using your plugin instead.
I then need to deliver wheels to an air-gapped system and so I need to perform something like:

$ poetry export -f requirements.txt --output requirements.txt
$ pip wheel -r requirements.txt  # downloads all wheels for delivery

The resulting requirements.txt file:

-e git+ssh://SERVER/repo.git@<hash>#egg=pc-sw

The resulting downloaded wheel is named pkg1-0.0.0-py3-none-any.whl but I was actually expecting a proper semver version here, not 0.0.0. 😢

I presume the problem here is that the wheel is built through pip (where your plugin is not available). I wonder if I could somehow instead use poetry so to get the actual SCM-managed version used as the version of the wheel, instead of "0.0.0" Any ideas?

Accessing Package Version in CI/CD Pipeline

I have a python package that I deploy in a CI/CD pipeline and I only want to publish the package given a clean tag/version number. I have successfully done this before with the following:

        pip3 install pipenv
        pipenv install --dev --python `which python3` --deploy --ignore-pipfile
        version=`pipenv run python setup.py --version`

        if [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
        then
            echo "Publishing package version: $version"
            pipenv run python setup.py bdist_wheel upload
        else
          echo "Not a clean distribution, skipping release - Version: $version"
        fi

I use Pipenv to manage the package and want to switch over to Poetry, while taking advantage of poetry-dynamic-versioning. Do you have a recommended approach to get the version?

Installing plugin in global Python installation not necessary

In the documentation it says:

Note that you must install the plugin in your global Python installation, 
not as a dependency in pyroject.toml, 
because the virtual environment that Poetry creates 
cannot see Poetry itself and therefore cannot patch it.

However I added it in a project with poetry add, installed it with poetry install and then ran poetry build (all this from inside a virtual environment of the project previously created by poetry). Checking inside the generated tar.gz the versions were correctly patched.

I am using version 0.6.0

[Question] Using with github actions

Hi

First, a big thank for your work and the package.
I am looking at using poetry-dynamic-versioning from an existing gh workflow. To give you a bit of context I am looking at building daily snaphots on top of regular tagged releases that are deployed on PyPi.

My Python/C++ project is using poetry but I am using build to run my workflows on GH. Cloning my repo on my laptop, and running poetry build locally seems to be running ok generating an artifact (scikit_decide-0.9.1.post81.dev0+f02af31-cp38-cp38-macosx_10_15_x86_64.whl)

Launching my workflow on GH leads to a very different result. The generated artifact is now: scikit_decide-0.0.0.post1.dev0+f02af31-cp38-cp38-macosx_10_15_x86_64.whl

Can this be due to the way I clone my repo ?

      - name: Checkout scikit-decide source code
        uses: actions/checkout@v2
        with:
          submodules: true

while my build is done using:

      - name: Build macOS/Windows wheel
        if: matrix.os != 'ubuntu-latest'
        run: |
          python -m pip install --upgrade -q pip
          pip install build poetry-dynamic-versioning
          python -m build --sdist --wheel

Thanks

Document git version needed

I got the following error when using poetry-dynamic-versioning:

Error: The command 'git tag --merged HEAD --sort -creatordate' returned code 129. Output:
error: unknown option `merged'

This feature was introduced in git 2.7.2 (released in 2016, long time ago, but not available on some platforms yet).

File substitution not working with namespace package

I am trying to replace __version__ = "0.0.0" with default file and pattern parameters but nothing is replaced. I am using a namespace package structure with code in src/top_namespace/next_namespace/__init__.py.

Hitting a weird bug where distance to last tag is far away

Hi!

I'm hitting a weird bug, I think...

In a GitLab PR, the commit distance is quite far away from the last tag. I've noticed that all of a sudden, I'm getting a 0.0.1 release when building a wheel.

Full output to illustrate the problem:

$ git log --graph --decorate --pretty=oneline --abbrev-commit
* cf46f54 (HEAD -> somebranch, origin/somebranch) obfuscated
* 0513694 obfuscated
* 9925bf0 obfuscated
* c8de772 obfuscated
* d0c594f obfuscated
* 4c28f28 obfuscated
* 7bddeb2 obfuscated
* d53f67c obfuscated
* c761777 obfuscated
* dc19807 obfuscated
* dc17e6b obfuscated
* bc8d09a obfuscated
* de08edb obfuscated
* 4251f56 obfuscated
* db35304 obfuscated
* d0561a1 obfuscated
* fd8dded obfuscated
* 9a98dca obfuscated
* b02bf94 obfuscated
* 687c86b obfuscated
* 8ee81d9 obfuscated
* 22cb5d8 obfuscated
* 99ddcda obfuscated
* 53881f6 obfuscated
* f71452b obfuscated
* ab06b3b obfuscated
* fd6e0ed obfuscated
* e4d44d4 obfuscated
*   0b2714e Merge branch 'somebranch' of xxx into somebranch
|\  
| * ec62f49 obfuscated
| * 29309df obfuscated
| * c1e8ed4 obfuscated
| * c681b20 obfuscated
| * 86e0550 obfuscated
| * e7586b0 obfuscated
| * 98e0b38 obfuscated
| * 1041e4d obfuscated
| * f083c0b obfuscated
| * 8d94c54 obfuscated
| * 5d3deb3 obfuscated
| * 612d12f obfuscated
| * 49ef012 obfuscated
| * 5288f58 obfuscated
| * cad651d obfuscated
| * e4102f4 obfuscated
| * 3f7fdc6 obfuscated
| * 600b579 obfuscated
| * e2cf989 obfuscated
| * fc52824 obfuscated
| * 014cd27 obfuscated
| * d379221 obfuscated
| * 3ae644f obfuscated
| * 8b74674 obfuscated
| * 5318a9a obfuscated
| * 93318a5 obfuscated
| * 5f2dfa0 obfuscated
| * 3fea383 obfuscated
| * 1fe44c3 obfuscated
| * 5270882 obfuscated
| * 9b0f7da obfuscated
| * 5271bcd obfuscated
| * 2a7a988 obfuscated
| * b698566 (tag: multitag-bug-test, tag: 1.68.0, origin/master, origin/HEAD, master) obfuscated
$ git --no-pager tag
0.1.0
1.0.0
1.1.0
1.10.0
1.11.0
1.12.0
1.16.0
1.17.0
1.18.0
1.19.0
1.2.0
1.20.0
1.21.0
1.22.0
1.23.0
1.24.0
1.24.1
1.24.2
1.25.0
1.26.0
1.27.0
1.28.0
1.29.0
1.3.0
1.30.0
1.31.0
1.32.0
1.33.0
1.34.0
1.35.0
1.36.0
1.37.0
1.38.0
1.38.1
1.39.0
1.4.0
1.4.1
1.40.0
1.41.0
1.42.0
1.43.0
1.44.0
1.45.0
1.46.0
1.47.0
1.48.0
1.49.0
1.5.0
1.5.1
1.5.2
1.5.3
1.50.0
1.51.0
1.52.0
1.53.0
1.54.0
1.55.0
1.56.0
1.57.0
1.58.0
1.59.0
1.6.0
1.60.0
1.61.0
1.62.0
1.63.0
1.64.0
1.65.0
1.66.0
1.67.0
1.68.0
1.7.0
1.7.1
1.7.2
1.8.0
1.8.1
1.9.0
1.9.1
1.9.2
$ poetry build --format wheel
Building pc-swdp-generic (0.0.1.dev90+gcf46f54.d20210618082223)
  - Building wheel
  - Built pc_swdp_generic-0.0.1.dev90+gcf46f54.d20210618082223-py3-none-any.whl

A couple of commits back, in the very same PR I see this when I build the wheel:

$ poetry build --format wheel
Building pc-swdp-generic (1.66.1.dev32+gddc29e5.d20210611144222)
  - Building wheel
  - Built pc_swdp_generic-1.66.1.dev32+gddc29e5.d20210611144222-py3-none-any.whl

Have you seen anything like this before?

Not working correctly on Fedora when installing from git

Copied from https://bugzilla.redhat.com/show_bug.cgi?id=1960138

Description of problem:
Fedora's pip cannot determine properly the installed package version when done through git.

Version-Release number of selected component (if applicable):
python3-pip-21.0.1-2.fc34.noarch

Steps to Reproduce:

  1. pip install git+https://github.com/copier-org/copier
  2. copier --version

Actual results: copier 0.0.0

Expected results: copier 6.0.0a6.post27.dev0+60f9160

Additional info:
I'm copier maintainer.

It works as expected in other environments, but for some reason not in Fedora:

❯ podman container run --rm -it docker.io/python:3.9 bash -c 'pip install -q git+https://github.com/copier-org/copier && copier --version'
copier 6.0.0a6.post27.dev0+60f9160

According to Fedora maintainer, probably fixing #39 should fix this issue as a side effect.

However, since this is a separate explicit issue, I think it's better for it to be tracked separately.

See https://bugzilla.redhat.com/show_bug.cgi?id=1960138#c2 for an analysis about why this is happening and how it could be fixed.

Thanks!

Support for poetry 1.1.0, poetry-core

Hi 🍻

I know it's early days for poetry 1.1.0 (not even out yet). But I just tried using poetry-dynamic-versioning 0.9.0 with poetry 1.1.0rc1 (with poetry-core 1.0.0rc2 as build-system).

During a poetry install, I can se git URLs like this (which shows the appropriate semver with poetry 1.0.10):

• Installing pkg1 (0.0.0 141bd6e)

In this case, pkg1 is actually using the build system poetry>=0.12, so maybe this is simply an incompatible combo?

Figured I'd report it here.

Thanks for your excellent work on this plugin/hack and on Dunamai! ❤

Odd behavior when using git URLs in pyproject.toml

I have the following in my pyproject.toml in pkg1:

[tool.poetry.dependencies]
python = "^3.7"
pkg2 = { git = "ssh://server/project/repo" }

[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
pattern  = "^(?P<base>\\d+\\.\\d+\\.\\d+)(-?((?P<stage>[a-zA-Z]+)\\.?(?P<revision>\\d+)?))?"
format-jinja = """
    {%- if distance == 0 -%}
        {{- base -}}
    {%- else -%}
        {{- bump_version(base, 2) }}.dev{{ distance - 1 }}+g{{ commit }}.d{{ datetime.now().strftime('%Y%m%d%H%M%S') -}}
    {%- endif -%}
"""
format-jinja-imports = [
    { module = "datetime", item = "datetime" }
]

And during poetry install -v I can see that the dependency pkg2 is being installed as:

- Installing pkg2 (0.0.1.dev1+gda05bfa.d20200827155343 6d5b826)

The funny thing here is that pk2 does not use poetry-dynamic-versioning. As you can see the hashes also do not match. It also has version git tags (although its pyproject.toml says 0.0.0). Seems like this info is actually taken from pkg1 (rather than from pkg2).

I presume this might be a limitation of poetry-dynamic-versioning?

[Question] How can I use poetry version with this plugin?

Hello, I would like to know if I can use poetry version patch (for example) and then the plugin is going to update everything(init.py, pythonprojec.toml, etc). I would like that after a poetry version command it will create that version, tag it with a git tag and push it. After that, I can use poetry publish to upload my package.

Does this plugin support that behaviour?

thank you!

poetry-dynamic-versioning breaks functionality of some poetry commands (e.g. poetry add, poetry remove) which modify pyproject.toml

Hi,
when poetry-dynamic-versioning is enabled for a project, some poetry commands do not work as expected.

For instance, the expected result of poetry add <dependency> or poetry remove <dependency> commands is to modify the content of pyproject.toml file with the new/removed package dependencies.

I think the reason is that, upon deactivation, poetry-dynamic-versioning completely restores the original contents of pyproject.toml, thus discarding any legitimate modifications to the file performed by poetry.

Would it make sense to only restore the original version field, and keep any other modifications?
If so, I can provide a PR for this.

Thanks and best regards,
Luca

Errors building with poetry-core through tox

Hi,

Thanks for the tool, I'm looking forward to adopting it!

This looks similar to #35 in that I'm experiencing issues when tox tries to build my project using poetry-core.

Build system config:

[build-system]
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
build-backend = "poetry.core.masonry.api"

Here is the tox log showing the installed libs:

action: .package, msg: getenv
cwd: /home/peter/topsport-com-au/tmpl-package
cmd: /home/peter/topsport-com-au/tmpl-package/.tox/.package/bin/python -m pip install 'poetry-core>=1.0.0' poetry-dynamic-versioning
Collecting poetry-core>=1.0.0
  Using cached poetry_core-1.0.0-py2.py3-none-any.whl (409 kB)
Collecting poetry-dynamic-versioning
  Using cached poetry_dynamic_versioning-0.12.1-py3-none-any.whl (11 kB)
Collecting dunamai<2.0,>=1.5
  Using cached dunamai-1.5.4-py3-none-any.whl (16 kB)
Requirement already satisfied: setuptools>=8.0 in ./.tox/.package/lib/python3.9/site-packages (from dunamai<2.0,>=1.5->poetry-dynamic-versioning) (51.3.3)
Collecting jinja2<3.0.0,>=2.11.1
  Using cached Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
Collecting MarkupSafe>=0.23
  Using cached MarkupSafe-1.1.1-cp39-cp39-linux_x86_64.whl
Collecting tomlkit>=0.4
  Using cached tomlkit-0.7.0-py2.py3-none-any.whl (32 kB)
Installing collected packages: MarkupSafe, tomlkit, jinja2, dunamai, poetry-dynamic-versioning, poetry-core
Successfully installed MarkupSafe-1.1.1 dunamai-1.5.4 jinja2-2.11.2 poetry-core-1.0.0 poetry-dynamic-versioning-0.12.1 tomlkit-0.7.0
WARNING: You are using pip version 20.3.3; however, version 21.0 is available.
You should consider upgrading via the '/home/peter/topsport-com-au/tmpl-package/.tox/.package/bin/python -m pip install --upgrade pip' command.

And there are 2 log files with errors after tox fails to package the project:

action: .package, msg: get-build-requires
cwd: /home/peter/topsport-com-au/tmpl-package
cmd: /home/peter/topsport-com-au/tmpl-package/.tox/.package/bin/python /home/peter/.cache/pypoetry/virtualenvs/tmpl-package-yMfoEiUP-py3.9/lib/python3.9/site-packages/tox/helper/build_requires.py poetry.core.masonry.api '' ''
Error processing line 1 of /home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/zzz_poetry_dynamic_versioning.pth:

  Traceback (most recent call last):
    File "/home/peter/.pyenv/versions/3.9.1/lib/python3.9/site.py", line 169, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "/home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 478, in activate
      _apply_patches()
    File "/home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 435, in _apply_patches
      from poetry import factory as factory_mod
    File "/home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 385, in alt_import
      _patch_poetry_create(module.factory)
  AttributeError: module 'poetry' has no attribute 'factory'

Remainder of file ignored
[]

... and this:

action: .package, msg: perform-isolated-build
cwd: /home/peter/topsport-com-au/tmpl-package
cmd: /home/peter/topsport-com-au/tmpl-package/.tox/.package/bin/python /home/peter/.cache/pypoetry/virtualenvs/tmpl-package-yMfoEiUP-py3.9/lib/python3.9/site-packages/tox/helper/build_isolated.py .tox/dist poetry.core.masonry.api '' ''
Error processing line 1 of /home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/zzz_poetry_dynamic_versioning.pth:

  Traceback (most recent call last):
    File "/home/peter/.pyenv/versions/3.9.1/lib/python3.9/site.py", line 169, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "/home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 478, in activate
      _apply_patches()
    File "/home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 435, in _apply_patches
      from poetry import factory as factory_mod
    File "/home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 385, in alt_import
      _patch_poetry_create(module.factory)
  AttributeError: module 'poetry' has no attribute 'factory'

Remainder of file ignored
Traceback (most recent call last):
  File "/home/peter/.cache/pypoetry/virtualenvs/tmpl-package-yMfoEiUP-py3.9/lib/python3.9/site-packages/tox/helper/build_isolated.py", line 41, in <module>
    basename = backend.build_sdist(dist_folder, {"--global-option": ["--formats=gztar"]})
  File "/home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/poetry/core/masonry/api.py", line 62, in build_sdist
    poetry = Factory().create_poetry(Path(".").resolve())
  File "/home/peter/topsport-com-au/tmpl-package/.tox/.package/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 287, in alt_poetry_create
    run_mod = _state.original_import_func("poetry.console.commands.run", fromlist=[None])
ModuleNotFoundError: No module named 'poetry.console'

If I remove "poetry-dynamic-versioning" from the build-system requirements tox is able to build the project and run tests etc.

I'm happy to provide more info if necessary, and apologies if I'm doing something stupid/missed something obvious!

poetry 1.0.10 build/shell/install/update does not trigger versioning

I have this in my pyprojects.toml :

[build-system]
requires = ["poetry>=1.0.10", "poetry-dynamic-versioning"]
build-backend = "poetry.masonry.api"

[tool.poetry-dynamic-versioning]
enable = true
latest-tag = true
pattern = "^(?P<base>\\d+\\.\\d+\\.\\d+)"
format = "{base}"
# bump = true

[tool.poetry-dynamic-versioning.substitution]
files = ["*/settings.py"]

Neither of the poetry commands trigger anything but using the CLI poetry-dynamic-versioning works as expected.

Issues trying to run with tox poetry helpers

Greeting,

First thanks for much for this plugin. This is one the main thing keeping us on setuptools+pbr.

I've gotten the plugin install and configure and working such that we can use poetry build and get package version we want. The problem is when I try and run our unit tests via tox. With poetry-dynamic-versioning disabled our unit tests work no problem. With poetry-dynamic-versioning enabled though we get the following error.

cfb@sandman:pistol.poetry/> venv-pistol/bin/tox -e py3
.package create: /Users/cfb/cisco/git/de/pistol.poetry/tox/py3
.package installdeps: poetry-core>=1.0.0, poetry-dynamic-versioning
py3 recreate: /Users/cfb/cisco/git/de/pistol.poetry/tox/py3
_______________________________________________________________ summary _______________________________________________________________
  py3: commands succeeded
  congratulations :)
Traceback (most recent call last):
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/bin/tox", line 8, in <module>
    sys.exit(cmdline())
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox/session/__init__.py", line 44, in cmdline
    main(args)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox/session/__init__.py", line 69, in main
    exit_code = session.runcommand()
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox/session/__init__.py", line 197, in runcommand
    return self.subcommand_test()
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox/session/__init__.py", line 225, in subcommand_test
    run_sequential(self.config, self.venv_dict)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox/session/commands/run/sequential.py", line 9, in run_sequential
    if venv.setupenv():
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox/venv.py", line 628, in setupenv
    status = self.update(action=action)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox/venv.py", line 275, in update
    self.hook.tox_testenv_install_deps(action=action, venv=self)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/pluggy/callers.py", line 208, in _multicall
    return outcome.get_result()
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox_poetry_installer/hooks.py", line 71, in tox_testenv_install_deps
    poetry = utilities.check_preconditions(venv, action)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/tox_poetry_installer/utilities.py", line 49, in check_preconditions
    return _poetry.Factory().create_poetry(venv.envconfig.config.toxinidir)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 296, in alt_poetry_create
    instance = original_poetry_create(cls, *args, **kwargs)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/poetry/factory.py", line 33, in create_poetry
    base_poetry = super(Factory, self).create_poetry(cwd)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 326, in alt_poetry_create
    config = get_config(cwd)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 134, in get_config
    pyproject_path = _get_pyproject_path(start)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 130, in _get_pyproject_path
    return _find_higher_file("pyproject.toml", start=start)
  File "/Users/cfb/cisco/git/de/pistol.poetry/venv-pistol/lib/python3.9/site-packages/poetry_dynamic_versioning/__init__.py", line 122, in _find_higher_file
    for level in [start, *start.parents]:
AttributeError: 'LocalPath' object has no attribute 'parents'

pyproject.toml

[tool.poetry]
name = "pistol"
version = "0.0.0"
description = "Polaris Image Smithing ToOLs"
authors = [
    "Chet Burgess <[email protected]>",
    "Darren Sanders <[email protected]>"
]
classifiers = [
    "Development Status :: 4 - Beta",
    "Environment :: Console",
    "Intended Audience :: Developers",
    "Intended Audience :: Information Technology",
    "Intended Audience :: System Administrators",
    "Natural Language :: English",
    "Operating System :: POSIX :: Linux",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.6",
    "Programming Language :: Python :: 3.7",
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Topic :: System :: Systems Administration",
    "Topic :: Utilities",
]
exclude = ["pistol/tests/*"]

[tool.poetry.scripts]
get_version = 'pistol.cli.get_version:main'
get_remote_url = 'pistol.cli.get_remote_url:main'
get_repo_name = 'pistol.cli.get_repo_name:main'
git_list_tags = 'pistol.cli.git_list_tags:main'
find_best_tag = 'pistol.cli.find_best_tag:main'
find_best_version_dir = 'pistol.cli.find_best_version_dir:main'
tag_new_release = 'pistol.cli.tag_new_release:main'
render_templates = 'pistol.cli.render_templates:main'

[tool.poetry.dependencies]
python = ">=3.6.1,<4.0.0"
click = "^7.1.2"
pygit2 = "^1.5.0"
cached-property = "^1.5.2"
PyYAML = "^5.4.1"
terminaltables = "^3.1.0"
deepmerge = "^0.1.1"
Jinja2 = "^2.11.3"

[tool.poetry.dev-dependencies]
bandit = "^1.7.0"
coverage = "^5.5"
fixtures = "^3.0.0"
flake8 = "^3.8.4"
flake8-bugbear = "^20.11.1"
flake8-docstrings = "^1.5.0"
isort = "^5.7.0"
pyfakefs = "^4.4.0"
stestr = "^3.1.0"
testscenarios = "^0.5.0"
testresources = "^2.0.1"
testtools = "^2.4.0"

[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
style = "semver"
pattern = "^(?P<base>\\d+\\.\\d+\\.\\d+)$"
format-jinja = """
    {%- set pre = None -%}
    {%- set metadata = None -%}
    {%- set build_type = env['POERTY_BUILD_TYPE']|default('NONE') -%}
    {%- if distance != 0 -%}
        {%- set pre = ['dev', distance] -%}
        {%- if build_type == 'premerge' -%}
            {%- set metadata = [commit] -%}
        {%- endif -%}
    {%- endif -%}
    {{ serialize_semver(base, pre, metadata) }}
"""

[build-system]
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
build-backend = "poetry.core.masonry.api"

tox.ini

[tox]
isolated_build = true
envlist = py3, pep8, bandit, formatcheck
toxworkdir={toxinidir}/tox

[testenv]
require_locked_deps = true
install_dev_deps = true
passenv =
    BASEPYTHON
basepython = python3
envdir = {toxworkdir}/py3
setenv =
    VIRTUAL_ENV={envdir}
whitelist_externals =
    bash
    echo
    mkdir
commands =
    failing: stestr run --failing
    pep8: flake8 {posargs}
    debug: python -m testtools.run discover '{posargs}'
    test: python -m testtools.run '{posargs}'
    bandit: bandit -c bandit.yml -r pistol
    venv: {posargs}

[testenv:py3]
setenv =
    PYTHON=coverage run --source pistol --parallel-mode
commands =
    stestr run '{posargs}'
    stestr slowest
    coverage combine
    coverage report --fail-under=100

[testenv:formatcheck]
commands =
    isort --fss --sl -c pistol

[testenv:format]
commands =
    isort -fss -sl -rc pistol

[testenv:cover]
setenv =
    {[testenv]setenv}
    PYTHON=coverage run --source pistol --parallel-mode
commands =
    stestr run '{posargs}'
    coverage combine
    coverage report
    coverage xml -o coverage.xml
    mkdir -p cover
    coverage html -d cover
    echo "Point your browser at cover/index.html to see the HTML report."

[flake8]
max-line-length = 79
max-complexity = 13
doctests = True
filename= *.py
exclude =
    .git,
    .tox,
    tox,
    __pycache__,
    alembic,
    bin,
    lib,
    build,
    dist,
    .eggs
show-source = true
ignore =
    D10  # ignore missing docstrings (for now)
    D202 # No blank lines allowed after function docstring
    W503 # Conflicts with new W504

[coverage:run]
omit =
    *pistol/tests*

[isort]
line_length = 79
multi_line_output = 3
indent='    '
include_trailing_comma = True
use_parentheses = True

I'm happy to provide more info if necessary, and apologies if I'm doing something stupid/missed something obvious!

Bump Jinja2 to allow for Jinja2 3.x

We have projects that depend on Jinja that also use this project and we are planning on using 3.x. It's a mess.. I know..

Please review new Jinja2 3.x for inclusion into this project. Alternatively I can help provide patching to remove Jinja2 from this project or possibly set Jinja2 as an extra dep since it is not required.

"pip wheel" does not see poetry-dynamic-versioning

Hi,
I'm trying to put things together and check how pyproject can be really help us.

I might be completely wrong here, and happy to be corrected:

when I run pip wheel --use-pep517 . on a project with pyproject.toml which defines a non setuptools build-backend (e.g. it uses poetry), then the building machine trigger by pip will delegate the building to the specified modules, via the entry point.

given that, I expect when I run the command, that also poetry-dynamic-versioning is triggered, the same way it is when I use 'poetry build'.

while when i use pip, the produced wheel packge has the version specified in the toml file, not the version computed by the dynamic plugin (which works fine if triggered by poetry)

poetry API is called as expected.

Support for branch name

Not really an issue, but is there support for a branch name in the pattern?

For example:

In my feature branch, it would build like this:
v1.0.0.my-branch

After merging to develop, it would build like this:
v1.0.0.develop

After merging to master, it would build like this, dropping the suffix:
v1.0.0

Where v1.0.0 could be set in the toml file, and the branch name would overwrite.

Any thoughts?

Error when using poetry 1.1.0b2

I am trying to install poetry 1.1.0b2 with poetry-dynamic-versioning 0.8.3 in tox, but these do not seem to be compatible:

tox.ini:

[tox]
minversion = 3.19.0
isolated_build = true

[base]
description = Base configuration, to be used for all testsenvs
allowlist_externals = poetry
setenv =
    LANG = en_US.UTF-8

[testenv:poetry]
description = Poetry installation for Tox (also executed in CI).
skip_install = true
setenv = {[base]setenv}
deps =
    poetry==1.1.0b2
    poetry-dynamic-versioning==0.8.3
commands =
    poetry --version

pyproject.toml:

[tool.poetry]
name = "redacted"
version = "0.0.0"
authors = ["Redacted <[email protected]>"]
description = "Redacted"

[tool.poetry.dependencies]
python = "^3.6"

[tool.poetry.dev-dependencies]
black = "^20.8b1"

[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
pattern  = "^(?P<base>\\d+\\.\\d+\\.\\d+)(-?((?P<stage>[a-zA-Z]+)\\.?(?P<revision>\\d+)?))?"
format-jinja = """
    {%- if distance == 0 -%}
        {{- base -}}
    {%- else -%}
        {{- bump_version(base, 2) }}.dev{{ distance - 1 }}+g{{ commit }}.d{{ datetime.now().strftime('%Y%m%d%H%M%S') -}}
    {%- endif -%}
"""
format-jinja-imports = [
    { module = "datetime", item = "datetime" }
]

[build-system]
requires = ["poetry-core>=1.0.0a9"]
build-backend = "poetry.core.masonry.api"

command:

$ tox -e poetry
poetry recreate: /home/fredrik/code/repos/REDACTED/.tox/poetry
poetry installdeps: poetry==1.1.0b2, poetry-dynamic-versioning==0.8.3
poetry installed: appdirs==1.4.4,CacheControl==0.12.6,cachy==0.3.0,certifi==2020.6.20,cffi==1.14.2,chardet==3.0.4,cleo==0.8.1,clikit==0.6.2,crashtest==0.3.1,cryptography==3.1,distlib==0.3.1,dunamai==1.3.0,filelock==3.0.12,html5lib==1.1,idna==2.10,importlib-metadata==1.7.0,jeepney==0.4.3,Jinja2==2.11.2,keyring==21.4.0,lockfile==0.12.2,MarkupSafe==1.1.1,msgpack==1.0.0,packaging==20.4,pastel==0.2.0,pexpect==4.8.0,pkginfo==1.5.0.1,poetry==1.1.0b2,poetry-core==1.0.0a9,poetry-dynamic-versioning==0.8.3,ptyprocess==0.6.0,pycparser==2.20,pylev==1.3.0,pyparsing==2.4.7,requests==2.24.0,requests-toolbelt==0.8.0,SecretStorage==3.1.2,shellingham==1.3.2,six==1.15.0,tomlkit==0.5.11,urllib3==1.25.10,virtualenv==20.0.31,webencodings==0.5.1,zipp==3.1.0
poetry run-test-pre: PYTHONHASHSEED='852148349'
poetry run-test: commands[0] | poetry --version
Traceback (most recent call last):
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/bin/poetry", line 5, in <module>
    from poetry.console import main
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry_dynamic_versioning/__init__.py", line 276, in alt_import
    module = _state.original_import_func(name, globals, locals, fromlist, level)
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry/console/__init__.py", line 1, in <module>
    from .application import Application
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry_dynamic_versioning/__init__.py", line 276, in alt_import
    module = _state.original_import_func(name, globals, locals, fromlist, level)
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry/console/application.py", line 7, in <module>
    from .commands.about import AboutCommand
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry_dynamic_versioning/__init__.py", line 276, in alt_import
    module = _state.original_import_func(name, globals, locals, fromlist, level)
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry/console/commands/__init__.py", line 4, in <module>
    from .check import CheckCommand
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry_dynamic_versioning/__init__.py", line 276, in alt_import
    module = _state.original_import_func(name, globals, locals, fromlist, level)
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry/console/commands/check.py", line 1, in <module>
    from poetry.factory import Factory
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry_dynamic_versioning/__init__.py", line 280, in alt_import
    _patch_poetry_create(module)
  File "/home/fredrik/code/repos/REDACTED/.tox/poetry/lib/python3.7/site-packages/poetry_dynamic_versioning/__init__.py", line 213, in _patch_poetry_create
    "poetry.semver.version", fromlist=["Version"]
ModuleNotFoundError: No module named 'poetry.semver'
ERROR: InvocationError for command /home/fredrik/code/repos/REDACTED/.tox/poetry/bin/poetry --version (exited with code 1)

No module named 'jinja2'

I am running latest ArchLinux. Installing poetry-dynamic-versioning with pip install installs it to the ~/.local/lib/python3.8/site-packages/poetry_dynamic_versioning directory:

─╼ pip install poetry-dynamic-versioning                                                                                                                                                                                               
Defaulting to user installation because normal site-packages is not writeable
Collecting poetry-dynamic-versioning
  Using cached poetry_dynamic_versioning-0.7.0-py3-none-any.whl (9.6 kB)
Requirement already satisfied: jinja2<3.0.0,>=2.11.1 in /usr/lib/python3.8/site-packages (from poetry-dynamic-versioning) (2.11.2)
Requirement already satisfied: dunamai<2.0,>=1.1 in /home/martynas/.local/lib/python3.8/site-packages (from poetry-dynamic-versioning) (1.1.0)
Requirement already satisfied: tomlkit>=0.4 in /usr/lib/python3.8/site-packages (from poetry-dynamic-versioning) (0.6.0)
Requirement already satisfied: MarkupSafe>=0.23 in /usr/lib/python3.8/site-packages (from jinja2<3.0.0,>=2.11.1->poetry-dynamic-versioning) (1.1.1)
Installing collected packages: poetry-dynamic-versioning
Successfully installed poetry-dynamic-versioning-0.7.0

However then when running poetry build in a poetry project directory I get the following error:

─╼ poetry build                                                                                                                                                                                                                        
Error processing line 1 of /home/martynas/.local/lib/python3.8/site-packages/zzz_poetry_dynamic_versioning.pth:

  Traceback (most recent call last):
    File "/usr/lib/python3.8/site.py", line 169, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "/home/martynas/.local/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 7, in <module>
      import jinja2
  ModuleNotFoundError: No module named 'jinja2'

Remainder of file ignored

But jinja2 is available in system-wide packages: /usr/lib/python3.8/site-packages

PEP 517 clarification

The README says

Include the plugin in the build-system section of pyproject.toml for interoperability with PEP 517 build frontends.

I did that, but then installing the created source distribution poetry build -f sdist with Pip fails, because Pip tries to first build the wheel, so it installs all build dependencies, and this then crashes with

RuntimeError: Unable to detect version control system.

When I don't include the plugin in the build-system dependencies, then everything actually works just fine. Am I missing something?

Doesn't work with `pip` when pyproject.toml is in a repository subdirectory

$ pip3 install . --user --force
Processing /Projects/test/src
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... error
    ERROR: Command errored out with exit status 1:
     command: /Library/Developer/CommandLineTools/usr/bin/python3 /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py prepare_metadata_for_build_wheel /var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/tmpndenwgx6
         cwd: /private/var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/pip-req-build-5hg4fjfe
    Complete output (22 lines):
    Traceback (most recent call last):
      File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py", line 207, in <module>
        main()
      File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py", line 197, in main
        json_out['return_val'] = hook(**hook_input['kwargs'])
      File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py", line 69, in prepare_metadata_for_build_wheel
        return hook(metadata_directory, config_settings)
      File "/private/var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/pip-build-env-m9lmbts8/overlay/lib/python3.8/site-packages/poetry/core/masonry/api.py", line 43, in prepare_metadata_for_build_wheel
        poetry = Factory().create_poetry(Path(".").resolve(), with_dev=False)
      File "/private/var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/pip-build-env-m9lmbts8/overlay/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 353, in alt_poetry_create
        _state.project(name).version = _get_version(config)
      File "/private/var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/pip-build-env-m9lmbts8/overlay/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 169, in _get_version
        version = Version.from_vcs(
      File "/private/var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/pip-build-env-m9lmbts8/overlay/lib/python3.8/site-packages/dunamai/__init__.py", line 890, in from_vcs
        return cls._do_vcs_callback(vcs, pattern, latest_tag, tag_dir)
      File "/private/var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/pip-build-env-m9lmbts8/overlay/lib/python3.8/site-packages/dunamai/__init__.py", line 906, in _do_vcs_callback
        return mapping[vcs](**kwargs)
      File "/private/var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/pip-build-env-m9lmbts8/overlay/lib/python3.8/site-packages/dunamai/__init__.py", line 485, in from_git
        _detect_vcs(Vcs.Git)
      File "/private/var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/pip-build-env-m9lmbts8/overlay/lib/python3.8/site-packages/dunamai/__init__.py", line 175, in _detect_vcs
        raise RuntimeError(
    RuntimeError: This does not appear to be a Git project
    ----------------------------------------
ERROR: Command errored out with exit status 1: /Library/Developer/CommandLineTools/usr/bin/python3 /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py prepare_metadata_for_build_wheel /var/folders/9d/w12tylk1403bjxd6k93pdqp80000gn/T/tmpndenwgx6 Check the logs for full command output.

Is it possible to choose the behavior when not installed?

Currently, if poetry-dynamic-versioning isn't installed on a system, the version doesn't change from 0.0.0.

I can't immediately see how PEP 518 handles the case when something in requires isn't present.

Is it possible to elect to raise an error? Or even install poetry-dynamic-versioning?

Installing with --no-root still requires vcs

We install dependencies in a docker build step prior to installing the python package. This allows docker to cache the dependency installations, which is useful given their cost and frequency of change.

I've tried using --no-root to ensure only the dependencies are installed, and hoping the .git path wouldn't be required by poetry-dynamic-versioning. But it still seems to raise an error:

Step 17/22 : RUN poetry config virtualenvs.create false     && poetry config experimental.new-installer false     && poetry install --no-root --no-interaction --no-ansi     && poetry check
 ---> Running in 2cf1426e52dd

  RuntimeError

  Unable to detect version control system.

  at /usr/local/lib/python3.8/site-packages/dunamai/__init__.py:145 in _detect_vcs
      141│             if shutil.which(command.split()[0]):
      142│                 code, _ = _run_cmd(command, codes=[])
      143│                 if code == 0:
      144│                     return vcs
    → 145│         raise RuntimeError("Unable to detect version control system.")
      146│
      147│
      148│ @total_ordering
      149│ class Version:
The command '/bin/sh -c poetry config virtualenvs.create false     && poetry config experimental.new-installer false     && poetry install --no-root --no-interaction --no-ansi     && poetry check' returned a non-zero code: 1

Does it actually work? ValueError: pattern did not match any tags

Hello

Thank you for making this package.

I am working in project that requires scm versioning, and we decided to use Poetry, however I wasn't able to set it up with your package. There is nothing going on here, so maybe I am naive by making this post, but still I decided to give it a shot.

I got this error(after running poetry check or poetry shell):


[ValueError]
Pattern 'v(?P<base>\d+\.\d+\.\d+)((?P<pre_type>[a-zA-Z]+)(?P<pre_number>\d+))?' did not match any tags

I set the code up just like in the documentation, I also check if the tags are actually there (by running git tag command).


[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"

I am using Poetry version 1.0.0b1 (the prerelease one). I installed your package both in my global python and inside the poetry shell.

Best regards

feature: write __version__.py automatically

Dear Matthew,

thanks a lot for poetry-dynamic-versioning. It is great!

Additionally it would be interesting if poetry could write the file

    <package>/__version__.py

automatically and fill it with the dynamic version number string.

This feature could be implemented with just three lines at the end of _get_version():

    if config["versionfile"]:
        version_file = pyproject_path.parent / pyproject["tool"]["poetry"]["name"] / "__version__.py"
        version_file.write_text(_VERSION_FILE_TEMPLATE.format(serialized))

Would you consider a pull request?

Best regards
Lars

Running poetry shell writes version information

The library is working really well — thanks again.

One issue we've been having recently is when running poetry shell, the __version__ gets written and not reverted. So on a clean repo, running poetry shell generates this diff:

diff --git a/foo/__init__.py b/foo/__init__.py
index 3c2d2ec..cca5dcb 100644
--- a/foo/__init__.py
+++ b/foo/__init__.py
@@ -7,7 +7,7 @@

 # Placeholder as specified in
 # https://github.com/mtkennerly/poetry-dynamic-versioning#installation
-__version__ = "0.0.0"
+__version__ = "0.2.1.post23.dev0+a5da3b3"

 import logging

diff --git a/pyproject.toml b/pyproject.toml
index ed9fbca..5af214a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "poetry.masonry.api"

 [tool.poetry]
 name = "foo"
-version = "0.2.0"
+version = "0.2.1.post23.dev0+a5da3b3"

Is there something I'm doing wrong?

Is the `version` needed in pyproject.toml?

I am trying poetry-dynamic-versioning on MacOS and I have successfully installed it.

I am able to run the CLI tool and I get the expected output:

─╼ poetry-dynamic-versioning
Version: 0.1.4-post.4+6f0ae10
Files with substitutions: none

But if I run poetry build I see the output with the version set in pyproject.toml:

─╼ poetry build
Building project (0.0.0)
 - Building sdist
 - Built project-0.0.0.tar.gz

 - Building wheel
 - Built project-0.0.0-py3-none-any.whl

But If I remove version from pyproject.toml then I get the following:

─╼ poetry build
[RuntimeError]
The Poetry configuration is invalid:
  - 'version' is a required property

pip sees correct version number but `__version__` is not substituted on `poetry install`

Hi

When I use poetry install to work on my package, pip list shows my package with the correct version number, but the __version__ variable is not set, although I have the following lines in my pyproject.toml.

 [tool.poetry-dynamic-versioning.substitution]
 files = ["packagename/__init__.py"]

When I create a wheel with poetry build the substitution is performed as expected.

Is this intended behaviour, that the defined substitutions are not performed when using poetry install although the correct version number is visible for pip, or is it a bug?

poetry-dynamic-versioning doesn't work properly with the Python user install directory

poetry-dynamic-versioning doesn't seem to work properly when installed in the Python user install directory ($HOME/.local by default on Linux). Packages get installed in this folder when installing with pip --user (see the documentation)

The issue can be reproduced with the official python:3.8 docker image:

$ docker run -it python:3.8 /bin/bash
root@1924046cfe65:/# export PATH=$HOME/.local/bin:$PATH
root@1924046cfe65:/# pip install --user poetry
Collecting poetry
  Downloading poetry-1.1.5-py2.py3-none-any.whl (171 kB)
[snip...]

root@1924046cfe65:/# poetry --version
Poetry version 1.1.5
root@1924046cfe65:/# pip install --user poetry-dynamic-versioning
Collecting poetry-dynamic-versioning
  Downloading poetry_dynamic_versioning-0.12.4-py3-none-any.whl (12 kB)
[snip...]

root@1924046cfe65:/# poetry --version
Error processing line 1 of /root/.local/lib/python3.8/site-packages/zzz_poetry_dynamic_versioning.pth:

  Traceback (most recent call last):
    File "/usr/local/lib/python3.8/site.py", line 169, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "/root/.local/lib/python3.8/site-packages/poetry_dynamic_versioning/__init__.py", line 15, in <module>
      from dunamai import (
    File "/root/.local/lib/python3.8/site-packages/dunamai/__init__.py", line 4, in <module>
      import pkg_resources
  ModuleNotFoundError: No module named 'pkg_resources'

Remainder of file ignored
Poetry version 1.1.5

When installing the packages without the --user pip flag, it works properly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.