コード例 #1
0
    def Run(self, args):
        """Clone a GCP repository to the current directory.

    Args:
      args: argparse.Namespace, the arguments this command is run with.

    Returns:
      The path to the new git repository.
    """
        # Ensure that we're logged in.
        c_store.Load(use_google_auth=True)

        res = sourcerepo.ParseRepo(args.src)
        source_handler = sourcerepo.Source()

        repo = source_handler.GetRepo(res)
        if hasattr(repo, 'mirrorConfig') and repo.mirrorConfig:
            mirror_url = repo.mirrorConfig.url
            self.ActionIfMirror(project=res.projectsId,
                                repo=args.src,
                                mirror_url=mirror_url)
        # do the actual clone
        git_helper = git.Git(res.projectsId, args.src, uri=repo.url)
        path = git_helper.Clone(destination_path=args.dst or args.src,
                                dry_run=args.dry_run,
                                full_path=self.UseFullGcloudPath(args))
        if path and not args.dry_run:
            log.status.write('Project [{prj}] repository [{repo}] was cloned '
                             'to [{path}].\n'.format(prj=res.projectsId,
                                                     path=path,
                                                     repo=args.src))
コード例 #2
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
  def testForcePushFilesToBranchNoCredHelper(self):
    self.git_version_mock.return_value = 'git version 1.7.9'
    self.StartObjectPatch(git, '_GetGcloudScript', return_value='gcloud')
    properties.VALUES.core.account.Set('fake-git-account')
    subprocess_mock = self.StartObjectPatch(subprocess, 'check_call')
    temp_path = '/tmp/path'
    self.StartObjectPatch(
        file_utils.TemporaryDirectory, '__enter__', return_value=temp_path)
    self.StartObjectPatch(file_utils, 'RmTree')
    abspath_mock = self.StartObjectPatch(os.path, 'abspath')
    abspath_mock.side_effect = (
        lambda p: p if p.startswith('/') else '/'.join(['/dir', p]))

    repo_url = 'https://source.developers.google.com/p/fake-project/r/fake-repo'
    repo = git.Git('fake-project', 'fake-repo')

    expected_calls = [mock.call(['git', 'init', temp_path])]

    def add_expected_call(*args):
      git_dir = '--git-dir=' + os.path.join(temp_path, '.git')
      work_tree = '--work-tree=/dir'
      expected_calls.append(mock.call(['git', git_dir, work_tree] + list(args)))

    add_expected_call('checkout', '-b', 'branch1')
    add_expected_call('add', '/dir/file1', '/dir/dir2/file2')
    add_expected_call('commit', '-m', 'source capture uploaded from gcloud')
    add_expected_call('remote', 'add', 'origin', repo_url)
    add_expected_call('push', '-f', 'origin', 'branch1')

    repo.ForcePushFilesToBranch(
        'branch1', '/dir', ['/dir/file1', '/dir/dir2/file2'])

    self.assertEqual(expected_calls, subprocess_mock.call_args_list)
コード例 #3
0
    def Run(self, args):
        """Clone a GCP repository to the current directory.

    Args:
      args: argparse.Namespace, the arguments this command is run with.

    Raises:
      ToolException: on project initialization errors.

    Returns:
      The path to the new git repository.
    """
        # Ensure that we're logged in.
        c_store.Load()

        project_id = properties.VALUES.core.project.Get(required=True)
        project_repo = git.Git(project_id, args.src)
        path = project_repo.Clone(destination_path=args.dst or args.src,
                                  dry_run=args.dry_run)
        if path and not args.dry_run:
            log.status.write(
                'Project [{prj}] repository [{repo}] was cloned to '
                '[{path}].\n'.format(prj=project_id,
                                     path=path,
                                     repo=project_repo.GetName()))
コード例 #4
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
 def testCloneRepoDirExistsGitNotFound(self):
   self.git_version_mock.side_effect = OSError(errno.ENOENT, 'not found')
   project_repo = git.Git('fake-project', 'fake-repo')
   repo_path = self.CreateTempDir('repo-path')
   with self.assertRaisesRegex(
       git.NoGitException,
       re.escape('Cannot find git. Please install git and try again.')):
     project_repo.Clone(destination_path=repo_path)
