Example #1
0
def isRepo():
    """ Returns if the cwd is a git repo """
    try:
        git("rev-parse", "--is-inside-work-tree")
        return 1
    except:
        return 0
    def add_change(self, change):
        """
        Merge a given GerritChange into the git source_workspace if possible
        """
        print("Attempting to add %s to %s" % (change, self))
        if change in self._applied_changes:
            print("Change %s has already been applied" % change)
            return
        if change.branch != self.target_branch:
            raise Exception(
                "Cannot merge change %s from branch %s onto target branch %s "
                "in package %s" %
                (change, change.branch, self.target_branch, self))
        # Check change isn't already merged.
        if change.status == "MERGED":
            print("Change %s has already been merged in gerrit" % change)
            return
        elif change.status == "ABANDONED":
            raise Exception("Can not merge abandoned change %s" % change)

        self.prep_workspace()

        with cd(self.source_dir):
            # If another change has already applied this change by having it as
            # one of its ancestry commits then the following merge will do a
            # harmless null operation
            print("Fetching ref %s" % change.ref)
            sh.git('fetch', self.url, change.ref)
            sh.git('merge', '--no-edit', 'FETCH_HEAD')
            self._applied_changes.add(change)
Example #3
0
    def clone(self, force=False, commit_hook=True):
        if os.path.exists(self.repo_path):
            print('Path {0} already exists'.format(self.repo_path))
            if force:
                pass
            else:
                return

        args = [
            'clone',
            self.url,
            self.repo_path
        ]
        print('Cloning repository {0} to {1}'.format(self.project, self.repo_path))
        git(*args)

        if commit_hook:
            curr_dir = os.getcwd()
            try:
                os.chdir(self.repo_path)
                git_dir = str(git('rev-parse', '--git-dir')).strip()
                scp(
                    '-p',
                    '-P', self.gerrit_port,
                    '{0}@{1}:hooks/commit-msg'.format(self.gerrit_user, self.gerrit_host),
                    os.path.join(git_dir, 'hooks'),
                )
            finally:
                os.chdir(curr_dir)
Example #4
0
    def setUp(self):
        self.powerline = mock.MagicMock()
        git.Color = mock.MagicMock()

        self.dirname = tempfile.mkdtemp()
        sh.cd(self.dirname)
        sh.git("init", ".")
Example #5
0
 def branch_exists(self, branch):
     """Returns true or false depending on if a branch exists"""
     try:
         git(self.gitdir, self.gitwd, "rev-parse", branch)
     except sh.ErrorReturnCode:
         return False
     return True
    def test_write(self):
        def cleanup_write():
            git.checkout("master")
            git.branch("-D","johndoe_study_9998")
            git.branch("-D","johndoe_study_9999")

        self.addCleanup(cleanup_write)

        author   = "John Doe <*****@*****.**>"
        content  = '{"foo":"bar"}'
        study_id = 9999
        branch   = "johndoe_study_%s" % study_id
        new_sha  = self.gd.write_study(study_id,content,branch,author)
        self.assertTrue( new_sha != "", "new_sha is non-empty")
        self.assertEqual(len(new_sha), 40, "SHA is 40 chars")
        self.assertEqual( content, self.gd.fetch_study(9999), "correct content found via fetch_study")

        author   = "John Doe <*****@*****.**>"
        content  = '{"foo2":"bar2"}'
        study_id = 9998
        branch   = "johndoe_study_%s" % study_id
        new_sha  = self.gd.write_study(study_id,content,branch,author)

        merge_base_sha1 = git("merge-base","johndoe_study_9999","johndoe_study_9998").strip()

        master_sha1     = git("rev-parse","master").strip()

        self.assertEqual(master_sha1, merge_base_sha1, "Verify that writing new study branches from master and not the current branch")
Example #7
0
    def fetch(self):
        LOG.debug('Fetching repo uri %s' % self.repo['uri'])

        if os.path.exists(self.folder):
            os.chdir(self.folder)
            uri = str(sh.git('config', '--get', 'remote.origin.url')).strip()
            if uri != self.repo['uri']:
                LOG.debug('Repo uri %(uri)s differs from cloned %(old)s',
                          {'uri': self.repo['uri'], 'old': uri})
                os.chdir('..')
                shutil.rmtree(self.folder)

        if not os.path.exists(self.folder):
            os.chdir(self.sources_root)
            try:
                sh.git('clone', self.repo['uri'])
            except sh.ErrorReturnCode as e:
                LOG.error('Unable to clone git repo %s. Ignore it',
                          self.repo['uri'])
                LOG.exception(e)
            os.chdir(self.folder)
        else:
            os.chdir(self.folder)
            try:
                sh.git('fetch')
            except sh.ErrorReturnCode as e:
                LOG.error('Unable to fetch git repo %s. Ignore it',
                          self.repo['uri'])
                LOG.exception(e)

        self.get_release_index()
Example #8
0
    def update(self, ref):
        """Inherited method
        :func:`~repoman.repository.Repository.update`
        """
        # As the library doesn't not allow you to checkout a remote branch,
        # checking if it's already created, if so, change to that branch,
        # otherwise, create the branch pointing to the remote hex
        remote_ref_prefix = 'refs/remotes/origin/'
        local_ref_prefix = 'refs/heads/'

        try:
            self._clean()
            if ref == 'HEAD':
                return self.tip()
            # Let's assume the ref is branch name
            branch = ref
            try:
                if not self._repository.lookup_branch(branch):
                    branch_head = self._repository.lookup_reference(
                        remote_ref_prefix + branch).get_object()
                    self._repository.create_branch(branch, branch_head)
                self._repository.checkout(local_ref_prefix + branch,
                                          strategy=pygit2.GIT_CHECKOUT_FORCE)
                return self.tip()
            except KeyError:
                # Ref is a hash so this must update to a detached head
                rev_hash = ref
            sh.git('checkout', rev_hash, _cwd=self.path)
            return self[rev_hash]
        except (pygit2.GitError, sh.ErrorReturnCode) as e:
            logger.exception(e)
            raise RepositoryError(e)
