def git(args, *command): """Run a ``git`` command on a environment repository's git repository. (Sorry for the name collision.) e.g.:: $ vee git -r primary status On branch master Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working directory clean """ home = args.assert_home() repo = home.get_env_repo(args.repo) if args.stree: call(['stree', repo.work_tree]) return if not command: print style_error('please provide a git command') return 1 makedirs(repo.work_tree) repo.git(*command, verbosity=0, indent=False)
def init(args): """Initialize the structures on disk before any other commands, and optionally setup the first environment repository. E.g.: vee init [email protected]:westernx/vee-repo primary This is the same as: vee init vee repo clone [email protected]:westernx/vee-repo primary """ try: args.home.init() print 'Initialized %s' % args.home.root except ValueError: print style_error('Home already exists.') if args.url: print 'Create a new repository via:' print '\tvee repo clone --default %s %s' % (args.url, args.name or '') return if args.url: env_repo = args.home.create_env_repo(url=args.url, name=args.name) print 'Created repo %s at %s' % (env_repo.name, env_repo.work_tree)
def commit(args): home = args.assert_home() env_repo = home.get_env_repo(args.repo) if not env_repo.status(): print style_error('Nothing to commit.') return 1 # Pick the level of the patch. while not args.micro and args.semver_level is None: print '%s [%s]:' % ( style('How severe are the changes?', 'green', bold=True), style('major,minor,PATCH,micro', faint=True), ), res = raw_input().strip() or 'patch' try: args.semver_level = dict(major=0, minor=1, patch=2, micro=None)[res] except KeyError: pass else: break if args.message is None: default_message = default_messages[args.semver_level] print '%s [%s]:' % ( style('Enter a short commit message', 'green', bold=True), style(default_message, faint=True), ), args.message = raw_input().strip() or default_message env_repo.commit(args.message, args.semver_level)
def git(args, *command): if not command: print style_error('please provide a git command') return 1 home = args.assert_home() retcode = 0 for dev_pkg in home.iter_development_packages(): log.info(style_note(dev_pkg.name, ' '.join(command))) try: dev_pkg.git(*command, verbosity=0, indent=False) except Exception as e: print_cli_exc(e) retcode = 1 return retcode
def add(args): home = args.assert_home() env_repo = home.get_env_repo(args.repo) req_set = env_repo.load_requirements() pkg_set = PackageSet(home=home) baked_any = None if args.update: baked_any = False for req in req_set.iter_packages(): pkg = pkg_set.resolve(req, check_existing=False) if pkg.fetch_type != 'git': continue print style_note('Fetching', str(req)) pkg.repo.fetch('origin', 'master') # TODO: track these another way? if pkg.repo.check_ff_safety('origin/master'): pkg.repo.checkout('origin/master') head = pkg.repo.head[:8] if head != req.revision: req.revision = pkg.repo.head[:8] print style_note('Updated', str(req)) baked_any = True if args.bake_installed: baked_any = False for req in req_set.iter_packages(): pkg = pkg_set.resolve(req) if pkg.fetch_type != 'git': continue repo = pkg.pipeline.steps['fetch'].repo if req.name and req.name == guess_name(req.url): req.name = None baked_any = True print style_note('Unset redundant name', req.name) if pkg.installed and req.revision != repo.head[:8]: req.revision = repo.head[:8] baked_any = True print style_note('Pinned', req.name, req.revision) if args.checksum: baked_any = False for req in req_set.iter_packages(): pkg = pkg_set.resolve(req) if pkg.checksum: continue if not pkg.package_path or not os.path.isfile(pkg.package_path): continue req.checksum = checksum_file(pkg.package_path) print style_note('Checksummed', pkg.name, req.checksum) baked_any = True if baked_any is not None: if baked_any: env_repo.dump_requirements(req_set) else: print style_note('No changes.') return row = home.get_development_record(os.path.abspath(args.package)) if not row: raise ValueError('No development package %r' % args.package) dev_repo = GitRepo(row['path']) # Get the normalized origin. dev_remote_urls = set() for url in dev_repo.remotes().itervalues(): url = normalize_git_url(url, prefer='scp') or url log.debug('adding dev remote url: %s' % url) dev_remote_urls.add(url) if not dev_remote_urls: print style_error('No git remotes for %s' % row['path']) return 1 for req in req_set.iter_packages(eval_control=False): # We only deal with git packages. pkg = pkg_set.resolve(req, check_existing=False) if pkg.fetch_type != 'git': continue req_url = normalize_git_url(req.url, prefer='scp') log.debug('does match package url?: %s' % req_url) if req_url in dev_remote_urls: if req.revision == dev_repo.head[:8]: print style_note('No change to', str(req)) else: req.revision = dev_repo.head[:8] print style_note('Updated', str(req)) break else: if not args.init: print '{error}: No required package {name}; would match one of:'.format( error=style('Error', 'red'), name=style(args.package, bold=True)) for url in sorted(dev_remote_urls): print ' {}'.format(url) print 'Use {} to setup: git+{} --revision {}'.format( style('vee add --init %s' % args.package, 'green'), dev_repo.remotes()['origin'], dev_repo.head[:8]) return 1 req = Package( url=normalize_git_url(dev_repo.remotes()['origin'], prefix=True), revision=dev_repo.head[:8], home=home, ) req_set.append(('', req, '')) env_repo.dump_requirements(req_set)
def delete(args): home = args.assert_home() cur = home.db.execute('DELETE FROM repositories WHERE name = ?', [args.name]) if not cur.rowcount: print style_error('No %r repository.' % args.name)
def init(args, do_clone=False, do_install=False, do_add=False, is_find=False): do_init = not (do_clone or do_install or do_add) name = args.name home = args.assert_home() con = home.db.connect() # Make sure there are no other packages already, and clear out old ones # which no longer exist. for row in con.execute('SELECT * FROM development_packages WHERE name = ?', [name]): if not args.force and os.path.exists(os.path.join(row['path'], '.git')): if is_find: print style_note('"%s" already exists:' % name, row['path']) return else: print style_error('"%s" already exists:' % name, row['path']) return 1 else: con.execute('DELETE FROM development_packages WHERE id = ?', [row['id']]) path = os.path.abspath(args.path or os.path.join(home.dev_root, name)) dev_repo = GitRepo(path) if do_init: print style_note('Initing %s' % dev_repo.work_tree) makedirs(dev_repo.work_tree) dev_repo.git('init') elif do_clone: print style_note('Cloning %s' % args.url) makedirs(dev_repo.work_tree) dev_repo.clone_if_not_exists(args.url) elif do_install: # Find an existing tool. # TODO: put more of this into EnvironmentRepo or Requirements env_repo = home.get_env_repo(args.repo) req_path = os.path.join(env_repo.work_tree, 'requirements.txt') reqs = Requirements(req_path, home=home) for req in reqs.iter_packages(): if req.name.lower() == name.lower(): # Make sure it is a Git package. url = normalize_git_url(req.url, prefix=False) if url: break else: print style_error('Could not find git-based "%s" in "%s" repo.' % (name, env_repo.name)) return 2 print style_note('Found %s in %s' % (name, env_repo.name), str(req)) makedirs(dev_repo.work_tree) dev_repo.clone_if_not_exists(url, shallow=False) elif do_add: print style_note('Adding %s from %s' % (name, path)) if not os.path.exists(path): log.error('%s does not exist' % path) return 1 package = Package([path], home=home, dev=True) try: package.pipeline.run_to('develop') except Exception as e: print_cli_exc(e) return 1 print style_note('Linking dev package', name, path) con.execute( 'INSERT INTO development_packages (name, path, environ) VALUES (?, ?, ?)', [name, path, json.dumps(package.environ)]) dev_pkg = DevPackage( { 'name': name, 'path': path, 'environ': package.environ }, home=home) dev_pkg.save_tag()