File: clone.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 (175 lines) | stat: -rw-r--r-- 4,907 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
import argparse
import logging
import os
import re
import shutil
from subprocess import CalledProcessError
import sys
from gitubuntu.__main__ import top_level_defaults
from gitubuntu.git_repository import (
    GitUbuntuRepository,
    GitUbuntuRepositoryFetchError,
)
from gitubuntu.run import decode_binary, run

import pkg_resources
import pygit2

def copy_hooks(src, dst):
    try:
        os.mkdir(dst)
    except FileExistsError:
        pass

    for hook in os.listdir(src):
        shutil.copy2(
            os.path.join(src, hook),
            dst,
        )

def main(
    package,
    directory=None,
    lp_user=None,
    proto=top_level_defaults.proto,
):
    """Entry point to clone subcommand

    @package: Name of source package
    @directory: directory to clone the repository into
    @lp_user: user to authenticate to Launchpad as
    @proto: string protocol to use (one of 'http', 'https', 'git')

    If directory is None, a relative directory with the same name as
    package will be used.

    If lp_user is None, value of `git config gitubuntu.lpuser` will be
    used.

    Returns the resulting GitUbuntuRepository object, if successful;
    None otherwise.
    """
    directory = (
        os.path.abspath(directory)
        if directory
        else os.path.join(os.path.abspath(os.getcwd()), package)
    )
    if os.path.isdir(directory):
        logging.error('directory %s exists' % directory)
        return None

    local_repo = GitUbuntuRepository(
        local_dir=directory,
        lp_user=lp_user,
        fetch_proto=proto,
    )

    copy_hooks(
        pkg_resources.resource_filename(
           'gitubuntu',
           'hooks',
        ),
        os.path.join(
            directory,
            os.getenv('GIT_DIR', '.git'),
            'hooks',
        ),
    )

    local_repo.add_base_remotes(package)
    try:
        local_repo.fetch_base_remotes(verbose=True)
    except GitUbuntuRepositoryFetchError:
        logging.error("Unable to find an imported repository for %s. "
            "Please request an import by e-mailing "
            "ubuntu-distributed-devel@lists.ubuntu.com.",
            package
        )
        shutil.rmtree(local_repo.local_dir)
        return None

    local_repo.add_lpuser_remote(pkgname=package)
    logging.debug("added remote '%s' -> %s", local_repo.lp_user,
        local_repo.raw_repo.remotes[local_repo.lp_user].url
    )
    try:
        local_repo.fetch_lpuser_remote(verbose=True)
    except GitUbuntuRepositoryFetchError:
        pass

    try:
        local_repo.create_tracking_branch(
            'ubuntu/devel',
            'pkg/ubuntu/devel'
        )
        local_repo.checkout_commitish('ubuntu/devel')
    except:
        logging.error('Unable to checkout ubuntu/devel, does '
            'pkg/ubuntu/devel branch exist?'
        )

    local_repo.git_run(['config', 'notes.displayRef', 'refs/notes/changelog'])

    if os.path.isfile(os.path.join(directory, '.gitignore')):
        logging.warning('A .gitignore file exists in the source '
            'package. This will affect the behavior of git. Consider '
            'backing up the gitignore while working on this package '
            'to ensure all changes are tracked or passing appropriate '
            'flags to git commands (e.g., git status --ignored).'
        )

    return local_repo

def parse_args(subparsers=None, base_subparsers=None):
    kwargs = dict(
        description='Clone a source package git repository to a directory',
        formatter_class=argparse.RawTextHelpFormatter,
        epilog='''
Example:
   * clone to open-iscsi/
     %(prog)s open-iscsi
   * clone to ubuntu.git
     %(prog)s open-iscsi ubuntu.git
   * use git rather than https protocol for remotes:
     %(prog)s --proto=git open-iscsi
'''
                 )
    if base_subparsers:
        kwargs['parents'] = base_subparsers
    if subparsers:
        parser = subparsers.add_parser('clone', **kwargs)
        parser.set_defaults(func=cli_main)
    else:
        parser = argparse.ArgumentParser(**kwargs)
    parser.add_argument('package', type=str,
        help='Name of source package to clone'
    )
    parser.add_argument('directory', type=str,
        help='Local directory to clone to. If not specified, a '
             ' directory with the same name as PACKAGE will be '
             'used',
        default=None,
        nargs='?'
    )
    parser.add_argument('-l', '--lp-user', type=str, help=argparse.SUPPRESS)
    if not subparsers:
        return parser.parse_args()
    return 'clone - %s' % kwargs['description']

def cli_main(args):
    try:
        lp_user = args.lp_user
    except AttributeError:
        lp_user = None

    if main(
        package=args.package,
        directory=args.directory,
        lp_user=lp_user,
        proto=args.proto,
    ) is not None:
        return 0
    return 1


# vi: ts=4 expandtab