Exemplo n.º 1
0
def configure(log_level=logging.INFO):
    """Allow the user to write a new configuration file.

    Returns:
        int: An exit status.
    """
    user_config = UserConfig()

    # Walk the user through basic configuration.
    setup_logging(log_level)
    logger.info('Welcome to artman. We will get you configured.')
    logger.info('When this is done, config will be stored in ~/.artman/config.yaml.')
    logger.info('')

    # Go through each step.
    # These are split out to make testing them easier.
    user_config.local.CopyFrom(_configure_local_config())

    try:
        config_dir = os.path.expanduser('~/.artman/')
        os.makedirs(config_dir)
    except OSError:
        pass
    _write_pb_to_yaml(user_config, os.path.join(config_dir, 'config.yaml'))
    logger.success('Configuration written successfully to '
                   '~/.artman/config.yaml.')
Exemplo n.º 2
0
def configure(log_level=logging.INFO):
    """Allow the user to write a new configuration file.

    Returns:
        int: An exit status.
    """
    user_config = UserConfig()

    # Walk the user through basic configuration.
    setup_logging(log_level)
    logger.info('Welcome to artman. We will get you configured.')
    logger.info(
        'When this is done, config will be stored in ~/.artman/config.yaml.')
    logger.info('')

    # Go through each step.
    # These are split out to make testing them easier.
    user_config.local.CopyFrom(_configure_local_config())

    try:
        config_dir = os.path.expanduser('~/.artman/')
        os.makedirs(config_dir)
    except OSError:
        pass
    _write_pb_to_yaml(user_config, os.path.join(config_dir, 'config.yaml'))
    logger.success('Configuration written successfully to '
                   '~/.artman/config.yaml.')
Exemplo n.º 3
0
 def execute(self, repo_url, username, password, publish_env, package_dir):
     self.exec_command([
         package_dir + '/gradlew', 'uploadArchives',
         '-PmavenRepoUrl=' + repo_url, '-PmavenUsername='******'-PmavenPassword='******'-p' + package_dir
     ])
     logger.success('Generated code uploaded to Maven: {}'.format(repo_url))
Exemplo n.º 4
0
 def execute(self, repo_url, username, password, publish_env,
             package_dir):
     self.exec_command(
         [package_dir + '/gradlew',
          'uploadArchives',
          '-PmavenRepoUrl=' + repo_url,
          '-PmavenUsername='******'-PmavenPassword='******'-p' + package_dir])
     logger.success('Generated code uploaded to Maven: {}'.format(repo_url))
Exemplo n.º 5
0
    def execute(self, gapic_code_dir, grpc_code_dir=None):
        """Emit a success message. No publishing is being done.

        Args:
            gapic_code_dir (str): The current GAPIC code location.
            grpc_code_dir (str): The current GRPC code location, if any.
        """
        userhome = os.path.expanduser('~')
        gapic_loc = os.path.realpath(gapic_code_dir).replace(userhome, '~')
        logger.success('Code generated: {0}'.format(gapic_loc))
        if grpc_code_dir:
            grpc_loc = os.path.realpath(grpc_code_dir).replace(userhome, '~')
            logger.success('GRPC code generated: {0}'.format(grpc_loc))
