python-poetry / poetry

Python packaging and dependency management made easy
https://python-poetry.org
MIT License
31.61k stars 2.26k forks source link

File created by custom build script is missing from the wheel #4174

Open mattdibi opened 3 years ago

mattdibi commented 3 years ago

Issue

When running poetry build for the first time the file (version.py) built by my custom build script (version_info.py) isn't added in the wheel sources resulting in a broken build.

Expected file tree:

project-name-0.0.0
├── project-name
│   └── version.py
├── PKG-INFO
├── pyproject.toml
├── setup.py
└── version_info.py

Actual file tree:

project-name-0.0.0
├── project-name
├── PKG-INFO
├── pyproject.toml
├── setup.py
└── version_info.py

If i run poetry build a second time the file is added to the wheel as expected.

project-name/version.py.in content

""" Netmanager version information module """

import pkg_resources

class Version():
    VERSION = pkg_resources.get_distribution('project-name').version
    MAJOR, MINOR, PATCH = VERSION.split(".", 3)

    BUILD_DATE     = "$date$"
    BUILD_TIME     = "$time$"
    GIT_SHA1       = "$git_sha1$"
    GIT_SHORT_SHA1 = "$git_short_sha1$"
    GIT_BRANCH     = "$git_branch$"

pyproject.toml content

[tool.poetry]
name = "project-name"
version = "0.0.0"
description = "My Project"
include = ["project-name/version.py"]
exclude = ["project-name/version.py.in"]

[tool.poetry.build]
script = "version_info.py"

[tool.poetry.dependencies]
...

[tool.poetry.dev-dependencies]
...

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

version_info.py content

import subprocess
import time

def get_git_revision_hash():
    return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode("utf-8")

def get_git_revision_short_hash():
    return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).strip().decode("utf-8")

def get_git_revision_branch():
    return subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip().decode("utf-8")

def get_build_date():
    timestr = time.gmtime()
    return time.strftime('%Y-%m-%d', timestr)

def get_build_time():
    timestr = time.gmtime()
    return time.strftime('%X', timestr)

def build(_):
    # Substitute target file content
    fin  = open("project-name/version.py.in", "rt")
    data = fin.read()
    fin.close()

    data = data.replace('$date$', get_build_date())
    data = data.replace('$time$', get_build_time())
    data = data.replace('$git_sha1$', get_git_revision_hash())
    data = data.replace('$git_short_sha1$', get_git_revision_short_hash())
    data = data.replace('$git_branch$', get_git_revision_branch())

    fout = open("project-name/version.py", "wt")
    fout.write(data)
    fout.close()

Am I missing something obvious?

danielloader commented 3 years ago

I was trying to do exactly what you were with some shell scripts, googled a more native solution - found this issue and it looked great until I realised it's not working. Subscribed anyway.