Example #9
0
def check_update():
    """
    Check if there is a later version of Screenly OSE
    available. Only do this update once per day.
    Return True if up to date was written to disk,
    False if no update needed and None if unable to check.
    """

    sha_file = path.join(settings.get_configdir(), 'latest_screenly_sha')
    device_id_file = path.join(settings.get_configdir(), 'device_id')

    if path.isfile(sha_file):
        sha_file_mtime = path.getmtime(sha_file)
        last_update = datetime.fromtimestamp(sha_file_mtime)
    else:
        last_update = None

    if not path.isfile(device_id_file):
        device_id = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(15))
        with open(device_id_file, 'w') as f:
            f.write(device_id)
    else:
        with open(device_id_file, 'r') as f:
            device_id = f.read()

    logging.debug('Last update: %s' % str(last_update))

    git_branch = sh.git('rev-parse', '--abbrev-ref', 'HEAD').strip()
    git_hash = sh.git('rev-parse', '--short', 'HEAD').strip()

    if last_update is None or last_update < (datetime.now() - timedelta(days=1)):

        if not settings['analytics_opt_out'] and not is_ci():
            mp = Mixpanel('d18d9143e39ffdb2a4ee9dcc5ed16c56')
            try:
                mp.track(device_id, 'Version', {
                    'Branch': str(git_branch),
                    'Hash': str(git_hash),
                })
            except MixpanelException:
                pass
            except AttributeError:
                pass

        if remote_branch_available(git_branch):
            latest_sha = fetch_remote_hash(git_branch)

            if latest_sha:
                with open(sha_file, 'w') as f:
                    f.write(latest_sha)
                return True
            else:
                logging.debug('Unable to fetch latest hash.')
                return
        else:
            touch(sha_file)
            logging.debug('Unable to check if branch exist. Checking again tomorrow.')
            return
    else:
        return False
 def setUp(self):
     super(TestServerOk, self).setUp()
     self.dir = tempfile.mkdtemp()
     sh.cd(self.dir)
     sh.git.init()
     sh.git('config', 'user.name', '"Guido"')
     sh.git('config', 'user.email', '"*****@*****.**"')
     sh.touch('README')
     sh.git.add('.')
     sh.git.commit('-am', 'first commit')
     sh.git.tag('-a', 'jenkins-release-1', '-m', 'Release 1')
     sh.touch('file1')
     sh.git.add('.')
     sh.git.commit('-am', 'second commit #777 #123')
     sh.git.tag('-a', 'jenkins-release-2', '-m', 'Release 2', _env={"GIT_COMMITTER_DATE": "2006-04-07T22:13:13"})
     sh.touch('file2')
     sh.git.add('.')
     sh.git.commit('-am', '#67 third commit')
     sh.git.tag('-a', 'jenkins-release-3', '-m', 'Release 3')
     self.prepare_client()
     self.valid_data = {
         'build_number': '42',
         'build_tag': 'jenkins-release-2',
         'previous_tag': 'jenkins-release-1',
         'job_url': 'http://jenkins_url/jobs/2/',
         'repo': self.dir,
         'instance': 'TestServer',
     }
Example #11
0
def gitrepo(root):
    '''Construct a dictionary holding all the Git data that can be found.'''
    oldpwd = sh.pwd().strip()
    sh.cd(root)
    gitlog = sh.git('--no-pager', 'log', '-1',
                    pretty="format:%s" % FORMAT).split('\n', 7)
    branch = (os.environ.get('CIRCLE_BRANCH') or
              os.environ.get('TRAVIS_BRANCH',
                             sh.git('rev-parse',
                                    '--abbrev-ref', 'HEAD').strip()))
    remotes = [x.split() for x in sh.git.remote('-v').strip().splitlines()
               if x.endswith('(fetch)')]
    sh.cd(oldpwd)
    return {
        "head": {
            "id": gitlog[0],
            "author_name": gitlog[1],
            "author_email": gitlog[2],
            "author_timestamp": gitlog[3],
            "committer_name": gitlog[4],
            "committer_email": gitlog[5],
            "committer_timestamp": gitlog[6],
            "message": gitlog[7].strip(),
        },
        "branch": branch,
        "remotes": [{'name': r[0], 'url': r[1]} for r in remotes]
    }
Example #12
0
    def create_or_checkout_branch(self, gh_user, study_id, parent_sha, force_branch_name=False):
        if force_branch_name:
            #@TEMP deprecated
            branch = "{ghu}_study_{rid}".format(ghu=gh_user, rid=study_id)
            if not self.branch_exists(branch):
                try:
                    git(self.gitdir, self.gitwd, "branch", branch, parent_sha)
                    _LOG.debug('Created branch "{b}" with parent "{a}"'.format(b=branch, a=parent_sha))
                except:
                    raise ValueError('parent sha not in git repo')
            self.checkout(branch)
            return branch

        frag = "{ghu}_study_{rid}_".format(ghu=gh_user, rid=study_id)
        branch = self._find_head_sha(frag, parent_sha)
        _LOG.debug('Found branch "{b}" for sha "{s}"'.format(b=branch, s=parent_sha))
        if not branch:
            branch = frag + '0'
            i = 1
            while self.branch_exists(branch):
                branch = frag + str(i)
                i += 1
            _LOG.debug('lowest non existing branch =' + branch)
            try:
                git(self.gitdir, self.gitwd, "branch", branch, parent_sha)
                _LOG.debug('Created branch "{b}" with parent "{a}"'.format(b=branch, a=parent_sha))
            except:
                raise ValueError('parent sha not in git repo')
        self.checkout(branch)
        _LOG.debug('Checked out branch "{b}"'.format(b=branch))
        return branch
    def test_request_refresh_not_existing_reference(self):
        dcvs = DepotOperations()

        # Remote repository
        self.add_content_to_repo(
            os.path.join(FIXTURE_PATH, 'fixture-2.git.bundle'),
            'remote')

        # Master cache
        master = dcvs.init_depot(
            os.path.join(self.environment_path, 'master'),
            parent=None,
            source=os.path.join(self.environment_path, 'remote'))

        # Workspace depot
        workspace1 = dcvs.init_depot(
            os.path.join(self.environment_path, 'workspace1'),
            parent=master,
            source=os.path.join(self.environment_path, 'master'))

        with self.assertRaises(sh.ErrorReturnCode):
            sh.git('rev-parse', 'notexists', _cwd=workspace1.path)

        self.assertFalse(workspace1.request_refresh({
            os.path.join(self.environment_path, 'remote'): ['notexists']}))
Example #14
0
    def pull(self, remote, env={}, branch=None):
        """
        Pull a branch from a given remote

        Given a remote, env and branch, pull branch
        from remote and add the environment variables
        in the env dict to the environment of the
        "git pull" command.

        If no branch is given, the current branch
        will be updated.
        """
        if branch:
            branch_to_pull = branch
        else:
            branch_to_pull = self.current_branch()

        # if there is no PKEY, we don't need to override env
        # We are explicit about what we are pushing, since the default behavior
        # is different in different versions of Git and/or by configuration
        if env["PKEY"]:
            new_env = os.environ.copy()
            new_env.update(env)
            git(self.gitdir, self.gitwd, "pull", remote, "{}:{}".format(branch_to_pull,branch_to_pull), _env=new_env)
        else:
            git(self.gitdir, self.gitwd, "pull", remote, "{}:{}".format(branch_to_pull,branch_to_pull))

        new_sha      = git(self.gitdir, self.gitwd, "rev-parse","HEAD")
        return new_sha.strip()
Example #15
0
def skipUnlessHasGit(obj):
    # Test git presence
    try:
        sh.git(version=True, _out='/dev/null')
        return lambda func: func
    except sh.CommandNotFound:
        return unittest.skip("Git is not installed")
