Completed
Pull Request — master (#122)
by Michael
06:12 queued 05:39
created

stage()   F

Complexity

Conditions 12

Size

Total Lines 87

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 13.5797

Importance

Changes 8
Bugs 0 Features 0
Metric Value
cc 12
c 8
b 0
f 0
dl 0
loc 87
ccs 28
cts 36
cp 0.7778
crap 13.5797
rs 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like stage() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1 3
import difflib
0 ignored issues
show
Bug introduced by
There seems to be a cyclic import (changes -> changes.cli -> changes.commands.status).

Cyclic imports may cause partly loaded modules to be returned. This might lead to unexpected runtime behavior which is hard to debug.

Loading history...
Bug introduced by
There seems to be a cyclic import (changes -> changes.cli -> changes.commands.stage -> changes.config).

Cyclic imports may cause partly loaded modules to be returned. This might lead to unexpected runtime behavior which is hard to debug.

Loading history...
Bug introduced by
There seems to be a cyclic import (changes -> changes.cli -> changes.commands.stage).

Cyclic imports may cause partly loaded modules to be returned. This might lead to unexpected runtime behavior which is hard to debug.

Loading history...
Bug introduced by
There seems to be a cyclic import (changes -> changes.cli -> changes.commands.init -> changes.config).

Cyclic imports may cause partly loaded modules to be returned. This might lead to unexpected runtime behavior which is hard to debug.

Loading history...
Bug introduced by
There seems to be a cyclic import (changes -> changes.cli).

Cyclic imports may cause partly loaded modules to be returned. This might lead to unexpected runtime behavior which is hard to debug.

Loading history...
2 3
from datetime import date
3 3
from pathlib import Path
4
5 3
import bumpversion
0 ignored issues
show
Configuration introduced by
The import bumpversion could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
6 3
import click
0 ignored issues
show
Configuration introduced by
The import click could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
7 3
import pkg_resources
8 3
from jinja2 import Template
0 ignored issues
show
Configuration introduced by
The import jinja2 could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
9
10 3
import changes
11 3
from changes.config import BumpVersion
12 3
from changes.models import Release, changes_to_release_type
13 3
from . import info, error, note, debug, STYLES
14
15
16 3
def stage(draft, release_name='', release_description=''):
17
18 3
    repository = changes.project_settings.repository
19 3
    bumpversion_part, release_type, proposed_version = changes_to_release_type(repository)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (90/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
20
21 3
    if not repository.changes_since_last_version:
22
        error("There aren't any changes to release since {}".format(proposed_version))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (86/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
23
        return
24
25 3
    info('Staging [{}] release for version {}'.format(
26
        release_type,
27
        proposed_version
28
    ))
29
30 3
    if BumpVersion.read_from_file(Path('.bumpversion.cfg')).current_version == str(proposed_version):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (101/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
31
        info('Version already bumped to {}'.format(proposed_version))
32
    else:
33 3
        bumpversion_arguments = (
34
            BumpVersion.DRAFT_OPTIONS if draft
35
            else BumpVersion.STAGE_OPTIONS
36
        )
37 3
        bumpversion_arguments += [bumpversion_part]
38
39 3
        info('Running: bumpversion {}'.format(
40
            ' '.join(bumpversion_arguments)
41
        ))
42 3
        bumpversion.main(bumpversion_arguments)
43
44 3
    info('Generating Release')
45
    # prepare context for changelog documentation
46 3
    project_labels = changes.project_settings.labels
47 3
    for label, properties in project_labels.items():
48 3
        pull_requests_with_label = [
49
            pull_request
50
            for pull_request in repository.changes_since_last_version
51
            if label in pull_request.labels
52
        ]
53
54 3
        project_labels[label]['pull_requests'] = pull_requests_with_label
55
56 3
    release = Release(
57
        name=release_name,
58
        release_date=date.today().isoformat(),
59
        version=str(proposed_version),
60
        description=release_description,
61
        changes=project_labels,
62
    )
63
64
    # TODO: if project_settings.release_notes_template is None
65 3
    release_notes_template = pkg_resources.resource_string(
66
        changes.__name__,
67
        'templates/release_notes_template.md'
68
    ).decode('utf8')
69
70 3
    release_notes = Template(release_notes_template).render(release=release)
71
72 3
    releases_directory = Path(changes.project_settings.releases_directory)
73 3
    if not releases_directory.exists():
74 3
        releases_directory.mkdir(parents=True)
75
76 3
    release_notes_path = releases_directory.joinpath(
77
        '{}.md'.format(release.version)
78
    )
79
80 3
    if draft:
81 3
        info('Would have created {}:'.format(release_notes_path))
82 3
        debug(release_notes)
83
    else:
84 3
        info('Writing release notes to {}'.format(release_notes_path))
85 3
        if release_notes_path.exists():
0 ignored issues
show
Bug introduced by
The Instance of PurePath does not seem to have a member named exists.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
86
            release_notes_content = release_notes_path.read_text(encoding='utf-8')
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Bug introduced by
The Instance of PurePath does not seem to have a member named read_text.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
87
            if release_notes_content != release_notes:
88
                info('\n'.join(difflib.unified_diff(
89
                    release_notes_content.splitlines(),
90
                    release_notes.splitlines(),
91
                    fromfile=str(release_notes_path),
92
                    tofile=str(release_notes_path)
93
                )))
94
                if click.confirm(
95
                        click.style(
96
                            '{} has modified content, overwrite?'.format(release_notes_path),
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (93/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
97
                            **STYLES['error']
98
                        )
99
                ):
100
                    release_notes_path.write_text(release_notes, encoding='utf-8')
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Bug introduced by
The Instance of PurePath does not seem to have a member named write_text.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
101
        else:
102
            release_notes_path.write_text(release_notes, encoding='utf-8')
0 ignored issues
show
Bug introduced by
The Instance of PurePath does not seem to have a member named write_text.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
103