def initialize(self, tag_config_path): """Initializes an empty git repository and creates and commits an initial tag configuration. If the repository already exists, only the tag configuration file is created and committed. Args: tag_config_path: The (relative) path to the dotfile tag configuration. """ if not isdir(self.path): print('Initializing empty repository in {}'.format(self.path)) _exec_raw(lambda: Git().init(self.path)) try: self._git().rev_parse() except InvalidGitRepositoryError: print('Initializing repository in existing directory {}'.format( self.path)) _exec_raw(lambda: Git(self.path).init()) full_path = join(self.path, tag_config_path) if not isfile(full_path): print('Creating initial tag configuration') makedirs(dirname(full_path), exist_ok=True) with open(full_path, 'w') as tag_config: tag_config.write('{0}: {0}'.format(gethostname())) self.add(tag_config_path)
async def pull(self, ctx): """Update the bot from github""" g = Git() try: await ctx.send(f"Probably pulled.\n```\n{g.pull()}```") except git.exc.GitCommandError as e: await ctx.send(f"An error has occured when pulling```\n{e}```")
def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs): """Initialize a git repository at the given path if specified :param path: is the full path to the repo (traditionally ends with /<name>.git) or None in which case the repository will be created in the current working directory :parm mkdir: if specified will create the repository directory if it doesn't already exists. Creates the directory with a mode=0755. Only effective if a path is explicitly given :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will be used to access all object data :parm kwargs: keyword arguments serving as additional options to the git-init command :return: ``git.Repo`` (the newly created repo)""" if path: path = _expand_path(path) if mkdir and path and not os.path.exists(path): os.makedirs(path, 0o755) # git command automatically chdir into the directory git = Git(path) git.init(**kwargs) return cls(path, odbt=odbt)
def __set_path(config: Config, attr: str): msg = { 'root_path': "path of the repository to work on", } while True: if not hasattr(config, attr) or not getattr(config, attr): path = prompt_enter_value(msg[attr]) else: path = getattr(config, attr) # set by script param if not __check_path(path): setattr(config, attr, "") continue if (attr == "root_path") & (os.path.realpath(__file__).startswith( os.path.abspath(path))): log_error( "Please copy and run the create release script in another place outside of the repository and execute again." ) sys.exit() try: Git(path) except InvalidGitRepositoryError: log_error("Path is not a git repository.") setattr(config, attr, path) info = { "root_path": "Executing release in path '", } log_info(info[attr] + str(getattr(config, attr)) + "'") break
def init(cls, path=None, mkdir=True, **kwargs): """Initialize a git repository at the given path if specified :param path: is the full path to the repo (traditionally ends with /<name>.git) or None in which case the repository will be created in the current working directory :parm mkdir: if specified will create the repository directory if it doesn't already exists. Creates the directory with a mode=0755. Only effective if a path is explicitly given :parm kwargs: keyword arguments serving as additional options to the git-init command :return: ``git.Repo`` (the newly created repo)""" if mkdir and path and not os.path.exists(path): os.makedirs(path, 0755) # git command automatically chdir into the directory git = Git(path) output = git.init(**kwargs) return Repo(path)
def urls(self): """:return: Iterator yielding all configured URL targets on a remote as strings""" try: remote_details = self.repo.git.remote("get-url", "--all", self.name) for line in remote_details.split('\n'): yield line except GitCommandError as ex: ## We are on git < 2.7 (i.e TravisCI as of Oct-2016), # so `get-utl` command does not exist yet! # see: https://github.com/gitpython-developers/GitPython/pull/528#issuecomment-252976319 # and: http://stackoverflow.com/a/32991784/548792 # if 'Unknown subcommand: get-url' in str(ex): try: remote_details = self.repo.git.remote("show", self.name) for line in remote_details.split('\n'): if ' Push URL:' in line: yield line.split(': ')[-1] except GitCommandError as ex: if any([msg in str(ex) for msg in ['correct access rights', 'cannot run ssh']]): # If ssh is not setup to access this repository, see issue 694 result = Git().execute(['git', 'config', '--get', 'remote.%s.url' % self.name]) yield result else: raise ex else: raise ex
def __init__(self, interval, length, should_notify=True): self.cwd = CURRENT_DIRECTORY self.start = datetime.datetime.now() reg = r'(\d+)' length_split = re.split(reg, length) time_int = length_split[1] time_type = length_split[2] if time_type == "h": self.until = datetime.datetime.now() + datetime.timedelta( hours=int(time_int)) elif time_type == "m": self.until = datetime.datetime.now() + datetime.timedelta( minutes=int(time_int)) elif time_type == "s": self.until = datetime.datetime.now() + datetime.timedelta( seconds=int(time_int)) print('Running BIF until {}'.format(self.until)) interval_split = re.split(reg, interval) interval_time = interval_split[1] interval_type = interval_split[2] if interval_type == "m": self.interval = datetime.timedelta( minutes=int(interval_time)).total_seconds() elif interval_type == "h": self.interval = datetime.timedelta( minutes=int(interval_time)).total_seconds() else: self.interval = int(interval_time) print('BIF Will Commit Every {} seconds'.format(self.interval)) self.g = Git(self.cwd) self.length = length self.should_run = True self.should_skip = False self.should_notify = should_notify self.run()
def check(self): git = Git() output = git.execute(['git', 'ls-remote', '--heads', self.repository]) if output: return True return False
def clone_from(cls, url, to_path, progress=None, env=None, multi_options=None, **kwargs): """Create a clone from the given URL :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS :param to_path: Path to which the repository should be cloned to :param progress: See 'git.remote.Remote.push'. :param env: Optional dictionary containing the desired environment variables. Note: Provided variables will be used to update the execution environment for `git`. If some variable is not specified in `env` and is defined in `os.environ`, value from `os.environ` will be used. If you want to unset some variable, consider providing empty string as its value. :param multi_options: See ``clone`` method :param kwargs: see the ``clone`` method :return: Repo instance pointing to the cloned directory""" git = Git(os.getcwd()) if env is not None: git.update_environment(**env) return cls._clone(git, url, to_path, GitCmdObjectDB, progress, multi_options, **kwargs)
def get_days_since_last_update(path): """ :return: The days since the last update of any of the files in path. If the path points to a filename, the last update of that filename is returned. """ git = Git(".") cmd_str = 'git log -1 --format=%%cd %s' % path cmd = shlex.split(cmd_str) try: date_str = git.execute(command=cmd, with_extended_output=False) except GitCommandError: raise ValueError('"%s" is not in tracked by this repository.' % path) # The date_str is in the following format: Sat Jun 21 10:20:31 2014 -0300 # We need to parse it, and then do some date math to return the result # # We ignore the UTC offset because it was "hard to parse" and we don't care last_commit_time = datetime.strptime(date_str[:-6], '%a %b %d %H:%M:%S %Y') last_commit_date = last_commit_time.date() today_date = date.today() time_delta = today_date - last_commit_date return time_delta.days
def get(): parser = reqparse.RequestParser() parser.add_argument('repo', location='args', required=True) parser.add_argument('port', location='args', required=True) data = parser.parse_args() repo = data['repo'] port = data['port'] try: response = requests.get(repo) if response.status_code != 200: return jsonify({ 'status': 401, 'error': '{} is not a valid URL'.format(repo) }) except: return jsonify({ 'status': 401, 'error': '{} is not a valid URL'.format(repo) }) gitcmd = Git('.') gitcmd.init() name = repo.split('/') repo_name = name[-1] repo_name = repo_name.replace('.git', '') gitcmd.clone(repo, 'repos/' + repo_name) subprocess.Popen( '.flaskapp/bin/uwsgi --http :%s --file repos/{}/wsgi.py --callable app' .format(port, repo_name)) return jsonify({ 'status': 200, 'message': 'Deployed to Raspberry Pi! {} is now running!'.format(repo_name) })
def __init__(self, options, title=None, default_index=0, options_map_func=None): self.KEYS_ENTER = (curses.KEY_ENTER, ord('\n'), ord('\r')) self.KEYS_UP = (curses.KEY_UP, ord('k')) self.KEYS_DOWN = (curses.KEY_DOWN, ord('j')) self.KEYS_SELECT = (curses.KEY_RIGHT, ord(' ')) self.options = options self.title = title self.indicator = "=>" self.options_map_func = options_map_func self.commit_type = [ "feat", "fix", "docs", "style", "refactor", "test", "chore", "exit" ] self.git = Git(os.getcwd()) self.emojis = { "feat": "sparkles", "fix": "bug", "docs": "memo", "style": "art", "refactor": "recycle", "test": "white_check_mark", "chore": "building_construction", } if default_index >= len(options): raise ValueError( 'default_index should be less than the length of options') self.index = default_index
def clone_from(cls, url, to_path, **kwargs): """Create a clone from the given URL :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS :param to_path: Path to which the repository should be cloned to :param **kwargs: see the ``clone`` method :return: Repo instance pointing to the cloned directory""" return cls._clone(Git(os.getcwd()), url, to_path, GitCmdObjectDB, **kwargs)
def graph(self): """ Prints a graph of the git log. This is used for testing and debugging only. """ sys.stdout.write( Git(self.repodir).execute(["git", "log", "--graph", "--oneline"]))
def command(self, command, freezer=None): """ Runs the Git command in self.repo """ args = split(command) cmd = Git(self.repodir) cmd.execute(args)
def clone(self, url): """Clones a dotfile repository. Args: url: The URL of the repository to clone. """ print('Cloning {} into {}'.format(url, self.path)) _exec_raw(lambda: Git().clone(url, self.path))
def graph(self): """ Prints a graph of the git log. This is used for testing and debugging only. """ sys.stdout.write( Git(self.repodir).execute(['git', 'log', '--graph', '--oneline']))
def init_logging(gn_env: GNEnvironment) -> None: if len(gn_env.config) == 0 or gn_env.config.get(ConfigKeys.TESTING, False): # assume we're testing return logging_type = gn_env.config.get( ConfigKeys.TYPE, domain=ConfigKeys.LOGGING, default="logger" ) if ( logging_type is None or len(logging_type.strip()) == 0 or logging_type in ["logger", "default", "mock"] ): return if logging_type != "sentry": raise RuntimeError(f"unknown logging type {logging_type}") dsn = gn_env.config.get(ConfigKeys.DSN, domain=ConfigKeys.LOGGING, default="") if dsn is None or len(dsn.strip()) == 0: logger.warning( "sentry logging selected but no DSN supplied, not configuring sentry" ) return import socket from git.cmd import Git home_dir = os.environ.get("DINO_HOME", default=None) if home_dir is None: home_dir = "." tag_name = Git(home_dir).describe() import sentry_sdk from sentry_sdk import capture_exception as sentry_capture_exception from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration sentry_sdk.init( dsn=dsn, environment=os.getenv("ENVIRONMENT"), # TODO: fix DINO_ENVIRONMENT / ENVIRONMENT discrepancy server_name=socket.gethostname(), release=tag_name, integrations=[ SqlalchemyIntegration(), RedisIntegration() ], ) def capture_wrapper(e_info) -> None: try: sentry_capture_exception(e_info) except Exception as e2: logger.exception(e_info) logger.error(f"could not capture exception with sentry: {str(e2)}") gn_env.capture_exception = capture_wrapper
def pull(repo_dir): """ Pull all the new files in the master in specified directory. Directory should contain path where .git file is located. :param repo_dir: directory where .git file is located """ g = Git(repo_dir) g.pull() a = Repo(repo_dir) for s in a.submodules: s.update(recursive=True, init=True)
def is_cached(self): try: cache_path = self.cache_dir + '/' + self.project is_dir = os.path.isdir(cache_path) if is_dir: result = Git(cache_path).execute( ['git', 'rev-parse', '--git-dir'], ) if result.startswith('.'): return True return False except Exception: return False
def __init__(self, options, build_type='job'): self.options = options repository, project, version = self.parse_repository() self.repository = repository self.project = project self.version = version self.cache_dir = Workspace().get_vcs_space('git') self.build_type = build_type self.workspace = self.cwd self.git = Git(working_dir=self.cwd) self.refs = None self.logger = get_logger('console')
def get_contibutors(self) -> list[str]: """Return list of Git contributors for given path using `git shortlog` :path: Path of which to get contributors :flags: Additional flags passed to `git shortlog` """ docfile_path = Path(self.get_source_info()[0]).resolve() docfile_name = docfile_path.name docdir_path = docfile_path.parent min_commits = self.optn_over_conf("min_commits", "scm_contribs_min_commits") limit_authors = self.optn_over_conf("limit_authors", "scm_contribs_limit_authors") if limit_authors is not None and limit_authors < 1: logger.warning( "List of contributors limited to less than one entry. " "Check '(scm_contribs_)limit_authors' option/config value") flags: list[str] = [] contribs_email = directives.choice( self.optn_over_conf("email", "scm_contribs_email"), ("true", "false"), ) flags += ["-e"] if contribs_email == "true" else [] contribs_sort = directives.choice( self.optn_over_conf("sort", "scm_contribs_sort"), ("name", "num"), ) flags += ["-n"] if contribs_sort == "num" else [] contribs_type = directives.choice( self.optn_over_conf("type", "scm_contribs_type"), ("author", "committer"), ) flags += ["-c"] if contribs_type == "committer" else [] git_shortlog_options = ["-s", *flags, "--", docfile_name] contributors = [] git_shortlog = Git(docdir_path).shortlog(*git_shortlog_options) git_shortlog_items = git_shortlog.split("\n") for item in git_shortlog_items: if not item: continue num, contributor = item.split("\t") if int(num) < min_commits: continue contributors += [contributor] return contributors[:limit_authors]
def is_type(cls, origin=None): if origin is None: return False g = Git() try: g.ls_remote(origin) except GitCommandError: return False return True
def install_by_url(self, url, ignore_errors=False): """ installs from the specified github repo """ url = url.strip() self.github_url_check(url) data = self.url_info(url) skill_folder = data["folder"] path = data["path"] self.send_message("msm.installing", data) if exists(path): LOG.info("skill exists, updating") # TODO get hashes before pulling to decide if pip and res.sh should be run # TODO ensure skill master branch is checked out, else dont update g = Git(path) try: g.pull() except GitCommandError: LOG.error("skill modified by user") if not ignore_errors: LOG.info("not updating") data["error"] = "skill modified by user" self.send_message("msm.install.failed", data) self.send_message("msm.installed") return False else: LOG.info("Downloading skill: " + url) Repo.clone_from(url, path) if skill_folder not in self.skills: self.skills[skill_folder] = data self.skills[skill_folder]["downloaded"] = True try: self.run_requirements_sh(skill_folder) except SystemRequirementsException: if not ignore_errors: data["error"] = "could not run requirements.sh" self.send_message("msm.install.failed", data) self.send_message("msm.installed") return False try: self.run_pip(skill_folder) except PipRequirementsException: if not ignore_errors: data["error"] = "could not run install requirements.txt" self.send_message("msm.install.failed", data) self.send_message("msm.installed") return False self.run_skills_requirements(skill_folder) self.send_message("msm.install.succeeded", data) self.send_message("msm.installed") return True
def pull(repo_dir: str): """ Pull all the new files in the master in specified directory. Directory should contain path where .git file is located. Arguments: :param repo_dir directory where .git file is located """ git = Git(repo_dir) git.pull() repo = Repo(repo_dir) for submodule in repo.submodules: submodule.update(recursive=True, init=True)
def clone_from(cls, url, to_path, progress=None, env=None, **kwargs): """Create a clone from the given URL :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS :param to_path: Path to which the repository should be cloned to :param progress: See 'git.remote.Remote.push'. :param env: Optional dictionary containing the desired environment variables. :param kwargs: see the ``clone`` method :return: Repo instance pointing to the cloned directory""" git = Git(os.getcwd()) if env is not None: git.update_environment(**env) return cls._clone(git, url, to_path, GitCmdObjectDB, progress, **kwargs)
def __init__(self, path: Path | str) -> None: self.path: Path = Path(path) self.repo: Repo = Repo(self.path) if self.repo.bare: logger.critical( "Please make sure you entered the correct repository " "in [SYNAPSE] -> Playbook.") sys.exit(1) self.git: Git = Git(self.path) self.heads = self.repo.heads self.master = self.heads.master
def __set_path(config: Config, attr: str): while True: if not hasattr(config, attr) or not getattr(config, attr): tempdir = tempfile.TemporaryDirectory() path = tempdir.name if not hasattr(config, "two_factor_authentication"): config.two_factor_authentication = prompt_yesno_question( "Are you using two-factor authentication on GitHub?") if config.two_factor_authentication: repository_url = "[email protected]:" + config.github_repo + ".git" else: repository_url = "https://github.com/" + config.github_repo + ".git" log_info("Cloning temporary repository from " + repository_url + " to " + str(path) + " for processing the release...") Git(path).clone(repository_url) else: path = getattr(config, attr) # set by script param if not __check_path(path): setattr(config, attr, "") continue if (attr == "root_path") & (os.path.realpath(__file__).startswith(os.path.abspath(path))): log_error( "Please copy and run the create release script in another place outside of the repository and execute again.") sys.exit() try: Git(path) except InvalidGitRepositoryError: log_error("Path is not a git repository.") setattr(config, attr, path) info = { "root_path": "Executing release in path '", } log_info(info[attr] + str(getattr(config, attr)) + "'") break
def open_or_clone_repo(): """Returns opened or cloned repo and 'True' flag if operation successful else 'None' object and 'False' flag. """ try: return GitRepo(path=procyon_settings.REPO_PATH), True except (InvalidGitRepositoryError, NoSuchPathError): pass try: Git(procyon_settings.PROCYON_PATH).clone(procyon_settings.REMOTE_REPO) except GitCommandError: return None, False return GitRepo(path=procyon_settings.REPO_PATH), True
def checkout(c, name=None): _platform = __platform() _c_name, _c_platform = f'[hl]{name}[/hl]', f'[hl]{_platform}[/hl]' _h_name, _h_platform = f'<b>{name}</b>', f'<b>{_platform}</b>' _msg = f'Checkout of :{cfg.icon.component}: %s %s completed @ :{cfg.icon.platform}: %s.' try: _git = Git(cfg.git.get(name)) _git.checkout() log.success(_msg % (_c_name, '[ok]correctly[/ok]', _c_platform)) telegrot.success(_msg % (_h_name, '<u>correctly</u>', _h_platform)) exit(0) except Exception: log.error(_msg % (_c_name, '[err]not[/err]', _c_platform)) telegrot.error(_msg % (_h_name, '<u>not</u>', _h_platform)) exit(1)