예제 #1
0
    def perform(self):
        for i in listdir(self.entry.path):
            if i.lower() == 'readme.md' and i != 'README.md':
                shutil.move(join(self.entry.path, i), join(self.entry.path, 'README.md'))

        creator = CreateAction(None, self.entry.name.replace('-skill', ''))
        creator.path = self.entry.path
        creator.initialize_template({'.git', '.gitignore', 'README.md'})
        self.git.add('README.md')
        creator.commit_changes()
        skill_repo = creator.create_github_repo(lambda: input('Repo name:'))
        if skill_repo:
            self.entry.url = skill_repo.html_url
            self.entry.author = self.user.login
        else:
            skill_repo = self.github.get_repo(skill_repo_name(self.entry.url))

        if not skill_repo.permissions.push:
            print('Warning: You do not have write permissions to the provided skill repo.')
            if ask_yes_no('Create a fork and use that instead? (Y/n)', True):
                skill_repo = self.user.create_fork(skill_repo)
                print('Created fork:', skill_repo.html_url)
                self.git.remote('rename', 'origin', 'upstream')
                self.git.remote('add', 'origin', skill_repo.html_url)

        self.entry.name = input('Enter a unique skill name (ie. npr-news or grocery-list): ')

        readme_file = {i.lower(): i for i in os.listdir(self.entry.path)}['readme.md']
        readme = read_file(self.entry.path, readme_file)

        last_section = None
        sections = {last_section: ''}
        for line in readme.split('\n'):
            line = line.strip()
            if line.startswith('#'):
                last_section = line.strip('# ').lower()
                sections[last_section] = ''
            else:
                sections[last_section] += '\n' + line
        del sections[None]

        if 'description' in sections:
            description = sections['description']
        else:
            description = ask_choice(
                'Which section contains the description?', list(sections),
                on_empty='Please create a description section in the README'
            )

        branch = SkillData(self.entry).add_to_repo()
        self.repo.push_to_fork(branch)

        pull = create_or_edit_pr(
            title='Add {}'.format(self.entry.name), body=body_template.format(
                description=description, skill_name=self.entry.name, skill_url=skill_repo.html_url
            ), user=self.user, branch=branch, skills_repo=self.repo.hub
        )

        print('Created pull request: ', pull.html_url)
예제 #2
0
class SkillData(GlobalContext):
    def __init__(self, skill: SkillEntry):
        self.entry = skill

    name = property(lambda self: self.entry.name)
    repo = Lazy(lambda s: RepoData())  # type: RepoData
    repo_git = Lazy(lambda s: Git(join(s.repo.msminfo.path, s.submodule_name)))  # type: Git
    git = Lazy(lambda s: Git(s.entry.path))  # type: Git
    hub = Lazy(lambda s: s.github.get_repo(skill_repo_name(s.entry.url)))  # type: Repository

    @Lazy
    def submodule_name(self):
        name_to_path = {name: path for name, path, url, sha in self.repo.msminfo.get_skill_data()}
        if self.name not in name_to_path:
            raise NotUploaded('The skill {} has not yet been uploaded to the skill store'.format(
                self.name
            ))
        return name_to_path[self.name]

    def upgrade(self) -> str:
        skill_module = self.submodule_name
        self.repo.msminfo.update()
        self.repo_git.fetch()
        default_branch = self.repo_git.symbolic_ref('refs/remotes/origin/HEAD')
        self.repo_git.reset(default_branch, hard=True)

        upgrade_branch = 'upgrade/' + self.name
        self.repo.checkout_branch(upgrade_branch)

        if not self.repo.git.diff(skill_module) and self.repo.git.ls_files(skill_module):
            raise AlreadyUpdated(
                'The latest version of {} is already uploaded to the skill repo'.format(
                    self.name
                )
            )
        self.repo.git.add(skill_module)
        self.repo.git.commit(message='Upgrade ' + self.name)
        return upgrade_branch

    def add_to_repo(self) -> str:
        self.repo.msminfo.update()
        elements = [i.split() for i in self.git.ls_tree('HEAD').split('\n')]
        existing_mods = [folder for size, typ, sha, folder in elements]
        if self.name not in existing_mods:
            self.repo.git.submodule('add', self.entry.url, self.name)

        # Upgrade skill in case it is outdated
        self.repo_git.fetch()
        default_branch = self.repo_git.symbolic_ref('refs/remotes/origin/HEAD')
        self.repo_git.reset(default_branch, hard=True)

        branch_name = 'add/' + self.name
        self.repo.checkout_branch(branch_name)
        self.repo.git.add(self.name)
        self.repo.git.commit(message='Add ' + self.name)
        return branch_name

    def init_existing(self):
        self.repo.git.submodule('update', '--init', self.submodule_name)
