Ejemplo n.º 1
0
 def find_command(name, warn=False):
     path = which(name)
     if path:
         print style_note('%s:' % name, path)
     else:
         if warn:
             print style_warning('cannot find %s' % name)
         else:
             print style_error('cannot find %s' % name)
             return 1
Ejemplo n.º 2
0
def rm(args):
    res = 0
    con = args.assert_home().db.connect()
    for pattern in args.patterns:
        cur = con.execute('DELETE FROM development_packages WHERE name GLOB ?',
                          [pattern])
        if not cur.rowcount:
            print style_warning('No dev packages matching "%s"' % pattern)
            res = 1
    return res
Ejemplo n.º 3
0
def list_(args):
    home = args.assert_home()
    rows = list(home.db.execute('SELECT * FROM repositories'))
    if not rows:
        print style_warning('No repositories.')
        return
    max_len = max(len(row['name']) for row in rows)
    for row in rows:
        env_repo = EnvironmentRepo(row, home=home)
        if env_repo.exists:
            print style_note(
                env_repo.name,
                '%s/%s' % (env_repo.remote_name, env_repo.branch_name),
                env_repo.remotes().get(env_repo.remote_name, '') + 
                ' --default' if row['is_default'] else '',
            )
Ejemplo n.º 4
0
def summarize_rev_distance(
    local,
    remote,
    local_name='You',
    local_verb='are',
    remote_name='',
    fork_action='please rebase.',
    ahead_action='you may push.',
    behind_action='please pull.',
    indent='    ',
):
    if local and remote:
        print indent + style_warning(
            '%s and %s have forked%s' %
            (local_name, remote_name
             or 'the remote', '; ' + fork_action if fork_action else '.'))
        print indent + style_warning(
            'There are %d local commit%s, and %d remote commit%s.' % (
                local,
                's' if local > 1 else '',
                remote,
                's' if remote > 1 else '',
            ))
    elif local:
        print indent + style('%s %s ahead%s by %d commit%s%s' % (
            local_name,
            local_verb,
            ' of ' + remote_name if remote_name else '',
            local,
            's' if local > 1 else '',
            '; ' + ahead_action if ahead_action else '.',
        ),
                             fg='green',
                             reset=True)
    elif remote:
        print indent + style_warning('%s %s behind%s by %d commit%s%s' % (
            local_name,
            local_verb,
            ' ' + remote_name if remote_name else '',
            remote,
            's' if remote > 1 else '',
            '; ' + behind_action if behind_action else '.',
        ))
Ejemplo n.º 5
0
    def update(self, force=False):

        log.info(style_note('Updating repo', self.name))

        self.clone_if_not_exists()

        if self.remote_name not in self.remotes():
            log.warning(
                style_warning('"%s" does not have remote "%s"' %
                              (self.name, self.remote_name)))
            return True

        rev = self.fetch()

        if not force and not self.check_ff_safety(rev):
            log.error('Cannot fast-forward; skipping.')
            return False

        self.checkout(force=force)
        return True
