pybuilder / pybuilder

Software build automation tool for Python.
https://pybuilder.io
Apache License 2.0
1.72k stars 249 forks source link

`source_distribution_plugin` is ignoring the `project.name` set in `@init` #646

Open marekyggdrasil opened 5 years ago

marekyggdrasil commented 5 years ago

Hi everyone!

I just started learning to use pybuilder and while including it into one of my projects I noticed that regardless of setting project.name it keeps the distribution name with default name. I prepared the smallest example that demonstrates the issue.

Here is my build.py

from pybuilder.core import use_plugin, init, task, depends, after
from pybuilder.utils import apply_on_files, GlobExpression

use_plugin("python.core")
use_plugin("python.unittest")
use_plugin("python.install_dependencies")
use_plugin("python.flake8")
use_plugin("python.coverage")
use_plugin("python.distutils")

name = "unwanted-name"
version = "0.0.1"
default_task = ["check_project", "publish"]

@init
def set_properties(project):
    project.name = 'wanted-name'
    pass

@task
def check_project(project, logger):
    logger.info("Project name is set to " + project.name)

I run the task check_project which logs the project name, it will allow us to see that project name is set before source_distribution_plugin is creating the directory. The output is the following:

$ pyb -E envname
PyBuilder version 0.11.17
Build started at 2019-10-02 22:37:35
------------------------------------------------------------
[INFO]  Activated environments: envname
[INFO]  Building wanted-name version 0.0.1
[INFO]  Executing build in /Users/marek/Development/projectname/api
[INFO]  Going to execute tasks: check_project, publish
[INFO]  Project name is set to wanted-name
[INFO]  Running unit tests
[INFO]  Executing unit tests from Python modules in /Users/marek/Development/projectname/api/src/unittest/python
[INFO]  Executed 3 unit tests
[INFO]  All unit tests passed.
[INFO]  Building distribution in /Users/marek/Development/projectname/api/target/dist/unwanted-name-0.0.1
[INFO]  Copying scripts to /Users/marek/Development/projectname/api/target/dist/unwanted-name-0.0.1/scripts
[INFO]  Writing setup.py as /Users/marek/Development/projectname/api/target/dist/unwanted-name-0.0.1/setup.py
[INFO]  Collecting coverage information
[WARN]  coverage_branch_threshold_warn is 0 and branch coverage will not be checked
[WARN]  coverage_branch_partial_threshold_warn is 0 and partial branch coverage will not be checked
[INFO]  Running unit tests
[INFO]  Executing unit tests from Python modules in /Users/marek/Development/projectname/api/src/unittest/python
[INFO]  Executed 3 unit tests
[INFO]  All unit tests passed.
[WARN]  Module '__init__' was not imported by the covered tests
[INFO]  Overall coverage is 100%
[INFO]  Overall coverage branch coverage is 100%
[INFO]  Overall coverage partial branch coverage is 100%
[INFO]  Building binary distribution in /Users/marek/Development/projectname/api/target/dist/unwanted-name-0.0.1
------------------------------------------------------------
BUILD SUCCESSFUL
------------------------------------------------------------
Build Summary
             Project: wanted-name
             Version: 0.0.1
      Base directory: /Users/marek/Development/projectname/api
        Environments: envname
               Tasks: check_project [0 ms] prepare [539 ms] compile_sources [0 ms] run_unit_tests [40 ms] package [7 ms] run_integration_tests [0 ms] verify [940 ms] publish [1844 ms]
Build finished at 2019-10-02 22:37:38
Build took 3 seconds (3417 ms)

as you can see the line

[INFO]  Project name is set to wanted-name

is displayed before

[INFO]  Building distribution in /Users/marek/Development/projectname/api/target/dist/unwanted-name-0.0.1

and as you can see it is using the default name, not the project name I set inside of the @init.

I also tried to set the property dir_source_dist manually as in:

https://github.com/pybuilder/pybuilder/blob/772cf66a6fea86c59bd76f22388b0ce964b2fc1a/src/main/python/pybuilder/plugins/source_distribution_plugin.py#L29-L31

with no success.

My pybuilder version is

$ pip freeze | grep pybuilder
You are using pip version 10.0.1, however version 19.2.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
pybuilder==0.11.17

Am I doing something wrong or is it a bug?

arcivanov commented 5 years ago

What are you expecting setting project.name vs name in the build.py?

marekyggdrasil commented 5 years ago

@arcivanov I'm expecting project.name to be used for creating the distribution directory, not the name. I also tried to removing name variable, but then it still ignores project.name and starts using main directory name as name.

Source of source_distribution plugin suggests it should be project.name used for creating directory name.