예제 #3
0
class RepoData(GlobalContext):
    msminfo = Lazy(lambda s: s.msm.repo)  # type: SkillRepo
    git = Lazy(lambda s: Git(s.msminfo.path))  # type: Git
    hub = Lazy(lambda s: s.github.get_repo(skill_repo_name(s.msminfo.url)))  # type: Repository
    fork = Lazy(lambda s: s.github.get_user().create_fork(s.hub))  # type: Repository

    def push_to_fork(self, branch: str):
        remotes = self.git.remote().split('\n')
        command = 'set-url' if 'fork' in remotes else 'add'
        self.git.remote(command, 'fork', self.fork.html_url)

        # Use call to ensure the environment variable GIT_ASKPASS is used
        call(['git', 'push', '-u', 'fork', branch, '--force'], cwd=self.msminfo.path)

    def checkout_branch(self, branch):
        with suppress(GitCommandError):
            self.git.branch('-D', branch)
        try:
            self.git.checkout(b=branch)
        except GitCommandError:
            self.git.checkout(branch)
예제 #4
0
    def perform(self):
        print('Uploading a new skill to the skill repo...')

        for i in listdir(self.entry.path):
            if i.lower() == 'readme.md' and i != 'README.md':
                shutil.move(join(self.entry.path, i),
                            join(self.entry.path, 'README.md'))

        creator = CreateAction(None, self.entry.name.replace('-skill', ''))
        creator.path = self.entry.path
        creator.initialize_template({'.git', '.gitignore', 'README.md'})
        self.git.add('README.md')
        creator.commit_changes()

        try:
            skill_repo = creator.create_github_repo(
                lambda: input('Repo name:'))
        except GithubRepoExists:
            try:
                print("A repository with that name already exists")
                skill_repo = creator.link_github_repo(
                    lambda: input('Remote repo name:'))
            except UnrelatedGithubHistory:
                print("Repository history does not seem to be related")
                skill_repo = creator.force_push(
                    lambda: input('Confirm repo name:'))
        if skill_repo:
            self.entry.url = skill_repo.html_url
            self.entry.author = self.user.login
        else:
            if not self.entry.url:
                raise NoGitRepository
            skill_repo = self.github.get_repo(skill_repo_name(self.entry.url))

        if not skill_repo.permissions.push:
            print(
                'Warning: You do not have write permissions to the provided skill repo.'
            )
            if ask_yes_no('Create a fork and use that instead? (Y/n)', True):
                skill_repo = self.user.create_fork(skill_repo)
                print('Created fork:', skill_repo.html_url)
                self.git.remote('rename', 'origin', 'upstream')
                self.git.remote('add', 'origin', skill_repo.html_url)

        # verify that the required files exists in origin and contain the
        # required content.
        if not self.check_valid():
            print("Please add the missing information and rerun the command.")
            return

        self.entry.name = input(
            'Enter a unique skill name (ie. npr-news or grocery-list): ')

        readme_file = {i.lower(): i
                       for i in os.listdir(self.entry.path)}['readme.md']
        readme = read_file(self.entry.path, readme_file)

        last_section = None
        sections = {last_section: ''}
        for line in readme.split('\n'):
            line = line.strip()
            if line.startswith('#'):
                last_section = line.strip('# ').lower()
                sections[last_section] = ''
            else:
                sections[last_section] += '\n' + line
        del sections[None]

        if 'about' in sections:
            description = sections['about']
        elif 'description' in sections:
            description = sections['description']

        branch = SkillData(self.entry).add_to_repo()
        self.repo.push_to_fork(branch)

        pull = create_or_edit_pr(title='Add {}'.format(self.entry.name),
                                 body=body_template.format(
                                     description=description,
                                     skill_name=self.entry.name,
                                     skill_url=skill_repo.html_url),
                                 user=self.user,
                                 branch=branch,
                                 skills_repo=self.repo.hub,
                                 repo_branch=self.branch)

        print('Created pull request: ', pull.html_url)