コード例 #5
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
 def testCloneRemoteDoesntExist(self):
   project_repo = git.Git('fake-project', 'fake-repo')
   repo_path = self.CreateTempDir('repo-path')
   project_repo._uri = 'abcd'
   subprocess_mock = self.StartObjectPatch(subprocess, 'check_call')
   subprocess_mock.side_effect = subprocess.CalledProcessError(
       1, ('fatal: repository {0} does not exist'.format(project_repo._uri)))
   with self.assertRaisesRegex(
       git.CannotFetchRepositoryException,
       re.escape('fatal: repository abcd does not exist')):
     project_repo.Clone(destination_path=repo_path)
コード例 #6
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
 def testCloneRepoOldGitVersion_NoCredentialHelper(self):
   self.git_version_mock.return_value = 'git version 1.7.9'
   self.StartObjectPatch(git, '_GetGcloudScript', return_value='gcloud')
   project_repo = git.Git('fake-project', 'fake-repo')
   path = project_repo.Clone(destination_path='repo-path', dry_run=True)
   repo_path = os.path.abspath('repo-path')
   self.assertEqual(repo_path, path)
   self.AssertOutputEquals(
       'git clone '
       'https://source.developers.google.com/p/fake-project/r/fake-repo {0}\n'
       .format(repo_path))
コード例 #7
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
  def testForcePushFilesToBranchGitSubdirectory(self):
    repo = git.Git('fake-project', 'fake-repo')
    with self.assertRaisesRegex(
        git.CannotPushToRepositoryException,
        (r"Can't upload the file tree.*abc")):
      repo.ForcePushFilesToBranch('branch1', '/dir', ['/dir/.git/abc'])

    with self.assertRaisesRegex(
        git.CannotPushToRepositoryException,
        (r"Can't upload the file tree.*gitignore")):
      repo.ForcePushFilesToBranch('branch1', '/dir', ['/dir/sub/.gitignore'])
コード例 #8
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
 def testCloneRepoDirExistsIsNotEmpty(self):
   self.StartObjectPatch(git, '_GetGcloudScript', return_value='gcloud')
   self.StartObjectPatch(os, 'listdir')
   listdir_mock = self.StartObjectPatch(os, 'listdir')
   listdir_mock.return_value = ('test.txt')
   project_repo = git.Git('fake-project', 'fake-repo')
   repo_path = self.CreateTempDir('repo-path')
   with self.assertRaisesRegex(
       git.CannotInitRepositoryException,
       re.escape('Directory path specified exists and is not empty')):
     project_repo.Clone(destination_path=repo_path)
コード例 #9
0
    def Run(self, args):
        """Clone a GCP repository to the current directory.

    Args:
      args: argparse.Namespace, the arguments this command is run with.

    Raises:
      ToolException: on project initialization errors.
      RepoCreationError: on repo creation errors.

    Returns:
      The path to the new git repository.
    """
        # Ensure that we're logged in.
        c_store.Load()

        project_id = resolvers.FromProperty(properties.VALUES.core.project)
        res = resources.REGISTRY.Parse(args.src,
                                       params={'projectsId': project_id},
                                       collection='sourcerepo.projects.repos')
        source_handler = sourcerepo.Source()

        repo = source_handler.GetRepo(res)
        if not repo:
            message = ('Repository "{src}" in project "{prj}" does not '
                       'exist.\nList current repos with\n'
                       '$ gcloud beta source repos list\n'
                       'or create with\n'
                       '$ gcloud beta source repos create {src}'.format(
                           src=args.src, prj=res.projectsId))
            raise c_exc.InvalidArgumentException('REPOSITORY_NAME', message)
        if hasattr(repo, 'mirrorConfig') and repo.mirrorConfig:
            mirror_url = repo.mirrorConfig.url
            message = (
                'Repository "{src}" in project "{prj}" is a mirror. Clone the '
                'mirrored repository directly with \n$ git clone '
                '{url}'.format(src=args.src,
                               prj=res.projectsId,
                               url=mirror_url))
            raise c_exc.InvalidArgumentException('REPOSITORY_NAME', message)
        # do the actual clone
        git_helper = git.Git(res.projectsId, args.src, uri=repo.url)
        path = git_helper.Clone(destination_path=args.dst or args.src,
                                dry_run=args.dry_run,
                                full_path=args.use_full_gcloud_path)
        if path and not args.dry_run:
            log.status.write('Project [{prj}] repository [{repo}] was cloned '
                             'to [{path}].\n'.format(prj=res.projectsId,
                                                     path=path,
                                                     repo=args.src))
