def set_long_path_support(): global_git_config_path = os.path.normpath(expanduser("~/.gitconfig")) with git.GitConfigParser(global_git_config_path, read_only=False) as git_globalconfig: if 'core' not in git_globalconfig.sections(): git_globalconfig.add_section('core') git_globalconfig.set('core', 'longpaths', 'true')
def load_configuration(): gitconfig = git.GitConfigParser([os.path.normpath(os.path.expanduser("~/.gitconfig"))], read_only=True) github_username = gitconfig.get('github', 'user', fallback=None) if not github_username: logger.error('No github username set. Please run "git config --global github.user your-username".') with open('config.yml') as f: template = jinja2.Template(f.read()) def _github(name, user=github_username): if user: if GITHUB_PROTOCOL == 'ssh': return json.dumps('[email protected]:{user}/{name}'.format(user=user, name=name)) elif GITHUB_PROTOCOL == 'https': return json.dumps('https://github.com/{user}/{name}'.format(user=user, name=name)) return 'null' source = template.render(github=_github) config = yaml.load(source) if os.path.exists('config.local.yml'): with open('config.local.yml') as f: template = jinja2.Template(f.read()) source = template.render(github_username=github_username) config = merge(config, yaml.load(source)) return config
def reset_git_config(self): message = "Remove user info? " print("STEP 2: reset config ...") globalconfig = git.GitConfigParser(os.path.normpath( os.path.expanduser("~/.gitconfig")), read_only=False) print("*********************************") print("Current git global config values:") print("*********************************") print("\t" + globalconfig.get_value("user", "name")) print("\t" + globalconfig.get_value("user", "email")) if py3: response = input(message) else: response = raw_input(message) if response == "yes": print("Resetting user...") globalconfig.set_value("user", "name", "John Doe") globalconfig.set_value("user", "email", "*****@*****.**") else: print("No changes made. Continuing...")
def new(): proj = Project() cfg = git.GitConfigParser() proj.author_name = gittools.get_user_name(cfg) proj.author_email = gittools.get_user_email(cfg) proj.root = cwd.name proj.name = pyip.inputStr(prompt=f"Project name? [default: {cwd.name}]", default=cwd.name, blank=True) proj.src_dir = Path( pyip.inputFilepath(prompt='Source directory? [default: src/]', default='src/', blank=True)) proj.test_dir = Path( pyip.inputFilepath(prompt='Test directory? [default: tests/]', default='tests/', blank=True)) proj.repo = gittools.init_git('.') proj.pipenv = pipenvtools.init_pipenv('.') return proj
def get_remote_url(remote='origin', required=True): """ Read the git url for the given remote from the .git/config file of the current working directory. :param str remote: Git remote to look for :param bool required: Should the program exit if the url for this remote isn't found? :return: The git url for the given remote :rtype: str """ # Handle case where git remote url isn't found. What to do depends # on whether this url is required to exist or not... def handle_not_found(err): if not required: return None log(err) exit(1) git_path = '{}/.git'.format(os.getcwd()) # Whether the cwd is a git repository or not is_git_repo = os.path.exists(git_path) and os.path.isdir(git_path) # Cwd needs to be a git repo... if not is_git_repo: return handle_not_found('Current project is not a git repository.') config_path = '{}/config'.format( git_path) # where the remote url should be found # Config file needs to exist... if not os.path.exists(config_path): return handle_not_found('.git/config file missing.') try: # Parse the git config file config = git.GitConfigParser([config_path], read_only=True) except KeyboardInterrupt: exit(0) except BaseException: return handle_not_found('Error parsing .git/config file.') try: # Get the url for the given remote url = config.get_value('remote "{}"'.format(remote), 'url') except KeyboardInterrupt: exit(0) except BaseException: return handle_not_found( 'Error determining remote origin url...make sure you have a git remote origin set up.' ) if not url.endswith('.git'): url += '.git' return str(url)
def _global_info(): info = dict(editor=None, name=None, email=None) globalconfig = git.GitConfigParser([ os.path.normpath(os.path.expanduser("~/.gitconfig"))], read_only=True) if globalconfig.has_option("core", "editor"): info['editor'] = globalconfig.get_value("core", "editor") if globalconfig.has_option("user", "name"): info['name'] = globalconfig.get_value("user", "name") if globalconfig.has_option("user", "email"): info['email'] = globalconfig.get_value("user", "email") return info
def rename_local_repo(old, new, project): """ Renames local repositories: - Rename the git dir - Change remote origin (svn or git) - Change commit notification ML - Change PR notification ML """ # First, rename the dir on the box. Fall flat on our behind if this fails. print(" - Renaming gitbox repo from %s/%s to %s/%s..." % (REPO_ROOT, old, REPO_ROOT, new)) os.rename("%s/%s" % (REPO_ROOT, old), "%s/%s" % (REPO_ROOT, new)) # Change git config options gcpath = "%s/%s/config" % (REPO_ROOT, new) if not os.path.exists(gcpath): gcpath = "%s/%s/.git/config" % (REPO_ROOT, new) gconf = git.GitConfigParser(gcpath, read_only=False) # Remote origin on GitHub if gconf.has_section('remote "origin"'): print(" - Setting remote...") gconf.set('remote "origin"', 'url', "https://github.com/apache/%s" % new) # Remote copy on GitHub if gconf.has_section('remote "github-copy"'): print(" - Setting remote...") gconf.set('remote "github-copy"', 'url', "https://github.com/apache/%s" % new) # Remote SVN origin? if gconf.has_section('svn-remote "svn"'): svnremote = gconf.get('svn-remote "svn"', 'url') newsvn = svnremote.replace("/incubator/", "/") print(" - Setting SVN remote from %s to %s...") gconf.set('svn-remote "svn"', 'url', newsvn) # ML notification targets for commits and PRs print(" - Changing notification options..") if gconf.has_option('hooks.asfgit', 'recips'): ml = gconf.get('hooks.asfgit', 'recips') ml = re.sub(r"incubator\.", "", ml) print(" - Changing commit ML to %s" % ml) gconf.set('hooks.asfgit', 'recips', ml) if gconf.has_section('apache') and gconf.has_option('apache', 'dev'): ml = gconf.get('apache', 'dev') ml = re.sub(r"incubator\.", "", ml) print(" - Changing PR notification ML to %s" % ml) gconf.set('apache', 'dev', ml) print(" - Done!")
def init_color_console(force_color_output): config = git.GitConfigParser(os.path.normpath(expanduser("~/.gitconfig"))) config_color = config.get("color", "ui", fallback="auto") strip = not sys.stdout.isatty() convert = sys.stdout.isatty() if force_color_output or config_color == "always": strip = False elif config_color == "false": strip = True convert = False if os.name == 'posix': # Never convert on Linux. Setting it to False seems to cause problems. convert = None colorama.init(strip=strip, convert=convert, autoreset=True) return strip, convert
def write_conditional_include(workspace_path, repo_sources, included_configs): gitconfigpath = os.path.normpath(expanduser("~/.gitconfig")) for source in repo_sources: for included_config in included_configs: if included_config[0] == source.remote_name: gitdir = str(os.path.normpath(os.path.join(workspace_path, source.root))) gitdir = get_actual_path(gitdir) gitdir = gitdir.replace('\\', '/') if sys.platform == "win32": gitdir = '/{}'.format(gitdir) path = '/{}'.format(included_config[1]) else: path = included_config[1] path = path.replace('\\', '/') section = 'includeIf "gitdir:{}/"'.format(gitdir) with git.GitConfigParser(gitconfigpath, read_only=False) as gitglobalconfig: gitglobalconfig.add_section(section) gitglobalconfig.set(section, 'path', path)
def update_repo_commit_template(workspace_dir, repo, repo_info, config, global_manifest_directory): # Open the local manifest and get any templates manifest = edk_manifest.ManifestXml(os.path.join(workspace_dir, 'repo', 'Manifest.xml')) templates = manifest.commit_templates #Check for the presence of a globally defined commit template global_template_in_use = False global_gitconfig_path = os.path.normpath(expanduser("~/.gitconfig")) with git.GitConfigParser(global_gitconfig_path, read_only=False) as gitglobalconfig: if gitglobalconfig.has_option(section='commit', option='template'): gitglobalconfig.get_value(section='commit', option='template') global_template_in_use = True print(COMMIT_TEMPLATE_CUSTOM_VALUE.format(repo_info.remote_name)) # Apply the template based on current manifest with repo.config_writer() as cw: if not global_template_in_use: if cw.has_option(section='commit', option='template'): current_template = cw.get_value(section='commit', option='template').replace('"', '') if not current_template.startswith(os.path.normpath(global_manifest_directory).replace('\\', '/')): if os.path.isfile(current_template): print(COMMIT_TEMPLATE_CUSTOM_VALUE.format(repo_info.remote_name)) return else: print(COMMIT_TEMPLATE_NOT_FOUND.format(current_template)) print(COMMIT_TEMPLATE_RESETTING_VALUE) if repo_info.remote_name in templates: template_path = os.path.normpath(os.path.join(global_manifest_directory, templates[repo_info.remote_name])) if not os.path.isfile(template_path): print(COMMIT_TEMPLATE_NOT_FOUND.format(template_path)) return template_path = template_path.replace('\\', '/') # Convert to git approved path cw.set_value(section='commit', option='template', value='"{}"'.format(template_path)) else: if cw.has_option(section='commit', option='template'): cw.remove_option(section='commit', option='template') else: if cw.has_option(section='commit', option='template'): cw.remove_option(section='commit', option='template')
def clean_git_globalconfig(): global_gitconfig_path = os.path.normpath(expanduser("~/.gitconfig")) with git.GitConfigParser(global_gitconfig_path, read_only=False) as git_globalconfig: includeif_regex = re.compile('^includeIf "gitdir:(/.+)/"$') for section in git_globalconfig.sections(): data = includeif_regex.match(section) if data: gitrepo_path = data.group(1) gitconfig_path = git_globalconfig.get(section, 'path') if sys.platform == "win32": gitrepo_path = gitrepo_path[1:] gitconfig_path = gitconfig_path[1:] gitrepo_path = os.path.normpath(gitrepo_path) gitconfig_path = os.path.normpath(gitconfig_path) (repo_manifest_path, _) = os.path.split(gitconfig_path) repo_manifest_path = os.path.join(repo_manifest_path, "Manifest.xml") if not os.path.isdir(gitrepo_path) and not os.path.isfile( gitconfig_path): if not os.path.isfile(repo_manifest_path): git_globalconfig.remove_section(section)
from collections import OrderedDict import git filePath = '/tmp/git.config' # Could use SubmoduleConfigParser to get fancier c = git.GitConfigParser(filePath, False) c.sections() # http://stackoverflow.com/questions/8031418/how-to-sort-ordereddict-in-ordereddict-python c._sections = OrderedDict(sorted(c._sections.iteritems(), key=lambda x: x[0])) c.write() del c
def __check_submodule_config(self, workspace_path, manifest, repo_sources): gitconfigpath = os.path.normpath(expanduser("~/.gitconfig")) gitglobalconfig = git.GitConfigParser(gitconfigpath, read_only=False) try: local_manifest_dir = os.path.join(workspace_path, "repo") includeif_regex = re.compile('^includeIf "gitdir:(/.+)/"$') rewrite_everything = False #Generate list of .gitconfig files that should be present in the workspace included_configs = [] for remote in manifest.remotes: included_config_name = os.path.join( local_manifest_dir, INCLUDED_FILE_NAME.format(remote.name)) included_config_name = get_actual_path(included_config_name) remote_alts = [ submodule for submodule in manifest.submodule_alternate_remotes if submodule.remote_name == remote.name ] if remote_alts: included_configs.append( (remote.name, included_config_name)) for source in repo_sources: for included_config in included_configs: #If the current repository has a .gitconfig (aka it has a submodule) if included_config[0] == source.remote_name: if not os.path.isfile(included_config[1]): rewrite_everything = True gitdir = str( os.path.normpath( os.path.join(workspace_path, source.root))) gitdir = get_actual_path(gitdir) gitdir = gitdir.replace('\\', '/') if sys.platform == "win32": gitdir = '/{}'.format(gitdir) #Make sure the .gitconfig file is referenced by the global git config found_include = False for section in gitglobalconfig.sections(): data = includeif_regex.match(section) if data: if data.group(1) == gitdir: found_include = True break if not found_include: #If the .gitconfig file is missing from the global git config, add it. if sys.platform == "win32": path = '/{}'.format(included_config[1]) else: path = included_config[1] path = path.replace('\\', '/') section = 'includeIf "gitdir:{}/"'.format(gitdir) gitglobalconfig.add_section(section) gitglobalconfig.set(section, 'path', path) gitglobalconfig.release() gitglobalconfig = git.GitConfigParser( gitconfigpath, read_only=False) if rewrite_everything: #If one or more of the .gitconfig files are missing, re-generate all the .gitconfig files remove_included_config(manifest.remotes, manifest.submodule_alternate_remotes, local_manifest_dir) write_included_config(manifest.remotes, manifest.submodule_alternate_remotes, local_manifest_dir) finally: gitglobalconfig.release()
def getActivity(): # Get Whimsy data first PODLINGS = requests.get(PODLINGS_URL).json() TLPS = requests.get(TLPS_URL).json() repos = [x for x in os.listdir(GITPATH) if os.path.isdir(os.path.join(GITPATH, x)) ] projects = {} gitrepos = {} outjson = { 'updated': int(time.time()), 'projects': {} } comcounts = {} for repo in repos: repopath = os.path.join(GITPATH, repo) # Get repo description repodesc = "No Description" dpath = os.path.join(repopath, 'description') if os.path.exists(dpath): repodesc = open(dpath).read().strip() # Get git config items if False: configpath = os.path.join(repopath, "config") if os.path.exists(configpath): gconf = git.GitConfigParser(configpath, read_only = True) # Get latest commit timestamp, default to none lcommit = 0 lcount = 0 zcount = 0 last_hour = int(time.time()) last_hour = int(last_hour - (last_hour % 3600)) try: lcount = int(subprocess.check_output(['/usr/bin/git', '-C', repopath, 'rev-list', '--all', '--count'])) lcommit = int(subprocess.check_output(['/usr/bin/git', '-C', repopath, 'log', '-n', '1', '--pretty=format:%ct', '--all'])) zcount = int(subprocess.check_output(['/usr/bin/git', '-C', repopath, 'rev-list', '--all', '--count', "--since=%u" % last_hour])) except: pass # if it failed (no commits etc), default to no commits now = time.time() ago = now - lcommit # Make 'N ago..' string agotxt = "No commits" if lcommit == 0: agotxt = "No commits" elif ago < 60: agotxt = "<1 minute ago" elif ago < 120: agotxt = "<2 minutes ago" elif ago < 300: agotxt = "<5 minutes ago" elif ago < 900: agotxt = "<15 minutes ago" elif ago < 1800: agotxt = "<30 minutes ago" elif ago < 3600: agotxt = "<1 hour ago" elif ago < 7200: agotxt = "< 2 hours ago" elif ago < 14400: agotxt = "< 4 hours ago" elif ago < 43200: agotxt = "< 12 hours ago" elif ago < 86400: agotxt = "< 1 day ago" elif ago < 172800: agotxt = "< 2 days ago" elif ago <= (31 * 86400): agotxt = "%u days ago" % round(ago/86400) else: agotxt = "%u weeks ago" % round(ago/(86400*7)) if lcommit == 0: agotxt = "<span style='color: #777; font-style: italic;'>%s</span>" % agotxt elif ago <= 172800: agotxt = "<span style='color: #070;'>%s</span>" % agotxt # Store in project hash r = re.match(r"^(?:incubator-)?([^-.]+).*", repo) project = r.group(1) projects[project] = projects.get(project, []) repo = repo.replace(".git", "") # Crop this for sorting reasons (INFRA-15952) projects[project].append(repo) if len(repodesc) > 64: repodesc = repodesc[:61] + "..." gitrepos[repo] = [agotxt, repodesc, lcommit, lcount, zcount] comcounts[repo] = {str(last_hour): zcount} html = "" a = 0 for project in sorted(projects): a %= 3 a += 1 pname = project[0].upper() + project[1:] if project in PODLINGS['podling']: pname = "Apache " + PODLINGS['podling'][project]['name'] + " (Incubating)" if project in TLPS['committees']: pname = "Apache " + TLPS['committees'][project]['display_name'] outjson['projects'][project] = { 'domain': project, 'description': pname, 'repositories': {} } table = """ <table class="tbl%u"> <thead> <tr> <td colspan="4">%s</td> </tr> </thead> <tbody> <tr> <th>Repository name:</th> <th>Description:</th> <th>Last changed:</th> <th>Links:</th> </tr> """ % (a, pname) for repo in sorted(projects[project]): outjson['projects'][project]['repositories'][repo] = { 'description': gitrepos[repo][1], 'last_update_txt': gitrepos[repo][0], 'last_update_int': gitrepos[repo][2], 'commits': gitrepos[repo][3] } table += """ <tr> <td><a href="/repos/asf/?p=%s.git">%s.git</a></td> <td>%s</td> <td>%s</td> <td> <a href="/repos/asf/?p=%s.git;a=summary">Summary</a> | <a href="/repos/asf/?p=%s.git;a=shortlog">Short Log</a> | <a href="/repos/asf/?p=%s.git;a=log">Full Log</a> | <a href="/repos/asf/?p=%s.git;a=tree">Tree View</a> </td> </tr> """ % (repo, repo, gitrepos[repo][1],gitrepos[repo][0], repo, repo, repo, repo) table += "</table>" html += table return html, outjson, comcounts
def config(self): if not self._config: self._config = git.GitConfigParser(self.config_file) return self._config