Exemplo n.º 6
0
    def execute(self, git_repo, github, branch_name, api_name, api_version,
                language):
        """Create a pull request on GitHub.

        Args:
            api_version (str): The version of the API. Used in the title of
                the pull request.
            language (str): The name of the language. Used in the title
                of the pull request.
        """
        # Determine the pull request title.
        pr_title = '{language} GAPIC: {api_name} {api_version}'.format(
            api_name=api_name.capitalize(),
            api_version=api_version,
            language=language.capitalize(),
        )

        # Determine the repo owner and name from the location, which is how
        # this API expects to receive this data.
        repo_loc = git_repo['location'].rstrip('/')
        repo_owner, repo_name = repo_loc.split(':')[-1].split('/')[-2:]
        if repo_name.endswith('.git'):
            repo_name = repo_name[:-4]

        # Instantiate the repo object.
        gh = github3.login(github['username'], github['token'])
        repo = gh.repository(repo_owner, repo_name)

        # Create the pull request.
        pr = repo.create_pull(
            base=git_repo.get('branch', 'master'),
            body='This pull request was generated by artman. '
                 'Please review it thoroughly before merging.',
            head=branch_name,
            title=pr_title,
        )

        # If we did not successfully create a pull request, this is an
        # error.
        if not pr:
            logger.error('Failed to create a pull request. You will need to '
                         'create a PR manually.')
            raise RuntimeError('Pull request creation failed.')

        # Log that the PR was created.
        logger.success('Pull request created: {url}'.format(
            url=pr.html_url,
        ))

        # Return back the pull request object.
        return pr
Exemplo n.º 7
0
    def execute(self, git_repo, github, branch_name, api_name, api_version,
                language):
        """Create a pull request on GitHub.

        Args:
            api_version (str): The version of the API. Used in the title of
                the pull request.
            language (str): The name of the language. Used in the title
                of the pull request.
        """
        # Determine the pull request title.
        pr_title = '{language} GAPIC: {api_name} {api_version}'.format(
            api_name=api_name.capitalize(),
            api_version=api_version,
            language=language.capitalize(),
        )

        # Determine the repo owner and name from the location, which is how
        # this API expects to receive this data.
        repo_loc = git_repo['location'].rstrip('/')
        repo_owner, repo_name = repo_loc.split(':')[-1].split('/')[-2:]
        if repo_name.endswith('.git'):
            repo_name = repo_name[:-4]

        # Instantiate the repo object.
        gh = github3.login(github['username'], github['token'])
        repo = gh.repository(repo_owner, repo_name)

        # Create the pull request.
        pr = repo.create_pull(
            base=git_repo.get('branch', 'master'),
            body='This pull request was generated by artman. '
            'Please review it thoroughly before merging.',
            head=branch_name,
            title=pr_title,
        )

        # If we did not successfully create a pull request, this is an
        # error.
        if not pr:
            logger.error('Failed to create a pull request. You will need to '
                         'create a PR manually.')
            raise RuntimeError('Pull request creation failed.')

        # Log that the PR was created.
        logger.success('Pull request created: {url}'.format(url=pr.html_url, ))

        # Return back the pull request object.
        return pr
Exemplo n.º 8
0
def configure(log_level=logging.INFO):
    """Allow the user to write a new configuration file.

    Returns:
        int: An exit status.
    """
    user_config = {}

    # Walk the user through basic configuration.
    setup_logging(log_level)
    logger.info('Welcome to artman. We will get you configured.')
    logger.info('When this is done, config will be stored in ~/.artman/config.yaml.')
    logger.info('')

    # Go through each step.
    # These are split out to make testing them easier.
    user_config['local_paths'] = _configure_local_paths(
        user_config.get('local_paths', {}),
    )
    user_config['publish'] = _configure_publish()
    if user_config['publish'] == 'github':
        user_config['github'] = _configure_github(
            user_config.get('github', {}),
        )

    # Write the final configuration.
    config_yaml = yaml.dump(user_config,
        block_seq_indent=2,
        default_flow_style=False,
        indent=2,
    )
    if isinstance(config_yaml, six.binary_type):
        config_yaml = config_yaml.decode('utf8')
    try:
        os.makedirs(os.path.expanduser('~/.artman/'))
    except OSError:
        pass
    with io.open(os.path.expanduser('~/.artman/config.yaml'), 'w+') as file_:
        file_.write(u'---\n')
        file_.write(config_yaml)
    logger.success('Configuration written successfully to '
                   '~/.artman/config.yaml.')
