Completed
Push — pyup-update-plumbum-1.6.5-to-1... ( 484603 )
by Michael
61:06 queued 60:19
created

Config.__init__()   A

Complexity

Conditions 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
dl 0
loc 14
ccs 8
cts 8
cp 1
crap 2
rs 9.4285
1 3
import io
2 3
import os
3 3
from os.path import exists, expanduser, expandvars, join, curdir
4 3
from pathlib import Path
5
6 3
import attr
0 ignored issues
show
Configuration introduced by
The import attr 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 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...
8 3
import inflection
0 ignored issues
show
Configuration introduced by
The import inflection 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 3
import toml
0 ignored issues
show
Configuration introduced by
The import toml 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...
10
11 3
from changes.models import BumpVersion
12 3
from changes import prompt, compat
13 3
from .commands import info, note, debug
14
15 3
AUTH_TOKEN_ENVVAR = 'GITHUB_AUTH_TOKEN'
16
17
# via https://github.com/jakubroztocil/httpie/blob/6bdfc7a/httpie/config.py#L9
18 3
DEFAULT_CONFIG_FILE = str(os.environ.get(
19
    'CHANGES_CONFIG_FILE',
20
    expanduser('~/.changes') if not compat.IS_WINDOWS else
21
    expandvars(r'%APPDATA%\\.changes')
22
))
23
24 3
PROJECT_CONFIG_FILE = '.changes.toml'
25 3
DEFAULT_RELEASES_DIRECTORY = 'docs/releases'
26
27
28 3
@attr.s
29 3
class Changes(object):
30 3
    auth_token = attr.ib()
31
32 3
    @classmethod
33
    def load(cls):
34 3
        tool_config_path = Path(str(os.environ.get(
35
            'CHANGES_CONFIG_FILE',
36
            expanduser('~/.changes') if not compat.IS_WINDOWS else
37
            expandvars(r'%APPDATA%\\.changes')
38
        )))
39
40 3
        tool_settings = None
41 3
        if tool_config_path.exists():
42 3
            tool_settings = Changes(
43
                **(toml.load(tool_config_path.open())['changes'])
44
            )
45
46
        # envvar takes precedence over config file settings
47 3
        auth_token = os.environ.get(AUTH_TOKEN_ENVVAR)
48 3
        if auth_token:
49 3
            info('Found Github Auth Token in the environment')
50 3
            tool_settings = Changes(auth_token=auth_token)
51 3
        elif not (tool_settings and tool_settings.auth_token):
52 3
            while not auth_token:
53 3
                info('No auth token found, asking for it')
54
                # to interact with the Git*H*ub API
55 3
                note('You need a Github Auth Token for changes to create a release.')
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (85/79).

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

Loading history...
56 3
                click.pause('Press [enter] to launch the GitHub "New personal access '
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...
57
                            'token" page, to create a token for changes.')
58 3
                click.launch('https://github.com/settings/tokens/new')
59 3
                auth_token = click.prompt('Enter your changes token')
60
61 3
            if not tool_settings:
62 3
                tool_settings = Changes(auth_token=auth_token)
63
64 3
            tool_config_path.write_text(
0 ignored issues
show
Bug introduced by
The Instance of Path 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...
65
                toml.dumps({
66
                    'changes': attr.asdict(tool_settings)
67
                })
68
            )
69
70 3
        return tool_settings
71
72
73 3
@attr.s
74 3
class Project(object):
75 3
    releases_directory = attr.ib()
76 3
    repository = attr.ib(default=None)
77 3
    bumpversion = attr.ib(default=None)
78 3
    labels = attr.ib(default=attr.Factory(dict))
79
80 3
    @classmethod
81
    def load(cls, repository):
82 3
        changes_project_config_path = Path(PROJECT_CONFIG_FILE)
83 3
        project_settings = None
84
85 3
        if changes_project_config_path.exists():
86
            # releases_directory, labels