コード例 #10
0
  def Run(self, args):
    """Clone a GCP repository to the current directory.

    Args:
      args: argparse.Namespace, the arguments this command is run with.

    Raises:
      ToolException: on project initialization errors.
      RepoCreationError: on repo creation errors.

    Returns:
      The path to the new git repository.
    """
    # Ensure that we're logged in.
    c_store.Load()

    project_id = resolvers.FromProperty(properties.VALUES.core.project)
    res = resources.REGISTRY.Parse(
        args.src,
        params={'projectsId': project_id},
        collection='sourcerepo.projects.repos')
    source_handler = sourcerepo.Source()

    # Check for the existence of the named repo in the project and maybe ask
    # the user whether they want to create it if it does not already exist.
    #
    # Note that repo creation can fail if there is a concurrent attempt to
    # create the repo (e.g. through another call to gcloud or a concurrent
    # attempt in the developer console through a browser).
    repo = source_handler.GetRepo(res)
    if not repo:
      message = ('Repository "{src}" in project "{prj}" does not yet '
                 'exist.'.format(src=args.src, prj=res.projectsId))
      prompt_string = 'Would you like to create it'
      if args.autocreate or console_io.PromptContinue(
          message=message, prompt_string=prompt_string, default=True):
        repo = source_handler.CreateRepo(res)
      else:
        message = ('Cannot clone from a non-existent repo. Please create it '
                   'with:\n  $ gcloud alpha source repos create {src}\n and '
                   'try cloning again.'.format(src=args.src))
        raise exceptions.InvalidUserInputError(message)
    # do the actual clone
    git_helper = git.Git(res.projectsId, args.src, uri=repo.url)
    path = git_helper.Clone(
        destination_path=args.dst or args.src, dry_run=args.dry_run)
    if path and not args.dry_run:
      log.status.write('Project [{prj}] repository [{repo}] was cloned '
                       'to [{path}].\n'.format(
                           prj=res.projectsId, path=path, repo=args.src))
コード例 #11
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
  def testCloneRepoWindowsGitSupportsCredHelperButNotEmptyHelper(self):
    self.git_version_mock.return_value = 'git version 2.10.0'

    self.StartObjectPatch(git, '_GetGcloudScript', return_value='gcloud')
    project_repo = git.Git('fake-project', 'fake-repo')
    path = project_repo.Clone(destination_path='repo-path')
    repo_path = os.path.abspath('repo-path')
    self.assertEqual(repo_path, path)
    self.AssertErrContains('gcloud auth print-access-token')
    self.assertEqual([
        mock.call([
            'git', 'clone',
            'https://source.developers.google.com/p/fake-project/r/fake-repo',
            repo_path
        ])
    ], self.clone_command_mock.call_args_list)
コード例 #12
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
  def testCloneRepo_DryRun(self):
    properties.VALUES.core.account.Set('fake-git-account')
    self.git_version_mock.return_value = 'git version 2.15.0'

    self.StartObjectPatch(git, '_GetGcloudScript', return_value='gcloud')
    project_repo = git.Git('fake-project', 'fake-repo')
    path = project_repo.Clone(destination_path='repo-path', dry_run=True)
    repo_path = os.path.abspath('repo-path')
    self.assertEqual(repo_path, path)
    self.AssertOutputContains(
        'git clone '
        'https://source.developers.google.com/p/fake-project/r/fake-repo {0} '
        '--config credential.helper= '
        '--config credential.helper='
        '!gcloud auth git-helper --account=fake-git-account '
        '--ignore-unknown $@'.format(repo_path))