Example #16
0
    def remove_study(self, first_arg, sec_arg, third_arg, fourth_arg=None, commit_msg=None):
        """Remove a study
        Given a study_id, branch and optionally an
        author, remove a study on the given branch
        and attribute the commit to author.
        Returns the SHA of the commit on branch.
        """
        if fourth_arg is None:
            study_id, branch_name, author = first_arg, sec_arg, third_arg
            gh_user = branch_name.split('_study_')[0]
            parent_sha = self.get_master_sha()
        else:
            gh_user, study_id, parent_sha, author = first_arg, sec_arg, third_arg, fourth_arg
        study_filepath = self.path_for_study(study_id)
        study_dir = os.path.split(study_filepath)[0]

        branch = self.create_or_checkout_branch(gh_user, study_id, parent_sha)
        prev_file_sha = None
        if commit_msg is None:
            msg = "Delete Study #%s via OpenTree API" % study_id
        else:
            msg = commit_msg
        if os.path.exists(study_filepath):
            prev_file_sha = self.get_blob_sha_for_file(study_filepath)
            git(self.gitdir, self.gitwd, "rm", "-rf", study_dir)
            git(self.gitdir,
                self.gitwd,
                "commit",
                author=author,
                message=msg)
        new_sha = git(self.gitdir, self.gitwd, "rev-parse", "HEAD").strip()
        return {'commit_sha': new_sha,
                'branch': branch,
                'prev_file_sha': prev_file_sha,
               }
    def remove_study(self,study_id, branch, author="OpenTree API <*****@*****.**>"):
        """Remove a study

        Given a study_id, branch and optionally an
        author, remove a study on the given branch
        and attribute the commit to author.

        Returns the SHA of the commit on branch.

        """
        os.chdir(self.repo)

        study_dir      = "study/%s" % study_id
        study_filename = "%s/%s.json" % (study_dir, study_id)

        if self.branch_exists(branch):
            git.checkout(branch)
            if not os.path.isdir(study_dir):
                # branch already exists locally with study removed
                # so just return the commit SHA
                return git("rev-parse","HEAD").strip()
        else:
            # Create this new branch off of master, NOT the currently-checked out branch!
            git.checkout("master")
            git.checkout("-b",branch)

        git.rm("-rf", study_dir)

        git.commit(author=author, message="Delete Study #%s via OpenTree API" % study_id)

        new_sha = git("rev-parse","HEAD")

        return new_sha.strip()
Example #18
0
def clone(root, uniqname, project):
	into='/tmp/'+root
	mkdir('-p', into)
	url='[email protected]:' + uniqname + '/' + project
	to_path=into + '/' + uniqname

	if 'rerun' in sys.argv:
		if os.path.exists(to_path):
			print('cached {}'.format(to_path))
			repo = git.Repo(to_path)
			return repo, to_path

	print('clone {}/{}'.format(uniqname, project))
	try:
		repo = git.Repo.clone_from(
				url=url,
				to_path=to_path,
				)
		return repo, to_path
	except:
		# Fall back to sh path to grab the error
		try:
			sh.git('clone', url, to_path)
		except sh.ErrorReturnCode as e:
			if 'Connection closed by remote host' in e.stderr.decode('utf8'):
				# gitlab rate-limited us
				time.sleep(3)
				return clone(root, uniqname, project)
			raise

		# Since we're hammering the gitlab server, rarely the first will
		# timeout, but this second chance will succeed. Create a repo object
		# from the path in that case.
		repo = git.Repo(to_path)
		return repo, to_path
Example #19
0
    def test_git_dir_from_subdir(self):
        sh.git('init')
        sh.mkdir('foo')
        expected = os.path.join(os.getcwd(), '.git')

        sh.cd('foo')
        self.assertEqual(expected, git_dir())
Example #20
0
def give_user_ztanesh(unix_user):
    """
    Make sure our UNIX user runs ZtaneSH shell it is more productive to work with Plone sites.

    https://github.com/miohtama/ztanesh
    """
    from sh import git
    from sh import chsh

    home = get_unix_user_home(unix_user)

    # Install ZtaneSH
    if not os.path.exists("%s/tools" % home):

        print "Installing ZtaneSH for user %s" % unix_user

        with sudo(i=True, u=unix_user, _with=True):
            cd(home)
            git("clone", "git://github.com/miohtama/ztanesh.git", "tools")
            setup = "%s/tools/zsh-scripts/setup.zsh" % home
            run = Command(setup)
            run()

    # Set user default shell
    with sudo:
        chsh("-s", "/bin/zsh", unix_user)
Example #21
0
def run_init(*args, **kwargs):

    # initialize the git repository if not already done
    try:
        git("rev-parse", "--dir-list")
    except ErrorReturnCode_128:
        git("init")

    exclude = kwargs.get('exclude')
    hooks_added = []

    for hook in SUPPORTED_HOOKS:
        if exclude and hook not in exclude or not exclude:
            try:
                os.symlink(path_to_the_script, '.git/hooks/{}'.format(hook))
            except OSError, e:
                if e.errno == 17:
                    logging.info('Already initialized')

            # create a temporary hook key/val
            key = 'hooks.{hook_type}.placeholder'.format(hook_type=hook)
            val = 'true'
            try:
                git.config('--get', key)
            except ErrorReturnCode_1:
                git.config('--add', key, val)

        hooks_added.append(hook)
Example #22
0
  def untrack_file(self, path):
    """Stop tracking changes to path."""
    assert not os.path.isabs(path)

    gl_st, git_st, is_au = self._status_file(path)

    if gl_st.type == GL_STATUS_UNTRACKED:
      raise ValueError('File {0} is already untracked'.format(path))
    elif gl_st.type == GL_STATUS_IGNORED:
      raise ValueError(
          'File {0} is ignored. Edit the .gitignore file to stop ignoring '
          'file {0}'.format(path))
    elif gl_st.in_conflict:
      raise ValueError('File {0} has conflicts'.format(path))

    # If we reached this point we know that the file to untrack is a tracked
    # file. This means that in the Git world, the file could be either:
    #   (i)  a new file for Git that is staged (the user executed `gl track` on
    #        an uncomitted file) => reset changes;
    #   (ii) the file is a previously committed file => mark it as assumed
    #        unchanged.
    if git_st == pygit2.GIT_STATUS_INDEX_NEW:  # Case (i)
      with self._index as index:
        index.remove(path)
    elif not is_au:  # Case (ii)
      git('update-index', '--assume-unchanged', path,
          _cwd=self.gl_repo.root)
    else:
      raise GlError('File {0} in unkown status {1}'.format(path, git_st))
def set_remote_url(git_dir, url):
    try:
        git('-C', git_dir, 'remote', 'set-url', 'origin', url)
    except ErrorReturnCode as e:
        return failed_util_call_results(e)
    else:
        return succeeded_util_call_results(None) 