Ejemplo n.º 6
0
    def upgrade(self,
                dirty=False,
                subset=None,
                reinstall=False,
                relink=False,
                no_deps=False,
                force_branch_link=True):

        self.clone_if_not_exists()

        try:
            head = self.head
        except CalledProcessError:
            log.warning(style_warning('no commits in repository'))
            head = None

        try:
            remote_head = self.rev_parse('%s/%s' %
                                         (self.remote_name, self.branch_name))
        except ValueError:
            log.warning(
                style_warning('tracked %s/%s does not exist in self' %
                              (self.remote_name, self.branch_name)))
            remote_head = None

        if remote_head and head != remote_head:
            log.warning(
                style_warning('%s repo not checked out to %s/%s' %
                              (self.name, self.remote_name, self.branch_name)))

        dirty = bool(list(self.status()))
        if not dirty and self.is_dirty():
            log.error('%s repo is dirty; force with --dirty' % self.name)
            return False

        env = self.get_environment()

        req_set = self.load_requirements()
        pkg_set = PackageSet(env=env, home=self.home)

        # Register the whole set, so that dependencies are pulled from here instead
        # of weakly resolved from installed packages.
        # TODO: This blanket reinstalls things, even if no_deps is set.
        pkg_set.resolve_set(req_set, check_existing=not reinstall)

        # Install and/or link.
        pkg_set.install(subset or None,
                        link_env=env,
                        reinstall=reinstall,
                        relink=relink,
                        no_deps=no_deps)

        if pkg_set._errored and not force_branch_link:
            log.warning(
                style_warning(
                    "Not creating branch or version links; force with --force-branch-link"
                ))
            return False

        # Create a symlink by branch.
        path_by_branch = self.home._abs_path('environments', self.name,
                                             self.branch_name)
        if os.path.lexists(path_by_branch):
            os.unlink(path_by_branch)
        makedirs(os.path.dirname(path_by_branch))
        os.symlink(env.path, path_by_branch)

        # Create a symlink by version.
        version = req_set.headers.get('Version')
        if version:
            path_by_version = self.home._abs_path(
                'environments', self.name, 'versions',
                version.value + ('-dirty' if dirty else ''))
            if os.path.lexists(path_by_version):
                os.unlink(path_by_version)
            makedirs(os.path.dirname(path_by_version))
            os.symlink(env.path, path_by_version)

        return True
Ejemplo n.º 7
0
def doctor(args):
    """Perform self-checks to make sure VEE is OK."""

    if args.ping:
        print 'pong'
        return

    import vee.__about__ as about

    if args.version:
        print about.__version__ + ('+' +
                                   about.__revision__ if args.revision else '')
        return
    if args.revision:
        print about.__revision__
        return

    print style_note('==> VEE')
    print style_note('version:', about.__version__)
    print style_note('revision:', about.__revision__)
    print style_note('package:',
                     os.path.abspath(os.path.join(__file__, '..', '..')))

    res = 0

    def find_command(name, warn=False):
        path = which(name)
        if path:
            print style_note('%s:' % name, path)
        else:
            if warn:
                print style_warning('cannot find %s' % name)
            else:
                print style_error('cannot find %s' % name)
                return 1

    print style_note('==> dependencies')
    for name, expected_version, in [('setuptools', '18.0.1'),
                                    ('virtualenv', '13.1.0')]:
        module = globals()[name]
        actual_version = module.__version__
        if expected_version == actual_version:
            print style_note(name + ':', expected_version)
        else:
            print style(
                '%s: %s (expected vendored %s) from %s' %
                (name, actual_version, expected_version, module.__file__),
                'yellow')
            res = 2

    print style_note('==> executables')
    print style_note('python:', sys.executable)
    res = find_command('git') or res
    if sys.platform == 'darwin':
        res = find_command('install_name_tool') or res
    if sys.platform.startswith('linux'):
        res = find_command('patchelf', warn=True) or res

    print style_note('==> configuration')
    home = args.assert_home()
    print style_note('home:', home.root)

    try:
        repo = home.get_env_repo()
    except ValueError:
        print style_warning('no default repo.',
                            'Use `vee repo add --default URL`.')
        return
    print style_note('repo:', repo.name, repo.remote_url)

    print style_note('==> summary')
    if not res:
        print style('Everything looks OK', 'green')
    else:
        print style('Something may be wrong', 'yellow')

    return res
