File: __main__.py

package info (click to toggle)
git-ubuntu 1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,688 kB
  • sloc: python: 13,378; sh: 480; makefile: 2
file content (276 lines) | stat: -rw-r--r-- 9,555 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#!/usr/bin/env python3

from collections import namedtuple
import logging
import sys

import pkg_resources

TopLevelDefaults = namedtuple(
    'TopLevelDefaults',
    [
        'verbose',
        'retries',
        'retry_backoffs',
        'proto',
        'parentfile',
        'pullfile',
        'changelog_date_override_file',
    ],
)
top_level_defaults = TopLevelDefaults(
    verbose=False,
    retries=5,
    retry_backoffs = [2 ** i for i in range(5)],
    proto='https',
    parentfile=pkg_resources.resource_filename(
        'gitubuntu',
        'parent_overrides.txt',
    ),
    pullfile=pkg_resources.resource_filename(
        'gitubuntu',
        'pull_overrides.txt',
    ),
    changelog_date_override_file=pkg_resources.resource_filename(
        'gitubuntu',
        'changelog_date_overrides.txt',
    ),
)

epilog_text = """
For more information on the commands see:

  $ git ubuntu <command> --help
  $ man git-ubuntu-<command>

More information about git ubuntu itself is available at:

  $ man git-ubuntu

See also:

  https://wiki.ubuntu.com/UbuntuDevelopment/Merging/GitWorkflow
"""