Example #24
0
  def track_file(self, path):
    """Start tracking changes to path."""
    assert not os.path.isabs(path)

    gl_st, git_st, is_au = self._status_file(path)

    if gl_st.type == GL_STATUS_TRACKED:
      raise ValueError('File {0} is already tracked'.format(path))
    elif gl_st.type == GL_STATUS_IGNORED:
      raise ValueError(
          'File {0} is ignored. Edit the .gitignore file to stop ignoring '
          'file {0}'.format(path))

    # If we reached this point we know that the file to track is a untracked
    # file. This means that in the Git world, the file could be either:
    #   (i)  a new file for Git => add the file;
    #   (ii) an assumed unchanged file => unmark it.
    if git_st == pygit2.GIT_STATUS_WT_NEW:  # Case (i)
      with self._index as index:
        index.add(path)
    elif is_au:  # Case (ii)
      git('update-index', '--no-assume-unchanged', path,
          _cwd=self.gl_repo.root)
    else:
      raise GlError('File {0} in unkown status {1}'.format(path, git_st))
    def test_master_grab_changesets(self):
        # Grabs branch from a "remote" depot.

        # Remote repository
        self.add_content_to_repo(
            os.path.join(FIXTURE_PATH, 'fixture-2.git.bundle'), 'remote')

        dcvs = DepotOperations()

        dcvs.init_depot(
            os.path.join(self.environment_path, 'master'),
            parent=None,
            source=os.path.join(self.environment_path, 'remote'))

        # Changeset both there
        self.assertEquals(
            True, dcvs.grab_changesets(
                os.path.join(self.environment_path, 'master'),
                os.path.join(self.environment_path, 'remote'),
                ['my-branch1']))

        # Check availability
        sh.git('log', '4632aa0b30c65cd1c6ec978d2905836ae65509ed',
               _cwd=os.path.join(self.environment_path, 'master'))

        # Changesets not there
        self.assertTrue(
            dcvs.grab_changesets(
                os.path.join(self.environment_path, 'master'),
                os.path.join(self.environment_path, 'remote'),
                ['c377d40d21153bdcc4ec0b24bba48af3899fcc7x',
                    'b93d349f220d892047817f7ab29b2e8bfc5569bx']))
def main():
    if len(sys.argv) == 2:
        sh.cd(sys.argv[1])
        print(sh.git("status"))
        print("(Y/n): Are you sure you want to reset this directory?")
        temp = str(input("Local changes will be deleted: "))
        if temp=="y" or temp =="Y":
            print(sh.git.reset("--hard", "HEAD"))
            print(sh.git.clean("-f"))
            print(sh.git.pull)
            print(sh.git("status"))
        else:
            sys.exit(0)

    else:
        print(sh.git("status"))
        print("(Y/n): Are you sure you want to reset this directory?")
        temp = str(input("Local changes will be deleted: "))
        if temp=="y" or temp =="Y":
            print(sh.git.reset("--hard", "HEAD"))
            print(sh.git.clean("-f"))
            print(sh.git.pull)
            print(sh.git("status"))
        else:
            sys.exit(0)
Example #27
0
 def _create_simple_commit(self, message):
     """ Creates a simple commit with an empty test file.
         :param message: Commit message for the commit. """
     test_filename = "test-file-" + str(uuid4())
     touch(test_filename, _cwd=self.tmp_git_repo)
     git("add", test_filename, _cwd=self.tmp_git_repo)
     git("commit", "-m", message, _cwd=self.tmp_git_repo)
Example #28
0
    def grab_changesets(self, path, url, changesets):
        """
        Inherited method :func:`~DepotOperations.grab_changesets`
        """
        logger.debug('Grabbing changesets from %s to %s' % (url, path))
        # Force handling it as a bare repository so even current branch can be
        # overwritten by fetch
        git_path = os.path.join(
            path,
            sh.git('rev-parse', '--git-dir', _cwd=path).strip())
        logger.debug("Executing git -c core.bare=true fetch " + url + " +refs/*:refs/* on " + git_path)
        output = sh.git('-c', 'core.bare=true', 'fetch',
                        url,
                        '+refs/*:refs/*',
                        _cwd=git_path,
                        _err_to_out=True)
        logger.debug("Output:\n%s" % output)
        if sh.git('rev-parse', '--is-bare-repository', _cwd=path).strip() == 'false':
            self._clear_working_copy(path)
        self._save_state(path)

        for c in changesets:
            try:
                sh.git('log', '-1', c, _cwd=path, _tty_out=False)
            except sh.ErrorReturnCode as e:
                logger.debug('Error checking changeset %s: %s', c, e)
                return False
        return True
Example #29
0
    def add_to_blacklist(self, items_to_blacklist, username, code_permissions):
        # Check if we're on master
        if git("rev-parse", "--abbrev-ref", "HEAD").strip() != "master":
            return (False, "Not currently on master.")

        # Check that we're up-to-date with origin (GitHub)
        git.remote.update()
        if git("rev-parse", "refs/remotes/origin/master").strip() != git("rev-parse", "master").strip():
            return (False, "HEAD isn't at tip of origin's master branch")

        # Check that blacklisted_websites.txt isn't modified locally. That could get ugly fast
        if "blacklisted_websites.txt" in git.status():  # Also ugly
            return (False, "blacklisted_websites.txt modified locally. This is probably bad.")

        # Store current commit hash
        current_commit = git("rev-parse", "HEAD").strip()

        # Add items to file
        with open("blacklisted_websites.txt", "a+") as blacklisted_websites:
            last_character = blacklisted_websites.read()[-1:]
            if last_character != "\n":
                blacklisted_websites.write("\n")
            blacklisted_websites.write("\n".join(items_to_blacklist) + "\n")

        # Checkout a new branch (mostly unnecessary, but may help if we create PRs in the future
        branch = "auto-blacklist-{0}".format(str(time.time()))
        git.checkout("-b", branch)

        # Clear HEAD just in case
        git.reset("HEAD")

        git.add("blacklisted_websites.txt")
        git.commit("-m", "Auto blacklist of {0} by {1} --autopull".format(", ".join(items_to_blacklist), username))

        if code_permissions:
            git.checkout("master")
            git.merge(branch)
            git.push()
        else:
            git.push("origin", branch)
            git.checkout("master")

            if GlobalVars.github_username is None or GlobalVars.github_password is None:
                return (False, "tell someone to set a GH password")

            payload = {"title": "{0}: Blacklist {1}".format(username, ", ".join(items_to_blacklist)),
                       "body": "{0} requests blacklist of domains: \n\n - {1}".format(username, "\n - ".join(items_to_blacklist)),
                       "head": branch,
                       "base": "master"}
            response = requests.post("https://api.github.com/repos/Charcoal-SE/SmokeDetector/pulls", auth=HTTPBasicAuth(GlobalVars.github_username, GlobalVars.github_password), data=json.dumps(payload))
            print(response.json())
            return (True, "You don't have code privileges, but I've [created a pull request for you]({0}).".format(response.json()["html_url"]))

        git.checkout(current_commit)  # Return to old commit to await CI. This will make Smokey think it's in reverted mode if it restarts

        if not code_permissions:
            return (False, "Unable to perform action due to lack of code-level permissions. [Branch pushed](https://github.com/Charcoal-SE/SmokeDetector/tree/{0}), PR at your leisure.".format(branch))

        return (True, "Blacklisted {0} - the entry will be applied via autopull if CI succeeds.".format(", ".join(items_to_blacklist)))