Ejemplo n.º 8
0
def status(args):

    home = args.assert_home()

    env_repo = home.get_env_repo(args.repo)
    pkg_set = PackageSet(home=home)

    by_name = {}

    # Dev packages.
    for row in home.db.execute('SELECT * FROM development_packages'):
        row = dict(row)

        if not os.path.exists(row['path']):
            continue

        dev_repo = GitRepo(row['path'])
        row['remotes'] = dev_repo.remotes()
        by_name.setdefault(row['name'], {})['dev'] = row

    # Current requirements.
    for revision, name in [
        (None, 'work'),
        ('HEAD', 'head'),
    ]:
        for req in env_repo.load_requirements(
                revision=revision).iter_packages():
            pkg = pkg_set.resolve(req, check_existing=False)
            if pkg.fetch_type != 'git':
                continue
            by_name.setdefault(pkg.name, {})[name] = req

    by_name = by_name.items()
    by_name.sort(key=lambda x: x[0].lower())

    if args.names:
        by_name = [x for x in by_name if x[0] in args.names]

    for name, everything in by_name:

        dev_row = everything.get('dev')
        work_req = everything.get('work')
        head_req = everything.get('head')

        has_dev = dev_row is not None
        only_has_dev = has_dev and not (work_req or head_req)

        # Skip dev-only stuff most of the time.
        if only_has_dev and not args.all_dev:
            continue

        # Title.
        print '%s %s' % (style(
            '%s %s' % ('==>' if has_dev else '-->', name),
            fg='blue'), '(dev only)' if only_has_dev else '')

        # Status of requirements.
        if work_req and head_req and str(work_req) == str(head_req):
            if args.verbose:
                print '=== %s' % work_req
        else:

            # Print a lovely coloured diff of the specific arguments that
            # are changing.
            # TODO: make this environment relative to the context.
            head_args = head_req.to_args(
                exclude=('base_environ', )) if head_req else []
            work_args = work_req.to_args(
                exclude=('base_environ', )) if work_req else []
            differ = difflib.SequenceMatcher(None, head_args, work_args)
            opcodes = differ.get_opcodes()
            if head_req is not None:
                print style('---', fg='red', bold=True),
                for tag, i1, i2, j1, j2 in opcodes:
                    if tag in ('replace', 'delete'):
                        print style(' '.join(head_args[i1:i2]),
                                    fg='red',
                                    bold=True)
                    elif tag in ('equal', ):
                        print ' '.join(head_args[i1:i2]),
            if work_req is not None:
                print style('+++', fg='green', bold=True),
                for tag, i1, i2, j1, j2 in opcodes:
                    if tag in ('replace', 'insert'):
                        print style(' '.join(work_args[j1:j2]),
                                    fg='green',
                                    bold=True)
                    elif tag in ('equal', ):
                        print ' '.join(work_args[j1:j2]),

        if dev_row:

            if 'warning' in dev_row:
                print dev_row['warning']

            if 'origin' in dev_row['remotes']:
                dev_row['remote_name'] = 'origin'
            else:
                remote_names = sorted(dev_row['remotes'])
                dev_row['remote_name'] = remote_names[0]
                if len(remote_names) != 1:
                    print '    ' + style_warning(
                        'More that one non-origin remote; picking %s' %
                        dev_row['remote_name'])

        dev_repo = dev_row and GitRepo(dev_row['path'])
        if dev_repo and not dev_repo.exists:
            print style_warning('Git repo does not exist.')
            dev_row = dev_repo = None

        if dev_repo:

            if dev_repo.status():
                print '    ' + style_warning('Work tree is dirty.')

            if args.fetch:
                dev_remote_head = dev_repo.fetch(dev_row['remote_name'],
                                                 'master')
            else:
                dev_remote_head = dev_repo.rev_parse(dev_row['remote_name'] +
                                                     '/master')

            # Check your local dev vs. its remote.
            dev_local, dev_remote = dev_repo.distance(dev_repo.head,
                                                      dev_remote_head)
            summarize_rev_distance(
                dev_local,
                dev_remote,
                local_name=name,
                local_verb='is',
                remote_name='%s/master' % dev_row['remote_name'],
                behind_action='please pull or `vee dev ff %s`' % name,
            )

        if dev_repo and work_req and work_req.revision:

            # Check your local dev vs the required revision
            try:
                pkg_revision = dev_repo.rev_parse(work_req.revision)
                pkg_local, pkg_remote = dev_repo.distance(
                    dev_repo.head, pkg_revision)
                summarize_rev_distance(
                    pkg_local,
                    pkg_remote,
                    local_name=name,
                    local_verb='is',
                    remote_name='%s repo' % env_repo.name,
                    ahead_action='you may `vee add %s`' % name,
                    behind_action='please `vee dev checkout --repo %s %s`' %
                    (env_repo.name, name),
                )

            except Exception as e:
                print '    ' + format_cli_exc(e)