Exemplo n.º 9
0
    def execute(self, git_repo, output_dir,
        gapic_code_dir=None, grpc_code_dir=None, proto_code_dir=None,
        local_repo_dir=None):
        """Copy the code to the correct local staging location.

        Args:
            gapic_code_dir (str): The location of the GAPIC code.
            git_repo (dict): Information about the git repository.
            output_dir (str): The original base output dir. This directory
                is removed after proper local code staging unless removing
                it would remove the final destination directories.
            grpc_code_dir (str): The location of the GRPC code, if any.
        """
        # Determine the actual repository name.
        # We can use this to derive the probable OS system path.
        repo_name = git_repo['location'].rstrip('/').split('/')[-1]
        if repo_name.endswith('.git'):
            repo_name = repo_name[:-4]

        # Artman will find the local repo dir via the following steps:
        # 1. Check whether an explicit `--local_repo_dir` flag is passed. Is so,
        #    use that value.
        # 2. Clones the repo to output_dir, and use the cloned repo dir.
        repo_name_underscore = repo_name.replace('-', '_')
        if local_repo_dir:
            api_repo = local_repo_dir
        else:
            api_repo = os.path.join(output_dir, repo_name)
            if os.path.exists(api_repo):
                logger.fatal(
                    'Local repo folder `%s` exists. Please manually remove the '
                    'folder, or point to another folder through artman user '
                    'config or `artman --output-dir` flag.' % api_repo)
            repo = git_repo['location']
            # This only works for public repo for now.
            if repo.startswith('[email protected]:'):
                repo = 'https://github.com/%s' % repo[15:]
            logger.info('Checking out fresh clone of %s.' % repo)
            self.exec_command(['git', 'clone', repo, api_repo])

        # Track our code directories, and use absolute paths, since we will
        # be moving around.
        code_dirs = {}
        if gapic_code_dir:
            code_dirs['gapic'] = os.path.abspath(gapic_code_dir)
        if grpc_code_dir:
            code_dirs['grpc'] = os.path.abspath(grpc_code_dir)
        if proto_code_dir:
            code_dirs['proto'] = os.path.abspath(proto_code_dir)

        if not code_dirs:
            raise RuntimeError('No code path is defined.')

        # Keep track of all destinations so we are not too eager on wiping
        # out code from the original output area.
        #
        # This also allows useful output to the user in the success message.
        dests = []

        # Sanity check: The git repository must explicitly define the paths
        # where the generated code goes. If that is missing, fail now.
        if not git_repo.get('paths'):
            raise RuntimeError('This git repository entry in the artman YAML '
                               'does not define module paths.')

        # Determine where the code belongs and stage it there.
        for path in git_repo['paths']:
            # Piece together where we are copying code from and to.
            if isinstance(path, (six.text_type, six.binary_type)):
                path = {'dest': path}
            artifact = path.get('artifact', 'gapic')

            if artifact in code_dirs:
                # Convert everything to an absolute path.
                src = os.path.abspath(os.path.join(code_dirs[artifact], path.get('src', '.')))
                dest = os.path.abspath(os.path.join(api_repo, path.get('dest', '.')))

                # All src path does not necessarily exist. For example, gapic src directory will
                # not be created for ProtoClientPipeline
                if os.path.isdir(src):
                    # Keep track of all code destinations, for output later.
                    dests.append(dest)

                    # Actually copy the code.
                    self.exec_command(['rm', '-rf', dest])
                    self.exec_command(['cp', '-rf', src, dest])

        # Remove the original paths.
        if gapic_code_dir and os.path.isdir(gapic_code_dir):
            self.exec_command(['rm', '-rf', gapic_code_dir])
        if grpc_code_dir and os.path.isdir(grpc_code_dir):
            self.exec_command(['rm', '-rf', grpc_code_dir])
        if not os.getenv('RUNNING_IN_ARTMAN_DOCKER'):
            if all([output_dir not in d for d in dests]) and os.path.isdir(output_dir):
                self.exec_command(['rm', '-rf', output_dir])

        # Log a useful success message.
        userhome = os.path.expanduser('~')
        for d in dests:
            location = d.replace(userhome, '~')
            logger.success('Code generated: {0}'.format(location))