Example #30
0
 def push_to_github(self):
     with CdContext(self.book.local_path):
         try:
             sh.git.push('origin', 'master')
         except sh.ErrorReturnCode_128:
             logging.error(u"github repo not ready yet")
             time.sleep(10)
             sh.git('push', 'origin', 'master')
Example #31
0
def get_git_references(git_address, project_id):
    resetEnv()
    os.chdir('/tmp')
    logger.debug('Getting git ref : git ls-remote {}'.format(git_address))
    fullRefs = git('ls-remote', git_address)
    fullRefs = fullRefs.splitlines()

    ref = [
        refs.split('\t')[1].replace('refs/', '').replace('heads/', '')
        for refs in fullRefs
    ]

    ref = [refs for refs in ref if refs != 'HEAD']

    return json.dumps(ref)
Example #32
0
def check_git_repo(git_path):
    """
    make sure there's actually a git repo initialized and
    check the git-diff exit code for changes if it exists

    git-diff exit codes:
    - 0: no changes
    - 1: changes
    - 129: no git repo
    """
    os.chdir(git_path)
    changed = False
    created = False
    try:
        git("diff", "--exit-code")
    except sh.ErrorReturnCode_1:
        changed = True
    except sh.ErrorReturnCode_129:
        click.echo("no git repo found; initializing a new repo")
        git.init()
        git.add(".")
        click.echo(git.commit('-m"Initial commit"'))
        created = True
    return created, changed
Example #33
0
def checandpAtualizacoes(diretorio):
    print("Comparando versão local com a remota em: " + diretorio)

    # Pegando a versão mais recente
    git("--git-dir=" + diretorio + ".git/",
        "--work-tree=" + diretorio,
        "fetch",
        "origin",
        "master",
        _out_bufsize=0,
        _tty_in=True)

    time.sleep(1)
    print("Checando o status do diretório...")
    statusCheck = git("--git-dir=" + diretorio + ".git/",
                      "--work-tree=" + diretorio, "status")

    # Resposta do git ao realizar um fetch
    if "Your branch is up-to-date" in statusCheck:
        print("Diretório atualizado.")
        return False
    else:
        print("Atualizações disponíveis")
        return True
Example #34
0
def deploy():
    build()
    proj()

    root_sha = sh.git("rev-parse", "HEAD")

    sh.cd("dist")

    sh.git.commit("-am", "'Automatic build from %s'" % root_sha)

    sh.git.push("origin", "gh-pages")

    proj()
    sh.git.add("dist")
    sh.git.status()
Example #35
0
 def get_git_matches(self, revision):
     try:
         return str(
             git('grep',
                 '-i',
                 '-e',
                 '"({})"'.format(r'\|'.join(self.keywords)),
                 revision,
                 _tty_out=False))
     # return subprocess.check_output('git grep -i -e "(api\\|key\\|username\\|user\\|pw\\|password\\|pass\\|email\\|mail)" -- `git ls-files | grep -v .html` | cat', shell=True).decode('utf8')
     except sh.ErrorReturnCode_1:
         return ''
     except:
         print('encoding error at revision: ', revision)
         return ''
Example #36
0
    def _status_file(self, path):
        assert not os.path.isabs(path)

        git_st = self.gl_repo.git_repo.status_file(path)

        root = self.gl_repo.root
        cmd_out = stdout(git('ls-files', '-v', '--full-name', path, _cwd=root))
        is_au = cmd_out and cmd_out[0] == 'h'
        if is_au:
            exists_in_wd = os.path.exists(os.path.join(root, path))
            f_st = self.FileStatus(path, GL_STATUS_UNTRACKED, True,
                                   exists_in_wd, True, False)
        else:
            f_st = self.FileStatus(path, *self._st_map[git_st])
        return f_st, git_st, is_au
Example #37
0
    def git_log_cmp(self, branch_1, branch_2):
        """Does branch_1 contain commits which aren't in branch_2?

        Here we call out to an external "git log" process - I couldn't
        work out a way to compute this result using gitpython.

        """
        os.chdir(os.path.join(self.path, self.name))
        args = (
            '--no-pager',
            'log',
            '--format=oneline',
            '{0}..{1}'.format(branch_1.name, branch_2.name),
        )
        return bool(sh.git(args).stdout.decode('utf-8').strip())
Example #38
0
def setup_stress(stress_revision):
    stress_path = None

    try:
        git_id = sh.git('--git-dir={home}/fab/cassandra.git'.format(home=HOME),
                        'rev-parse', stress_revision).strip()
    except sh.ErrorReturnCode:
        raise AssertionError(
            'Invalid stress_revision: {}'.format(stress_revision))

    path = os.path.join(CASSANDRA_STRESS_PATH, git_id)
    if not os.path.exists(path):
        logger.info("Building cassandra-stress '{}' in '{}'.".format(
            stress_revision, path))
        os.makedirs(path)
        sh.tar(
            sh.git("--git-dir={home}/fab/cassandra.git".format(home=HOME),
                   "archive", git_id), 'x', '-C', path)
        antcmd('-Dbasedir={}'.format(path), '-f', '{}/build.xml'.format(path),
               'realclean', 'jar')

    stress_path = os.path.join(path, 'tools/bin/cassandra-stress')

    return stress_path
Example #39
0
 def find_WIP_branches(self, study_id):
     pat = re.compile(r'.*_study_{i}_[0-9]+'.format(i=study_id))
     head_shas = git(self.gitdir, self.gitwd, "show-ref", "--heads")
     ret = {}
     #_LOG.debug('find_WIP_branches head_shas = "{}"'.format(head_shas.split('\n')))
     for lin in head_shas.split('\n'):
         try:
             local_branch_split = lin.split(' refs/heads/')
             if len(local_branch_split) == 2:
                 sha, branch = local_branch_split
                 if pat.match(branch) or branch == 'master':
                     ret[branch] = sha
         except:
             raise
     return ret
Example #40
0
def make_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument("--root-dir", default=".")
    parser.add_argument("--unix-path", default="unix/Cargo.toml")
    parser.add_argument("--glutin-path", default="glutin/Cargo.toml")
    parser.add_argument("--release", action="store_true", default=False)
    parser.add_argument("--target-dir", default="target")
    parser.add_argument("--output-dir", default="uploads")
    parser.add_argument("--name", required=True)
    parser.add_argument("--os", required=True, choices=["linux", "macos"])
    parser.add_argument("--macos-app-name", required=False, type=str)
    parser.add_argument(
        "--branch", default=sh.git("rev-parse", "--abbrev-ref", "HEAD").strip()
    )
    return parser