87 3
            project_settings = Project(
88
                **(toml.load(changes_project_config_path.open())['changes'])
89
            )
90
91 3
        if not project_settings:
92 3
            releases_directory = Path(click.prompt(
93
                'Enter the directory to store your releases notes',
94
                DEFAULT_RELEASES_DIRECTORY,
95
                type=click.Path(exists=True, dir_okay=True)
96
            ))
97
98 3
            if not releases_directory.exists():
99 3
                debug('Releases directory {} not found, creating it.'.format(
100
                    releases_directory))
101 3
                releases_directory.mkdir(parents=True)
102
103 3
            project_settings = Project(
104
                releases_directory=str(releases_directory),
105
                labels=configure_labels(repository.labels),
106
            )
107
            # write config file
108 3
            changes_project_config_path.write_text(
0 ignored issues
show
Bug introduced by
The Instance of Path 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...
109
                toml.dumps({
110
                    'changes': attr.asdict(project_settings)
111
                })
112
            )
113
114 3
        project_settings.repository = repository
115 3
        project_settings.bumpversion = BumpVersion.load(
116
            repository.latest_version)
117
118 3
        return project_settings
119
120
121 3
def configure_labels(github_labels):
122 3
    labels_keyed_by_name = {}
123 3
    for label in github_labels:
124 3
        labels_keyed_by_name[label['name']] = label
125
126
    # TODO: streamlined support for github defaults: enhancement, bug
127 3
    changelog_worthy_labels = prompt.choose_labels([
128
        properties['name']
129
        for _, properties in labels_keyed_by_name.items()
130
    ])
131
132
    # TODO: apply description transform in labels_prompt function
133 3
    described_labels = {}
134
    # auto-generate label descriptions
135 3
    for label_name in changelog_worthy_labels:
136 3
        label_properties = labels_keyed_by_name[label_name]
137
        # Auto-generate description as pluralised titlecase label name
138 3
        label_properties['description'] = inflection.pluralize(
139
            inflection.titleize(label_name)
140
        )
141
142 3
        described_labels[label_name] = label_properties
143
144 3
    return described_labels
145
146
147
# TODO: borg legacy
148 3
DEFAULTS = {
149
    'changelog': 'CHANGELOG.md',
150
    'readme': 'README.md',
151
    'github_auth_token': None,
152
}
153
154
155 3
class Config:
156
    """Deprecated"""
157 3
    test_command = None
158 3
    pypi = None
159 3
    skip_changelog = None
160 3
    changelog_content = None
161 3
    repo = None
162
163 3
    def __init__(self, module_name, dry_run, debug, no_input, requirements,
0 ignored issues
show
Comprehensibility Bug introduced by
debug is re-defining a name which is already available in the outer-scope (previously defined on line 13).

It is generally a bad practice to shadow variables from the outer-scope. In most cases, this is done unintentionally and might lead to unexpected behavior:

param = 5

class Foo:
    def __init__(self, param):   # "param" would be flagged here
        self.param = param
Loading history...
164
                 new_version, current_version, repo_url, version_prefix):
165 3
        self.module_name = module_name
166
        # module_name => project_name => curdir
167 3
        self.dry_run = dry_run
168 3
        self.debug = debug
169 3
        self.no_input = no_input
170 3
        self.requirements = requirements
171 3
        self.new_version = (
172
            version_prefix + new_version
173
            if version_prefix
174
            else new_version
175
        )
176 3
        self.current_version = current_version
177
178
179 3
def project_config():
180
    """Deprecated"""
181
    project_name = curdir
182
183
    config_path = Path(join(project_name, PROJECT_CONFIG_FILE))
184
185
    if not exists(config_path):
186
        store_settings(DEFAULTS.copy())
187
        return DEFAULTS
188
189
    return toml.load(io.open(config_path)) or {}
190
191
192 3
def store_settings(settings):
193
    pass
194