コード例 #13
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
  def testCloneRepoGitSupportsEmptyHelper(self):
    properties.VALUES.core.account.Set('fake-git-account')
    self.git_version_mock.return_value = 'git version 2.15.0'

    self.StartObjectPatch(git, '_GetGcloudScript', return_value='gcloud')
    project_repo = git.Git('fake-project', 'fake-repo')
    path = project_repo.Clone(destination_path='repo-path')
    repo_path = os.path.abspath('repo-path')
    self.assertEqual(repo_path, path)
    self.assertEqual([
        mock.call([
            'git', 'clone',
            'https://source.developers.google.com/p/fake-project/r/fake-repo',
            repo_path, '--config', 'credential.helper=', '--config',
            'credential.helper='
            '!gcloud auth git-helper --account=fake-git-account '
            '--ignore-unknown $@'
        ])
    ], self.clone_command_mock.call_args_list)
コード例 #14
0
  def Run(self, args):
    """Clone a GCP repository to the current directory.

    Args:
      args: argparse.Namespace, the arguments this command is run with.

    Returns:
      The path to the new git repository.
    """
    # Ensure that we're logged in.
    c_store.Load()

    res = sourcerepo.ParseRepo(args.src)
    source_handler = sourcerepo.Source()

    repo = source_handler.GetRepo(res)
    if not repo:
      message = ('Repository "{src}" in project "{prj}" does not '
                 'exist.\nList current repos with\n'
                 '$ gcloud beta source repos list\n'
                 'or create with\n'
                 '$ gcloud beta source repos create {src}'.format(
                     src=args.src, prj=res.projectsId))
      raise c_exc.InvalidArgumentException('REPOSITORY_NAME', message)
    if hasattr(repo, 'mirrorConfig') and repo.mirrorConfig:
      mirror_url = repo.mirrorConfig.url
      self.ActionIfMirror(
          project=res.projectsId, repo=args.src, mirror_url=mirror_url)
    # do the actual clone
    git_helper = git.Git(res.projectsId, args.src, uri=repo.url)
    path = git_helper.Clone(
        destination_path=args.dst or args.src,
        dry_run=args.dry_run,
        full_path=self.UseFullGcloudPath(args))
    if path and not args.dry_run:
      log.status.write('Project [{prj}] repository [{repo}] was cloned '
                       'to [{path}].\n'.format(
                           prj=res.projectsId, path=path, repo=args.src))
コード例 #15
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
  def testCloneRepoOldGitVersion(self):
    self.git_version_mock.return_value = 'git version 1.7.9'
    self.StartObjectPatch(git, '_GetGcloudScript', return_value='gcloud')

    expected_min = '2.0.1'
    if (platforms.OperatingSystem.Current() == platforms.OperatingSystem.WINDOWS
       ):
      expected_min = '2.15.0'
    project_repo = git.Git('fake-project', 'fake-repo')
    repo_path = os.path.abspath('repo-path')
    project_repo.Clone(destination_path=repo_path, dry_run=True)
    self.AssertErrContains(
        textwrap.dedent("""\
    WARNING: You are using a Google-hosted repository with a
    git version {current} which is older than {min_version}. If you upgrade
    to {min_version} or later, gcloud can handle authentication to
    this repository. Otherwise, to authenticate, use your Google
    account and the password found by running the following command.
     $ gcloud auth print-access-token
               """.format(current='1.7.9', min_version=expected_min)))
    self.AssertOutputEquals(
        'git clone '
        'https://source.developers.google.com/p/fake-project/r/fake-repo {0}\n'
        .format(repo_path))