Example #41
0
    def test_config_from_file_debug(self):
        commit_msg = u"WIP: Thïs is a title thåt is a bit longer.\nContent on the second line\n" + \
                     "This line of the body is here because we need it"
        self._create_simple_commit(commit_msg)
        commit_sha = self.get_last_commit_hash()
        config_path = self.get_sample_path("config/gitlintconfig")
        output = gitlint("--config",
                         config_path,
                         "--debug",
                         _cwd=self.tmp_git_repo,
                         _tty_in=True,
                         _ok_code=[5])

        expected_date = git("log",
                            "-1",
                            "--pretty=%ai",
                            _cwd=self.tmp_git_repo)
        expected_date = arrow.get(str(expected_date),
                                  "YYYY-MM-DD HH:mm:ss Z").datetime
        expected_gitlint_version = gitlint("--version").replace(
            "gitlint, version ", "").replace("\n", "")
        expected_git_version = git("--version").replace("\n", "")

        expected = self.get_expected(
            'debug_output1', {
                'platform': platform.platform(),
                'python_version': sys.version,
                'git_version': expected_git_version,
                'gitlint_version': expected_gitlint_version,
                'config_path': config_path,
                'target': self.tmp_git_repo,
                'commit_sha': commit_sha,
                'commit_date': expected_date
            })

        self.assertEqual(output, expected)
Example #42
0
def get_version(repos, version):
    if version is not None and version != 'nightly':
        return version

    m = hashlib.sha256()
    for repo in repos:
        version = "unknown"
        with push_pop(repo):
            try:
                version = git("describe").strip()
            except:
                pass
        m.update(version)

    return "{0}-{1}".format(str(datetime.date.today()), m.hexdigest()[:8])
Example #43
0
def list_all(ctx,
             apps_folder: Path,
             ls_remote: bool,
             verbose: int,
             verbose_inf: bool,
             ):

    tty, verbose = tv(ctx=ctx,
                      verbose=verbose,
                      verbose_inf=verbose_inf,
                      )

    apps_folder = Path(apps_folder)
    ic(apps_folder)

    edit_configs = find_edit_configs(apps_folder=apps_folder,
                                     verbose=verbose,
                                     )
    for config in edit_configs:
        if verbose:
            ic(config)
        if ls_remote:
            project_dir = config.parent
            return_code = None
            if verbose:
                ic(project_dir)
            with chdir(project_dir):
                try:
                    sh.git('ls-remote')
                    return_code = 0
                except sh.ErrorReturnCode_128:
                    return_code = 128

            print(return_code, config.parent.name)
        else:
            print(config.parent.name)
def main():
    github_remote_url = f"{get_github_url()}/{get_input('target_remote')}.git"
    work_dir = pathlib.Path(get_input("work_dir"))
    if work_dir.is_dir() and len(list(work_dir.iterdir())) > 0:
        os.chdir(work_dir)
        remote = "origin"
        if get_input("source_remote_name") == remote:
            remote = remote + "2"
        add_or_set_git_remote(remote, github_remote_url)
        git.fetch(remote)
        git.checkout("-B", get_input("target_branch"),
                     f"{remote}/{get_input('target_branch')}")
        git.reset("--hard", "HEAD")
        git.clean("-fdx")
    else:
        git.clone("--branch", get_input("target_branch"), github_remote_url,
                  str(work_dir))
        os.chdir(work_dir)

    if get_input("target_remote") != get_input("source_remote"):
        source_remote_name = get_input("source_remote_name")
        add_or_set_git_remote(
            source_remote_name,
            f"{get_github_url()}/{get_input('source_remote')}.git")
        git.fetch(source_remote_name)

    set_git_author_info(f"GitHub Action {os.environ['GITHUB_ACTION']}",
                        "action@localhost")

    try:
        git("cherry-pick", get_input("source_commits"))
        print("Source commits were cherry-picked successfully",
              file=sys.stderr)
    except sh.ErrorReturnCode:
        print("Source commits could not be cherry-picked", file=sys.stderr)
        raise
Example #45
0
    def clone(self):
        """ clones a book from GITenberg's repo into the library
        assumes you are authenticated to git clone from repo?
        returns True/False, message
        """
        # FIXME: check if this works from a server install
        logging.debug("Attempting to clone {0}".format(
            self.book_repo_name.repo_name))

        if self.path_exists():
            return False, "Error: Local clone of {0} already exists".format(
                self.book_repo_name.repo_name)

        # TODO: rewrite using github3.py's git module
        try:
            sh.git('clone', self.book_repo_name.get_clone_url_ssh(),
                   self.library_book_dir())
            return True, "Success! Cloned {0}".format(
                self.book_repo_name.repo_name)
        except sh.ErrorReturnCode_128:
            # TODO: log exception information here on debug
            logging.debug(
                "clone ran into an issue, likely this already exists")
            return False, "Error sh.py returned with a fail code"
Example #46
0
def main():
  """A thin wrapper around perf_ab_test that restores git state after."""
  options, args = parse_options()

  os.chdir(IMPALA_HOME)

  if sh.git("status", "--porcelain", "--untracked-files=no", _out=None).strip():
    sh.git("status", "--porcelain", "--untracked-files=no", _out=sys.stdout)
    raise Exception("Working copy is dirty. Consider 'git stash' and try again.")

  # Save the current hash to be able to return to this place in the tree when done
  current_hash = sh.git("rev-parse", "--abbrev-ref", "HEAD").strip()
  if current_hash == "HEAD":
    current_hash = get_git_hash_for_name("HEAD")

  try:
    workloads = backup_workloads()
    perf_ab_test(options, args)
  finally:
    # discard any changes created by the previous restore_workloads()
    shutil.rmtree("testdata/workloads")
    sh.git.checkout("--", "testdata/workloads")
    sh.git.checkout(current_hash)
    restore_workloads(workloads)
Example #47
0
    def test_commit_hook_edit(self):
        self.responses = ["e", "y"]
        env = {"EDITOR": ":"}
        test_filename = self._create_simple_commit(
            u"WIP: This ïs a title.\nContënt on the second line",
            out=self._interact,
            env=env,
            tty_in=True)
        git("rm", "-f", test_filename, _cwd=self.tmp_git_repo)

        short_hash = git("rev-parse",
                         "--short",
                         "HEAD",
                         _cwd=self.tmp_git_repo,
                         _tty_in=True).replace("\n", "")

        # Determine short commit-msg hash, needed to determine expected output

        expected_output = self._violations()
        expected_output += [
            'Continue with commit anyways (this keeps the current commit message)? '
            + '[y(es)/n(no)/e(dit)] ' + self._violations()[0]
        ]
        expected_output += self._violations()[1:]
        expected_output += [
            'Continue with commit anyways (this keeps the current commit message)? '
            + "[y(es)/n(no)/e(dit)] " +
            u"[master %s] WIP: This ïs a title. Contënt on the second line\n" %
            short_hash, " 1 file changed, 0 insertions(+), 0 deletions(-)\n",
            u" create mode 100644 %s\n" % test_filename
        ]

        assert len(self.githook_output) == len(expected_output)
        for output, expected in zip(self.githook_output, expected_output):
            self.assertMultiLineEqual(output.replace('\r', ''),
                                      expected.replace('\r', ''))