Exemplo n.º 10
0
    def execute(self,
                git_repo,
                output_dir,
                gapic_code_dir=None,
                grpc_code_dir=None,
                proto_code_dir=None,
                local_repo_dir=None):
        """Copy the code to the correct local staging location.

        Args:
            gapic_code_dir (str): The location of the GAPIC code.
            git_repo (dict): Information about the git repository.
            output_dir (str): The original base output dir. This directory
                is removed after proper local code staging unless removing
                it would remove the final destination directories.
            grpc_code_dir (str): The location of the GRPC code, if any.
        """
        # Determine the actual repository name.
        # We can use this to derive the probable OS system path.
        repo_name = git_repo['location'].rstrip('/').split('/')[-1]
        if repo_name.endswith('.git'):
            repo_name = repo_name[:-4]

        # Artman will find the local repo dir via the following steps:
        # 1. Check whether an explicit `--local_repo_dir` flag is passed. Is so,
        #    use that value.
        # 2. Clones the repo to output_dir, and use the cloned repo dir.
        repo_name_underscore = repo_name.replace('-', '_')
        if local_repo_dir:
            api_repo = local_repo_dir
        else:
            api_repo = os.path.join(output_dir, repo_name)
            if os.path.exists(api_repo):
                logger.fatal(
                    'Local repo folder `%s` exists. Please manually remove the '
                    'folder, or point to another folder through artman user '
                    'config or `artman --output-dir` flag.' % api_repo)
            repo = git_repo['location']
            # This only works for public repo for now.
            if repo.startswith('[email protected]:'):
                repo = 'https://github.com/%s' % repo[15:]
            logger.info('Checking out fresh clone of %s.' % repo)
            self.exec_command(['git', 'clone', repo, api_repo])

        # Track our code directories, and use absolute paths, since we will
        # be moving around.
        code_dirs = {}
        if gapic_code_dir:
            code_dirs['gapic'] = os.path.abspath(gapic_code_dir)
        if grpc_code_dir:
            code_dirs['grpc'] = os.path.abspath(grpc_code_dir)
        if proto_code_dir:
            code_dirs['proto'] = os.path.abspath(proto_code_dir)

        if not code_dirs:
            raise RuntimeError('No code path is defined.')

        # Keep track of all destinations so we are not too eager on wiping
        # out code from the original output area.
        #
        # This also allows useful output to the user in the success message.
        dests = []

        # Sanity check: The git repository must explicitly define the paths
        # where the generated code goes. If that is missing, fail now.
        if not git_repo.get('paths'):
            raise RuntimeError('This git repository entry in the artman YAML '
                               'does not define module paths.')

        # Determine where the code belongs and stage it there.
        for path in git_repo['paths']:
            # Piece together where we are copying code from and to.
            if isinstance(path, (six.text_type, six.binary_type)):
                path = {'dest': path}
            artifact = path.get('artifact', 'gapic')

            if artifact in code_dirs:
                # Convert everything to an absolute path.
                src = os.path.abspath(
                    os.path.join(code_dirs[artifact], path.get('src', '.')))
                dest = os.path.abspath(
                    os.path.join(api_repo, path.get('dest', '.')))

                # All src path does not necessarily exist. For example, gapic src directory will
                # not be created for ProtoClientPipeline
                if os.path.isdir(src):
                    # Keep track of all code destinations, for output later.
                    dests.append(dest)

                    # Actually copy the code.
                    self.exec_command(['rm', '-rf', dest])
                    self.exec_command(['cp', '-rf', src, dest])

        # Remove the original paths.
        if gapic_code_dir and os.path.isdir(gapic_code_dir):
            self.exec_command(['rm', '-rf', gapic_code_dir])
        if grpc_code_dir and os.path.isdir(grpc_code_dir):
            self.exec_command(['rm', '-rf', grpc_code_dir])
        if not os.getenv('RUNNING_IN_ARTMAN_DOCKER'):
            if all([output_dir not in d
                    for d in dests]) and os.path.isdir(output_dir):
                self.exec_command(['rm', '-rf', output_dir])

        # Log a useful success message.
        userhome = os.path.expanduser('~')
        for d in dests:
            location = d.replace(userhome, '~')
            logger.success('Code generated: {0}'.format(location))
