Пример #1
0
    def _run_bin(self, cwd: pathlib.Path, cmd: str, *args):
        """
        Execute binary with arguments in specified directory.

        :param cwd: Directory in which the binary will be invoked
        :param cmd: Binary definition invoked with shell
        :param args:
        :raises exceptions.RepoException: If the binary exited with non-zero status
        :return:
        """
        os.chdir(str(cwd))
        full_cmd = f'{cmd} {" ".join(args)}'
        logger.info(f'Running shell command "{full_cmd}" with cwd={cwd}')

        r = subprocess.run(full_cmd, shell=True, capture_output=True)

        if r.returncode != 0:
            r.stderr and logger.debug(f'STDERR: {r.stderr.decode("utf-8")}')
            r.stdout and logger.debug(f'STDOUT: {r.stdout.decode("utf-8")}')
            raise exceptions.RepoException(
                f'\'{cmd}\' binary exited with non-zero code!')
Пример #2
0
    def _remove_glob(self, path: pathlib.Path, glob: str):
        """
        Removes all files from path that matches the glob string.

        :param path:
        :param glob:
        :return:
        """
        for path_to_delete in path.glob(glob):
            path_to_delete = path_to_delete.resolve()
            if not path_to_delete.exists():
                continue

            if path not in path_to_delete.parents:
                raise exceptions.RepoException(
                    f'Trying to delete file outside the repo temporary directory! {path_to_delete}'
                )

            if path_to_delete.is_file():
                path_to_delete.unlink()
            else:
                shutil.rmtree(str(path_to_delete))
Пример #3
0
    def __init__(self, git_repo_url, **kwargs):
        if not is_github_url(git_repo_url):
            raise exceptions.RepoException('The passed Git repo URL is not related to GitHub!')

        super().__init__(git_repo_url=git_repo_url, **kwargs)
Пример #4
0
    def bootstrap_repo(cls, config: config_module.Config, name=None, git_repo_url=None, branch=None, secret=None,
                       ipns_key=None, ipns_lifetime=None, pin=None, republish=None, after_publish_bin=None,
                       build_bin=None, publish_dir: typing.Optional[str] = None, ipns_ttl=None) -> 'GenericRepo':
        """
        Method that interactively bootstraps the repository by asking interactive questions.

        :param ipns_ttl:
        :param config:
        :param name:
        :param git_repo_url:
        :param branch:
        :param secret:
        :param ipns_key:
        :param ipns_lifetime:
        :param pin:
        :param republish:
        :param after_publish_bin:
        :param build_bin:
        :param publish_dir:
        :return:
        """

        git_repo_url = cls.bootstrap_property('Git repo URL', 'text', 'Git URL of the repo', git_repo_url,
                                              validate=lambda _, x: validate_repo(x))

        name = cls.bootstrap_property('Name', 'text', 'Name of the new repo', name,
                                      default=get_name_from_url(git_repo_url),
                                      validate=lambda _, x: validate_name(x, config)).lower()

        branch = cls.bootstrap_property('Branch name', 'text', 'Which branch name should be build?', branch,
                                        default=DEFAULT_BRANCH_PLACEHOLDER,
                                        validate=lambda _, x: validate_branch(git_repo_url, x))
        if branch == DEFAULT_BRANCH_PLACEHOLDER:
            branch = get_default_branch(git_repo_url)

        ipns_key, ipns_addr = bootstrap_ipns(config, name, ipns_key)

        if secret is None:
            secret = ''.join(
                secrets.choice(string.ascii_uppercase + string.digits) for _ in range(DEFAULT_LENGTH_OF_SECRET))

        pin = cls.bootstrap_property('Pin flag', 'confirm', 'Do you want to pin the published IPFS objects?', pin,
                                     default=True)

        if build_bin is None:
            build_bin = inquirer.shortcuts.text('Path to build binary, if you want to do some pre-processing '
                                                'before publishing', default='')

        if after_publish_bin is None:
            after_publish_bin = inquirer.shortcuts.text('Path to after-publish binary, if you want to do some '
                                                        'actions after publishing', default='')

        if publish_dir is None:
            publish_dir = inquirer.shortcuts.text('Directory to be published inside the repo. Path related to the root '
                                                  'of the repo', default='/')

        ipns_lifetime = ipns_lifetime or '24h'
        if not validate_time_span(ipns_lifetime):
            raise exceptions.RepoException('Passed lifetime is not valid! Supported units are: h(our), m(inute), '
                                           's(seconds)!')

        ipns_ttl = ipns_ttl or '15m'
        if not validate_time_span(ipns_ttl):
            raise exceptions.RepoException('Passed ttl is not valid! Supported units are: h(our), m(inute), '
                                           's(seconds)!')

        if ipns_key is None and after_publish_bin is None:
            raise exceptions.RepoException(
                'You have choose not to use IPNS and you also have not specified any after publish command. '
                'This does not make sense! What do you want to do with this setting?! I have no idea, so aborting!')

        return cls(config=config, name=name, git_repo_url=git_repo_url, branch=branch, secret=secret, pin=pin,
                   publish_dir=publish_dir,
                   ipns_key=ipns_key, ipns_addr=ipns_addr, build_bin=build_bin, after_publish_bin=after_publish_bin,
                   republish=republish, ipns_lifetime=ipns_lifetime, ipns_ttl=ipns_ttl)
Пример #5
0
def bootstrap_ipns(config: config_module.Config,
                   name: str,
                   ipns_key: str = None) -> typing.Tuple[str, str]:
    """
    Functions that handle bootstraping of IPNS informations.

    :param config:
    :param name:
    :param ipns_key:
    :return:
    """

    ipns_addr = None
    if ipns_key is None:
        wanna_ipns = inquirer.shortcuts.confirm(
            'Do you want to publish to IPNS?', default=True)

        if wanna_ipns:
            ipns_key = f'{IPNS_KEYS_NAME_PREFIX}_{name}'

            try:
                out = config.ipfs.key_gen(ipns_key, IPNS_KEYS_TYPE)
            except ipfsapi.exceptions.Error:
                use_existing = inquirer.shortcuts.confirm(
                    f'There is already IPNS key with name \'{ipns_key}\', '
                    f'do you want to use it?',
                    default=True)

                if use_existing:
                    keys = config.ipfs.key_list()
                    out = next(
                        (x for x in keys['Keys'] if x['Name'] == ipns_key),
                        None)

                    if out is None:
                        raise exceptions.RepoException(
                            'We were not able to generate or fetch the IPNS key'
                        )
                else:
                    while True:
                        ipns_key = inquirer.shortcuts.text(
                            'Then please provide non-existing name for the IPNS key'
                        )

                        try:
                            out = config.ipfs.key_gen(ipns_key, IPNS_KEYS_TYPE)
                            break
                        except ipfsapi.exceptions.Error:
                            click.echo(
                                'There is already existing key with this name!'
                            )
                            continue

            ipns_addr = f'/ipns/{out["Id"]}/'
    else:
        keys = config.ipfs.key_list()
        key_object = next((x for x in keys['Keys'] if x['Name'] == ipns_key),
                          None)
        if key_object is None:
            logger.info(
                'The passed IPNS key name \'{}\' was not found, generating new key with this name'
            )
            key_object = config.ipfs.key_gen(ipns_key, IPNS_KEYS_TYPE)

        ipns_addr = f'/ipns/{key_object["Id"]}/'

    return ipns_key, ipns_addr