Example #48
0
    def pull(self, remote, revision=None, branch=None):
        """Inherited method
        :func:`~repoman.repository.Repository.pull`
        """
        git_dir = os.path.join(
            self.path,
            sh.git('rev-parse', '--git-dir', _cwd=self.path).strip())
        git = GitCmd(git_dir)

        refspec = '+refs/*:refs/*'
        if branch != None:
            refspec = '+refs/heads/%s:refs/heads/%s' % (branch, branch)

        git('-c', 'core.bare=true', 'fetch', remote, refspec)
        self._clean()
Example #49
0
def generate_full_docs(args):
    """Regenerate the documentation for all plugins listed in the plugin_to_collection_file."""
    # imports here so that they don't cause unnecessary deps for all of the plugins
    import sh
    from antsibull.cli import antsibull_docs

    with TemporaryDirectory() as tmp_dir:
        sh.git(['clone', 'https://github.com/ansible-community/ansible-build-data'], _cwd=tmp_dir)
        # If we want to validate that the ansible version and ansible-base branch version match,
        # this would be the place to do it.

        build_data_working = os.path.join(tmp_dir, 'ansible-build-data')

        ansible_version = args.ansible_version
        if ansible_version is None:
            ansible_version = find_latest_ansible_dir(build_data_working)

        latest_filename = find_latest_deps_file(build_data_working, ansible_version)

        # Make a copy of the deps file so that we can set the ansible-base version we'll use
        modified_deps_file = os.path.join(tmp_dir, 'ansible.deps')
        shutil.copyfile(latest_filename, modified_deps_file)

        # Put our version of ansible-base into the deps file
        with open(modified_deps_file, 'r') as f:
            deps_data = yaml.safe_load(f.read())

        deps_data['_ansible_base_version'] = ansible_base__version__

        with open(modified_deps_file, 'w') as f:
            f.write(yaml.dump(deps_data))

        # Generate the plugin rst
        return antsibull_docs.run(['antsibull-docs', 'stable', '--deps-file', modified_deps_file,
                                   '--ansible-base-source', str(args.top_dir),
                                   '--dest-dir', args.output_dir])
Example #50
0
def buildForReal(site_branch):
    # make sure there are no local mods outstanding
    repo = Repo(os.getcwd())
    if repo.is_dirty() or repo.untracked_files:
        print "ERROR: Your working directory has outstanding changes."
        print "Commit or stash them."
        return

    mygit = Git(os.getcwd())
    cfg = config.load_config()

    # sanity check that the version branches exist as named
    for version in cfg['extra']['versions']:
        print 'Verifying branch %s' % (version['branch'])
        mygit.checkout(version['branch'])

    # sanity check - only one latest
    latest = False
    for version in cfg['extra']['versions']:
        if not latest and version['latest']:
            print 'Latest is %s' % (version['branch'])
            latest = True
        elif latest and version['latest']:
            print 'ERROR: More than one version is latest.'
            print 'Only one version can be latest: True.'
            print 'Check mkdocs.yml.'
            return

    mygit.checkout(site_branch)
    print "Building site pages from: %s..." % (site_branch)
    sh.rm('-rf', 'site')
    sh.mkdocs('build', '--clean')

    for version in cfg['extra']['versions']:
        sh.git('checkout', version['branch'], '--', 'docs', 'mkdocs.yml')
        deployVersion(version)
Example #51
0
    def get_last_id(self, branch):
        LOG.debug('Get head commit for repo uri: %s', self.repo['uri'])

        os.chdir(self.folder)
        if not self._checkout(branch):
            return None

        try:
            return str(sh.git('rev-parse', 'HEAD')).strip()
        except sh.ErrorReturnCode as e:
            LOG.error('Unable to get HEAD for git repo %s. Ignore it',
                      self.repo['uri'])
            LOG.exception(e)

        return None
Example #52
0
    def _is_commit_hash(self, revision):
        """
        Returns True is revision is a valid commit hash, False otherwise.

        ***NOTE***:
        This test invokes git rev-parse in the current working directory and will fail
        if git is not installed or run outside of a git workspace.

        >>> class worker:
        ...   app = {}
        ...   job = None
        ...   log_file = None
        ...   _config = None

        >>> Deploy(worker=worker())._is_commit_hash('HEAD')
        False

        >>> Deploy(worker=worker())._is_commit_hash('master')
        False

        >>> Deploy(worker=worker())._is_commit_hash('dev')
        False

        >>> current_git_hash = git('--no-pager', 'rev-parse', 'HEAD', _tty_out=False).strip()
        >>> Deploy(worker=worker())._is_commit_hash(current_git_hash)
        True

        The length of a valid abbreviated hash depends on the current repository:

        >>> shortest_hash = git('--no-pager', 'rev-parse', '--short', 'HEAD', _tty_out=False).strip()
        >>> Deploy(worker=worker())._is_commit_hash(current_git_hash[:len(shortest_hash)])
        True

        Very short substrings won't match:

        >>> Deploy(worker=worker())._is_commit_hash(current_git_hash[:3])
        False
        """

        resolved_revision = ''
        try:
            # git rev-parse returns a complete hash from an abbreviated hash, if valid
            resolved_revision = git('--no-pager', 'rev-parse', revision, _tty_out=False).strip()
        except:
            pass

        # If resolved_revision begins with or equals revision, it is a commit hash
        return resolved_revision.find(revision) == 0
Example #53
0
def pre_execute():

    global EXECLIST
    global CMD_FILE

    if len(EXECLIST) == 0:
        #nothing to do
        lg.warning("nothing to execute")
        exit(-1)

    lg.debug("number of commands to execute: %d", len(EXECLIST))

    cmdlist = []
    global_meta = EXECLIST[0]['_global_meta']
    template_name = util.get_template_name(global_meta)

    for i, meta in enumerate(EXECLIST):
        cmd = util.get_jinja_template(meta, 'command.template',
                                      'executor/' + EXECNAME)
        cmd = util.recursive_render(cmd, meta)
        if i == 0:
            print(cmd)

        meta['_cmd_file'] = util.script_write(cmd, './kea2',
                                              meta.get('_uid', template_name))
        cmdrunner = util.get_jinja_template(meta, 'command_runner.template',
                                            'executor/' + EXECNAME)
        cmdrunner = util.recursive_render(cmdrunner, meta)
        cmdlist.append(cmdrunner)

    global_meta['commandlist'] = cmdlist

    try:
        output = git('rev-parse')
        ingit = True
        lg.debug("In a git repository - add & commit the script")
    except ErrorReturnCode as e:
        lg.info("not git - backing up the cmd file")
        ingit = False

    runsh = util.get_jinja_template(meta, 'run.template',
                                    'executor/' + EXECNAME).render(global_meta)

    lg.info("write command script: %s", CMD_FILE)
    CMD_FILE = util.script_write(runsh,
                                 '.',
                                 template_name,
                                 backup_dir='./kea2/backup')