def main():
    try:
        import argparse
        from importlib import import_module
        from os import isatty
        import shutil
        from subprocess import CalledProcessError
        import textwrap
        from gitubuntu.run import run

        import argcomplete

        logging.getLogger('keyring').setLevel(logging.WARNING)

        known_subcommands = {
            'import': 'gitubuntu.importer',
            'importer-service-broker': 'gitubuntu.importer_service_broker',
            'importer-service-poller': 'gitubuntu.importer_service_poller',
            'importer-service-worker': 'gitubuntu.importer_service_worker',
            'merge': 'gitubuntu.merge',
            'clone': 'gitubuntu.clone',
            'tag': 'gitubuntu.tag',
            'queue': 'gitubuntu.queue',
            'remote': 'gitubuntu.remote',
            'submit': 'gitubuntu.submit',
            'export-orig': 'gitubuntu.exportorig',
            'prepare-upload': 'gitubuntu.prepare_upload',
        }

        known_network_subcommands = {
            'import',
            'clone',
            'export-orig',
            'queue',
            'remote',
            'submit',
        }

        parser = argparse.ArgumentParser(
            description='A git-based Ubuntu package maintenance system',
            formatter_class=argparse.RawTextHelpFormatter,
            epilog='',
        )
        subparsers = parser.add_subparsers(
            dest='subcommand',
            help='See below',
            metavar='<command>',
        )
        # This help ends up not being very useful to the end user
        # subparsers.required = True

        # common flags to all subcommands
        base_subparser = argparse.ArgumentParser(add_help=False)
        base_subparser.add_argument(
            '-v', '--verbose',
            action='store_true',
            help="Increase verbosity",
            default=top_level_defaults.verbose,
        )
        network_base_subparser = argparse.ArgumentParser(add_help=False)
        network_base_subparser.add_argument(
            '--retries',
            type=int,
            help="Number of times to attempt to retry downloading from "
                 "Launchpad.",
            default=top_level_defaults.retries,
        )
        network_base_subparser.add_argument(
            '--retry-backoffs',
            type=lambda s : [int(item) for item in s.split(',')],
            help="Comma-separated list of backoffs in seconds to use "
                "between each retry attempt. Default is exponential "
                "backoff.",
            default=argparse.SUPPRESS,
        )
        known_protos = ['git', 'http', 'https', 'git+ssh']
        network_base_subparser.add_argument(
            '--proto',
            metavar='[%s]' % '|'.join(known_protos),
            choices=known_protos,
            help="Specify protocol to use for fetch. Default: %(default)s",
            default=top_level_defaults.proto,
        )

        # Deprecated commands
        subparsers.add_parser("build")
        subparsers.add_parser("build-source")
        subparsers.add_parser("import-local")
        subparsers.add_parser("import-ppa")
        subparsers.add_parser("lint")
        subparsers.add_parser("review")

        width, _ = shutil.get_terminal_size()
        subhelp_width = width - 4
        subcommand_text = 'Commands:\n'
        for sub in sorted(known_subcommands):
            m = import_module(known_subcommands[sub])
            if sub in known_network_subcommands:
                help_text = m.parse_args(
                    subparsers,
                    [base_subparser, network_base_subparser],
                )
            else:
                help_text = m.parse_args(subparsers, [base_subparser])
            if sub in known_subcommands:
                subcommand_text += '\n'
                subcommand_text += '\n'.join(
                    textwrap.wrap(
                        help_text,
                        subhelp_width,
                        break_on_hyphens=False,
                        initial_indent='  ',
                        subsequent_indent='    ',
                    )
                )
        parser.add_argument(
            '-P', '--parentfile',
            type=str,
            help=argparse.SUPPRESS,
            default=top_level_defaults.parentfile,
        )
        parser.add_argument(
            '-L', '--pullfile',
            type=str,
            help=argparse.SUPPRESS,
            default=top_level_defaults.pullfile,
        )
        parser.add_argument(
            '--changelog-date-override-file',
            type=str,
            help=argparse.SUPPRESS,
            default=top_level_defaults.changelog_date_override_file,
        )
        parser.epilog = subcommand_text + "\n" + epilog_text

        argcomplete.autocomplete(parser)
        args = parser.parse_args()
        if 'subcommand' not in args or args.subcommand is None:
            parser.print_help()
            sys.exit(1)
        elif args.subcommand == 'build':
            sys.stderr.write('"build" is no longer available\n')
            sys.exit(1)
        elif args.subcommand == 'build-source':
            sys.stderr.write('"build-source" is no longer available\n')
            sys.exit(1)
        elif args.subcommand == 'import-local':
            sys.stderr.write('"import-local" is not currently available, please use "bin/git-dsc-commit" from the source tree instead\n')
            sys.exit(1)
        elif args.subcommand == 'import-ppa':
            sys.stderr.write('"import-ppa" is not currently available, please use "bin/git-dsc-commit" from the source tree instead\n')
            sys.exit(1)
        elif args.subcommand == 'lint':
            sys.stderr.write('"lint" is not currently available\n')
            sys.exit(1)
        elif args.subcommand == 'review':
            sys.stderr.write('"review" is not currently available\n')
            sys.exit(1)

        # fragile, assumes developers will pass the base_subparser above
        # should make this structural in the classes
        if args.verbose:
            level=logging.DEBUG
        else:
            level=logging.INFO
        logging.basicConfig(
            level=level,
            format='%(asctime)s - %(levelname)s:%(message)s',
            datefmt='%m/%d/%Y %H:%M:%S',
        )
        if args.subcommand in known_network_subcommands:
            try:
                retry_backoffs = args.retry_backoffs
                if len(retry_backoffs) != args.retries:
                    logging.error(
                        "Number of backoffs specified in "
                        "--retry-backoffs must match --retries."
                    )
                    sys.exit(1)
            except AttributeError:
                args.retry_backoffs = [2 ** i for i in range(args.retries)]

        try:
            run(
                ['git', 'config', 'gitubuntu.lpuser'],
                verbose_on_failure=False,
            )
        except CalledProcessError:
            if isatty(sys.stdin.fileno()):
                user = input(
                    "gitubuntu.lpuser is not set. What is your "
                    "Launchpad username? We will set this in your "
                    "personally global git configuration for you. "
                    "To abort, press Enter.\nUsername: "
                )
                if len(user) == 0:
                    logging.error("git-ubuntu requires a launchpad user")
                    sys.exit(1)
                else:
                    logging.warning(
                        "Setting the Launchpad user for git-ubuntu to %s "
                        "with `git config --global gitubuntu.lpuser %s`.",
                        user,
                        user,
                    )
                    run(['git', 'config', '--global', 'gitubuntu.lpuser', user])
            else:
                logging.error(
                    "Not connected to a TTY and no git-ubuntu lpuser "
                    "defined. Please run `git config --global "
                    "gitubuntu.lpuser <Launchpad username>` and re-run "
                    "this command."
                )
                sys.exit(1)

        sys.exit(args.func(args))
    except KeyboardInterrupt:
        sys.stderr.write('User abort\n')
        sys.exit(130)

if __name__ == '__main__':
    main()