Exemplo n.º 11
0
    def execute(self, git_repo, local_paths, output_dir,
        gapic_code_dir=None, grpc_code_dir=None, proto_code_dir=None):
        """Copy the code to the correct local staging location.

        Args:
            gapic_code_dir (str): The location of the GAPIC code.
            git_repo (dict): Information about the git repository.
            local_paths (dict): Configured local paths; here we use it for
                knowing where api_client_staging is.
            output_dir (str): The original base output dir. This directory
                is removed after proper local code staging unless removing
                it would remove the final destination directories.
            grpc_code_dir (str): The location of the GRPC code, if any.
        """
        # Determine the actual repository name.
        # We can use this to derive the probable OS system path, as well
        # as the key we expect in `local_paths` for an override.
        repo_name = git_repo['location'].rstrip('/').split('/')[-1]
        if repo_name.endswith('.git'):
            repo_name = repo_name[:-4]

        # Where is the target git repo located?
        # Start by checking for an explicit path in `local_paths`, and then
        # if none is found, derive it from reporoot.
        repo_name_underscore = repo_name.replace('-', '_')
        api_repo = local_paths.get(repo_name_underscore,
            os.path.join(local_paths.get('reporoot', '..'), repo_name),
        )
        api_repo = os.path.realpath(os.path.expanduser(api_repo))

        # Track our code directories, and use absolute paths, since we will
        # be moving around.
        code_dirs = {}
        if gapic_code_dir:
            code_dirs['gapic'] = os.path.abspath(gapic_code_dir)
        if grpc_code_dir:
            code_dirs['grpc'] = os.path.abspath(grpc_code_dir)
        if proto_code_dir:
            code_dirs['proto'] = os.path.abspath(proto_code_dir)

        if not code_dirs:
            raise RuntimeError('No code path is defined.')

        # Keep track of all destinations so we are not too eager on wiping
        # out code from the original output area.
        #
        # This also allows useful output to the user in the success message.
        dests = []

        # Sanity check: The git repository must explicitly define the paths
        # where the generated code goes. If that is missing, fail now.
        if not git_repo.get('paths'):
            raise RuntimeError('This git repository entry in the artman YAML '
                               'does not define module paths.')
            
        # Determine where the code belongs and stage it there.
        for path in git_repo['paths']:
            # Piece together where we are copying code from and to.
            if isinstance(path, (six.text_type, six.binary_type)):
                path = {'dest': path}
            artifact = path.get('artifact', 'gapic')

            if artifact in code_dirs:
                # Convert everything to an absolute path.
                src = os.path.abspath(os.path.join(code_dirs[artifact], path.get('src', '.')))
                dest = os.path.abspath(os.path.join(api_repo, path.get('dest', '.')))

                # All src path does not necessarily exist. For example, gapic src directory will
                # not be created for ProtoClientPipeline
                if os.path.isdir(src):
                    # Keep track of all code destinations, for output later.
                    dests.append(dest)

                    # Actually copy the code.
                    self.exec_command(['rm', '-rf', dest])
                    self.exec_command(['cp', '-rf', src, dest])

        # Remove the original paths.
        if gapic_code_dir and os.path.isdir(gapic_code_dir):
            self.exec_command(['rm', '-rf', gapic_code_dir])
        if grpc_code_dir and os.path.isdir(grpc_code_dir):
            self.exec_command(['rm', '-rf', grpc_code_dir])
        if all([output_dir not in d for d in dests]) and os.path.isdir(output_dir):
            self.exec_command(['rm', '-rf', output_dir])

        # Log a useful success message.
        userhome = os.path.expanduser('~')
        for d in dests:
            location = d.replace(userhome, '~')
            logger.success('Code generated: {0}'.format(location))