https://github.com/pybuilder/pybuilder/blob/772cf66a6fea86c59bd76f22388b0ce964b2fc1a/src/main/python/pybuilder/plugins/source_distribution_plugin.py#L27-L41

marekyggdrasil commented 5 years ago

@arcivanov I think I know where the problem is

The directory path is set to DISTRIBUTION_PROPERTY in this task being part of @init of core plugin.

https://github.com/pybuilder/pybuilder/blob/64219f573b0086cc214813629ce54099c7702450/src/main/python/pybuilder/plugins/python/core_plugin.py#L40-L41

My guess is, when my task is run (which sets the project.name property the DISTRIBUTION_PROPERTY is already set. Is there a way to ensure my task is executed before the task @init of core plugin?

marekyggdrasil commented 5 years ago

I found the solution.

In order to make sure the distribution name follows the project name set in the initialisation task we need to use @before decorator to indicate for this task to be run before the package task. Then we need to update the project name and set the distribution property one more time.

from pybuilder.core import use_plugin, init, task, depends, before, after
from pybuilder.utils import apply_on_files, GlobExpression

use_plugin("python.core")
use_plugin("python.unittest")
use_plugin("python.install_dependencies")
use_plugin("python.flake8")
use_plugin("python.coverage")
use_plugin("python.distutils")

name = "unwanted-name"
version = "0.0.1"
default_task = ["check_project", "publish"]

DISTRIBUTION_PROPERTY = "dir_dist"

@init
@before("package")
def set_properties(project, logger):
    logger.info("Setting project name")
    project.name = 'wanted-name'
    project.set_property(DISTRIBUTION_PROPERTY,
                                  "$dir_target/dist/{0}-{1}".format(project.name, project.version))
    pass

@task
def check_project(project, logger):
    logger.info("Project name is set to " + project.name)

As you can see where previously we had unwanted-name now there is wanted-name including the distribution directory.

$ pyb -E envname
PyBuilder version 0.11.17
Build started at 2019-10-30 20:44:34
------------------------------------------------------------
[INFO]  Activated environments: envname
[INFO]  Building unwanted-name version 0.0.1
[INFO]  Executing build in /Users/marek/Development/projectname/api/
[INFO]  Going to execute tasks: check_project, publish
[INFO]  Project name is set to unwanted-name
[INFO]  Running unit tests
[INFO]  Executing unit tests from Python modules in /Users/marek/Development/projectname/api/src/unittest/python
[INFO]  Executed 3 unit tests
[INFO]  All unit tests passed.
[INFO]  Setting project name
[INFO]  Building distribution in /Users/marek/Development/projectname/api/target/dist/wanted-name-0.0.1
[INFO]  Copying scripts to /Users/marek/Development/projectname/api/target/dist/wanted-name-0.0.1/scripts
[INFO]  Writing setup.py as /Users/marek/Development/projectname/api/target/dist/wanted-name-0.0.1/setup.py
[INFO]  Collecting coverage information
[WARN]  coverage_branch_threshold_warn is 0 and branch coverage will not be checked
[WARN]  coverage_branch_partial_threshold_warn is 0 and partial branch coverage will not be checked
[INFO]  Running unit tests
[INFO]  Executing unit tests from Python modules in /Users/marek/Development/projectname/api/src/unittest/python
[INFO]  Executed 3 unit tests
[INFO]  All unit tests passed.
[WARN]  Module '__init__' was not imported by the covered tests
[INFO]  Overall coverage is 100%
[INFO]  Overall coverage branch coverage is 100%
[INFO]  Overall coverage partial branch coverage is 100%
[INFO]  Building binary distribution in /Users/marek/Development/projectname/api/target/dist/wanted-name-0.0.1
------------------------------------------------------------
BUILD SUCCESSFUL
------------------------------------------------------------
Build Summary
             Project: wanted-name
             Version: 0.0.1
      Base directory: /Users/marek/Development/projectname/api
        Environments: envname
               Tasks: check_project [0 ms] prepare [513 ms] compile_sources [0 ms] run_unit_tests [49 ms] package [12 ms] run_integration_tests [0 ms] verify [762 ms] publish [1401 ms]
Build finished at 2019-10-30 20:44:37
Build took 2 seconds (2793 ms)

The use of that is it allows you to change package name depending on environment or other parameters. That's exactly what I needed. Closing.

arcivanov commented 5 years ago

Thank you for finding a workaround. I'm reopening to investigate whether it's a documentation error or an implementation error.

marekyggdrasil commented 4 years ago

Sure thing @arcivanov, just let me know if you have questions or if I can be of any use. I may have not described perfectly what I needed.