コード例 #16
0
    def Upload(self, branch, root_path, ignore_file=None):
        """Uploads files to a branch in Cloud Source Repositories.

    Args:
      branch: (string) The name of the branch to upload to. If empty, a
        name will be generated.
      root_path: (string) The path of a directory tree to upload.
      ignore_file: (string) The file overrides the `.gcloudignore` file and
        uses the specified file instead.

    Returns:
      A dictionary containing various status information:
        'branch': The name of the branch.
        'source_contexts': One or more dictionaries compatible with the
          ExtendedSourceContext message, including one context pointing
          to the upload. This context will be the only one with the value
          'capture' for its 'category' label.
        'files_written': The number of files uploaded.
        'files_skipped': The number of files skipped.
        'size_written': The total number of bytes in all files uploaded.
    """
        try:
            sourcerepo.Source().GetRepo(sourcerepo.ParseRepo(UPLOAD_REPO_NAME))
        except exceptions.HttpNotFoundError:
            raise RepoNotFoundError(
                REPO_NOT_FOUND_ERROR.format(UPLOAD_REPO_NAME,
                                            self._project_id))

        file_chooser = gcloudignore.GetFileChooserForDir(
            root_path, write_on_disk=False, ignore_file=ignore_file)
        branch = branch or (_GetNow().strftime(TIME_FORMAT) + '.' +
                            _GetUuid().hex)
        all_paths = [
            os.path.join(root_path, f)
            for f in file_chooser.GetIncludedFiles(root_path,
                                                   include_dirs=False)
        ]
        paths = [
            f for f in all_paths if not os.path.islink(f)
            and os.path.getsize(f) <= self.SIZE_THRESHOLD
        ]
        git.Git(self._project_id, UPLOAD_REPO_NAME).ForcePushFilesToBranch(
            branch, root_path, sorted(paths))

        source_context = {
            'context': {
                'cloudRepo': {
                    'repoId': {
                        'projectRepoId': {
                            'projectId': self._project_id,
                            'repoName': UPLOAD_REPO_NAME
                        }
                    },
                    'aliasContext': {
                        'kind': 'MOVABLE',
                        'name': branch
                    }
                }
            },
            'labels': {
                'category': 'capture'
            }
        }

        return {
            'branch': branch,
            'source_contexts': [source_context],
            'files_written': len(paths),
            'files_skipped': len(all_paths) - len(paths),
            'size_written': sum([os.path.getsize(f) for f in paths])
        }
コード例 #17
0
    def Upload(self, branch, root_path):
        """Uploads files to a branch in Cloud Source Repositories.

    Args:
      branch: (string) The name of the branch to upload to. If empty, a
        name will be generated.
      root_path: (string) The path of a directory tree to upload.

    Returns:
      A dictionary containing various status information:
        'branch': The name of the branch.
        'source_contexts': One or more dictionaries compatible with the
          ExtendedSourceContext message, including one context pointing
          to the upload. This context will be the only one with the value
          'capture' for its 'category' label.
        'files_written': The number of files uploaded.
        'files_skipped': The number of files skipped.
        'size_written': The total number of bytes in all files uploaded.
    """
        if not sourcerepo.Source().GetRepo(
                sourcerepo.ParseRepo(UPLOAD_REPO_NAME)):
            raise exceptions.Error(
                REPO_NOT_FOUND_ERROR.format(UPLOAD_REPO_NAME,
                                            self._project_id))

        branch = branch or (_GetNow().strftime(TIME_FORMAT) + '.' +
                            _GetUuid().hex)
        all_paths = [
            f
            for f in self._ignore_handler.GetFiles(os.path.abspath(root_path))
            if not os.path.islink(f)
        ]
        paths = [
            f for f in all_paths if os.path.getsize(f) <= self.SIZE_THRESHOLD
        ]
        git.Git(self._project_id, UPLOAD_REPO_NAME).ForcePushFilesToBranch(
            branch, root_path, paths)

        source_context = {
            'context': {
                'cloudRepo': {
                    'repoId': {
                        'projectRepoId': {
                            'projectId': self._project_id,
                            'repoName': UPLOAD_REPO_NAME
                        }
                    },
                    'aliasContext': {
                        'kind': 'MOVABLE',
                        'name': branch
                    }
                }
            },
            'labels': {
                'category': 'capture'
            }
        }

        return {
            'branch': branch,
            'source_contexts': [source_context],
            'files_written': len(paths),
            'files_skipped': len(all_paths) - len(paths),
            'size_written': sum([os.path.getsize(f) for f in paths])
        }
コード例 #18
0
ファイル: git_test.py プロジェクト: piotradamczyk5/gcloud_cli
 def testNoCredentialHelper(self, subprocess_mock):
   subprocess_mock.return_value = ''
   project_repo = git.Git('fake-project', 'fake-repo')
   project_repo.Clone('dest', dry_run=True)
   self.AssertErrNotContains('cancel')