Example #54
0
 def setUp(self):
     self.dir = tempfile.mkdtemp()
     sh.cd(self.dir)
     sh.git.init()
     sh.git('config', 'user.name', '"Daniël"')
     sh.git('config', 'user.email', '"*****@*****.**"')
     sh.touch('README')
     sh.git.add('README')
     sh.git.commit('-m', 'first commit')
     sh.git('remote', 'add', 'origin', 'https://github.com/username/Hello-World.git')
Example #55
0
    def __init__(self, working_directory, branch_name):
        self.target_branch = branch_name
        self.target_file = "readme.txt"

        self._working_directory = working_directory
        self._repo = git.Repo.init(unicode(working_directory))
        self._repo.daemon_export = True
        self._daemon_started = False

        def std_redirect(line):
            print "[git daemon] " + line
            if "Ready to rumble" in line:
                self._daemon_started = True

        port = utils.get_open_port()
        # We use this URL for now while docker works in 'host' mode
        # In 'host' mode host localhost is container localhost
        self.url = "git://127.0.0.1:" + unicode(port) + unicode(
            working_directory)

        # pylint: disable = unexpected-keyword-arg, too-many-function-args
        # module sh built-in alias for sh.Command('git') causes pylint warnings
        self._daemon = sh.git("daemon",
                              "--verbose",
                              "--listen=127.0.0.1",
                              "--port=" + unicode(port),
                              "--enable=receive-pack",
                              unicode(working_directory),
                              _iter=True,
                              _bg_exc=False,
                              _bg=True,
                              _out=std_redirect,
                              _err=std_redirect)

        configurator = self._repo.config_writer()
        configurator.set_value("user", "name", "Testing user")
        configurator.set_value("user", "email", "*****@*****.**")
        self._file = self._working_directory.join(self.target_file)
        self._file.write("")

        self._repo.index.add([unicode(self._file)])
        self._repo.index.commit("initial commit")
        self._commit_count = 0

        self._branch = self._repo.create_head(branch_name)

        while not self._daemon_started:
            sleep(1)
Example #56
0
    def _git_commit(commit_message):
        """
        Do a git commit in the current directory with the given commit
        message (without adding any changes). Instead of using a Git wrapper
        library, we directly call the Git binaries using :mod:`sh`, which
        ensures that error return codes are either handled or raised.

        If the :option:`DEBUG` setting is set, a Git push is attempted after
        commiting.

        Args:
            commit_message (str): Single-line commit message

        Returns:
            *True* if a commit has been made and `False` if there weren't any
            changes.

        Raises:
            :exc:`sh.ErrorReturnCode` exception in case of failure.

        """

        # This is, of course, not the most sophisticated approach at
        # interacting with Git but hey, it's simple and it works. Any error
        # code != 0 results in an exception, so there's little risk of
        # silent failure. We should probably replace this with GitPython or
        # any of the full-featured command-line wrappers at some point in
        # the future, but as long as all we're doing is automated commits,
        # it's perfectly fine.

        # Check if there are any staged changes, abort if not (git commit
        # would return an error otherwise).

        if len(git("diff-index", "--name-only", "HEAD", "--")):
            git.commit(message=commit_message)

            # Doing a git push inside the handler means that the entire task
            # would fail if the push fails. Doing a push once per run is
            # sufficient, so only push inside the task handler in debug mode.

            if settings.DEBUG:
                git.push()

            changes = True
        else:
            changes = False

        return changes
    def run(self):
        self.prepare()
        # TODO: testing an old self.commit range that doesn't end
        # with HEAD is most likely a mistake. Should warn, see
        # https://github.com/zephyrproject-rtos/ci-tools/pull/24
        codeowners = os.path.join(git_top, "CODEOWNERS")
        if not os.path.exists(codeowners):
            self.skip("CODEOWNERS not available in this repo")

        commit = sh.git("diff","--name-only", "--diff-filter=A", self.commit_range, **sh_special_args)
        new_files = commit.splitlines()
        logging.debug("New files %s", new_files)

        if not new_files:
            # TODO: parse CODEOWNERS to report errors in it *without*
            # scanning the tree to keep this case very fast.
            return

        # Convert to pathlib.Path string representation (e.g.,
        # backslashes 'dir1\dir2\' on Windows) to be consistent
        # with self.ls_owned_files()
        new_files = [str(Path(f)) for f in new_files]

        logging.info("If this takes too long then cleanup and try again")
        patrn2files = self.ls_owned_files(codeowners)

        new_not_owned = []
        for newf in new_files:
            f_is_owned = False

            for git_pat, owned in patrn2files.items():
                logging.debug("Scanning %s for %s", git_pat, newf)

                if newf in owned:
                    logging.info("%s matches new file %s", git_pat, newf)
                    f_is_owned = True
                    # Unlike github, we don't care about finding any
                    # more specific owner.
                    break

            if not f_is_owned:
                new_not_owned.append(newf)

        if new_not_owned:
            self.add_failure("New files added that are not covered in "
                             "CODEOWNERS:\n\n" + "\n".join(new_not_owned) +
                             "\n\nPlease add one or more entries in the "
                             "CODEOWNERS file to cover those files")
Example #58
0
def repository(namespace, name, branch='master'):
    '''Returns a repository'''
    with TemporaryDirectory() as download_path:
        old_directory = str(pwd()).strip()
        try:
            git.clone('https://github.com/{0}/{1}.git'.format(namespace, name),
                      download_path)
            cd(download_path)
            git.fetch('origin', branch)
            git.checkout(branch)
            yield (download_path, git('rev-parse', 'HEAD'),
                   redis.Dict(key="{0}.{1}".format(namespace, name)))
        except ErrorReturnCode_128:
            mkdir(download_path)
            yield (None, None, None)
        cd(old_directory)
def get_hits(defname,files=()):
    cs=set()
    for f in files:
        try:
            r=sh.git('blame', '-L', '/def\s*{start}/,/def/'.format(start=defname),f,_tty_out=False)
        except sh.ErrorReturnCode_128:
            logger.debug("no matches in %s" % f)
            continue

        lines = r.strip().splitlines()[:-1]
        # remove comment lines
        lines = [x for x in lines if not re.search("^\w+\s*\(.+\)\s*#",x)]
        hits = set(map(lambda x: x.split(" ")[0],lines))
        cs.update(set(Hit(commit=c,path=f) for c in hits))

    return cs
Example #60
0
def github_url(match) -> Optional[str]:
    repo, *path = match["path"].parts
    if repo in _repos:
        revision = _repos[repo]
    else:
        try:
            ret = git("-C", repo, "rev-parse", "--short", "HEAD")
        except sh.ErrorReturnCode:
            return None
        revision = str(ret).strip()
        _repos[repo] = revision
    org = "alphagov"
    line_number = f"L{match['line_number']}"
    return (
        f"https://github.com/{org}/{repo}/blob/{revision}/{Path(*path)}#{line_number}"
    )