Exemple #1
0
    def _GetRemoteHosts(self):
        remote_hosts = self._remote_hosts
        if remote_hosts is None:
            # Lazily-calculate (and then cache it).
            git = self.git
            from mu_repo.execute_command import ExecuteCommand
            output = ExecuteCommand(
                [git] + 'config --get-regexp mu-repo.remote-base-url'.split(), '.', return_stdout=True)

            remotes_hosts = []
            for line in output.splitlines():
                if line.startswith('mu-repo.remote-base-url '):
                    line = line[len('mu-repo.remote-base-url '):]
                    remotes_hosts.append(line)
            self._remote_hosts = remotes_hosts

        return self._remote_hosts
Exemple #2
0
    def _GetRemoteHosts(self):
        remote_hosts = self._remote_hosts
        if remote_hosts is None:
            # Lazily-calculate (and then cache it).
            git = self.git
            from mu_repo.execute_command import ExecuteCommand
            output = ExecuteCommand(
                [git] + 'config --get-regexp mu-repo.remote-base-url'.split(),
                '.',
                return_stdout=True)

            remotes_hosts = []
            for line in output.splitlines():
                if line.startswith('mu-repo.remote-base-url '):
                    line = line[len('mu-repo.remote-base-url '):]
                    remotes_hosts.append(line)
            self._remote_hosts = remotes_hosts

        return self._remote_hosts
def Run(params):
    '''
    This action will grab the latest version of mu-repo from the repository.
    '''
    import mu_repo
    import os.path
    repo_dir = os.path.dirname(os.path.dirname(mu_repo.__file__))
    if not os.path.exists(os.path.join(repo_dir, '.git')):
        Print(
            'Can only automatically update mu-repo if it was properly gotten from a git repository.'
        )
        return

    config = params.config
    git = config.git or 'git'
    ExecuteCommand([git, 'pull', '--rebase'], repo=repo_dir)
Exemple #4
0
def _Clone(remote, repo, params, other_cmd_line_args):
    created_dir = os.path.join('.', repo)
    if os.path.exists(os.path.join(created_dir, '.git')):
        # If it already exists, bail out!
        Print(
            'Skipping clone of: ${START_COLOR}%s${RESET_COLOR} because it already exists.'
            % (repo, ))
        return True

    remote_path = remote
    if not remote_path.endswith('/') and not remote_path.endswith('\\'):
        remote_path += '/'

    git = params.config.git
    ExecuteCommand([git, 'clone', '%s%s' % (remote_path, repo)] +
                   other_cmd_line_args, '.')
    if os.path.exists(os.path.join(created_dir, '.git')):
        return True
    return False
def Run(params):
    '''
    This action applies a pull request from github in a new branch. There can be no changes in the current repo. 
    
    To execute:
        mu github-pull user/repo.git:branch
    
    Will do the following:
    
        git checkout -b branch-pull-request
        git pull https://github.com/user/repo.git branch
        git checkout initial_branch
        git merge branch-pull-request --no-commit --no-ff
    '''

    config = params.config
    if len(config.repos) != 1:
        Print('Can only apply pull request for a single repo.')
        return

    if len(params.args) < 2:
        Print(
            'Expecting at least 1 argument. E.g.: user/repo.git:branch_to_merge'
        )
        return

    user_repo_and_branch = params.args[1]
    splitted = user_repo_and_branch.split(':')
    if len(splitted) != 2:
        Print('Expected: user/repo.git:branch. Received: %s' %
              (user_repo_and_branch))
        return
    user_repo, user_branch = splitted
    user = user_repo.split('/')[0]

    repo = iter(config.repos).next()

    git = config.git or 'git'
    cmd = [git, 'status', '--porcelain']
    stdout = ExecuteCommand(cmd, repo, return_stdout=True)

    if stdout:
        Print(
            'Unable to execute because there are changes in the working directory:\n',
            stdout)
        return

    repos_and_curr_branch = GetReposAndCurrBranch(params)
    if len(repos_and_curr_branch) != 1:
        Print('Must find a single repo with current branch. Found: %s' %
              (repos_and_curr_branch, ))
        return
    _local_repo, local_branch = repos_and_curr_branch[0]

    local_pull_request_branch = user_branch + '-' + user + '-pull-request'

    ExecuteCommand([git, 'checkout', '-b', local_pull_request_branch], '.')
    ExecuteCommand(
        [git, 'pull', 'https://github.com/' + user_repo, user_branch], '.')
    #    Exec([git, 'checkout', local_branch])
    #    Exec([git, 'merge', local_pull_request_branch, '--no-commit', '--no-ff'])

    msg = '\n'.join([
        '\n$If all went well, do:',
        '${START_COLOR}mu dd${RESET_COLOR} to see changes, then: ',
        '${START_COLOR}mu ac${RESET_COLOR} to commit changes (if all is OK): ',
        'To discard/forget this merge, do:',
        '${START_COLOR}mu reset --hard${RESET_COLOR}',
        '${START_COLOR}mu branch -D %s${RESET_COLOR}' %
        (local_pull_request_branch, ),
        'To merge this request:',
        '${START_COLOR}mu checkout %s${RESET_COLOR}' % (local_branch, ),
        '${START_COLOR}mu merge %s --no-commit --no-ff${RESET_COLOR}' %
        (local_pull_request_branch, ),
    ])
    Print(msg)
Exemple #6
0
def Run(params):
    '''
    This is the first action that should be run in a new mu installation. It'll ask for common
    things to configure git properly.
    
    Things not done here but which the user should still do:
    
    Set: GIT_SSH to point to plink.exe (and have pageant with the key already loaded).
    '''
    git = params.config.git or 'git'
    from mu_repo.execute_command import ExecuteCommand

    #--- Name
    user_name = raw_input('User name:').strip()
    if user_name:
        ExecuteCommand([git] + 'config --global user.name'.split() +
                       [user_name], '.')
    else:
        Print('Skipping user.name configuration.')

    #--- E-mail
    user_email = raw_input('\nUser e-mail:').strip()
    if user_email:
        ExecuteCommand([git] + 'config --global user.email'.split() +
                       [user_email], '.')
    else:
        Print('Skipping user.email configuration.')

    #--- Auto-crlf
    auto_crlf = raw_input(
        '\nAuto-crlf handling (default false, options: false, true, input):'
    ).strip().lower()
    if not auto_crlf:
        auto_crlf = 'false'

    if auto_crlf in ('false', 'true', 'input'):
        ExecuteCommand([git] + 'config --global core.autocrlf'.split() +
                       [auto_crlf], '.')
    else:
        Print(
            'Skipping core.autocrlf configuration (input: "%s" not recognized).'
            % (auto_crlf, ))

    config_date = raw_input(
        '\nConfig format.pretty for one line and set default to short? (default: y, options: y, n)'
    ).strip().lower()
    if not config_date:
        config_date = 'y'
    if config_date == 'y':
        ExecuteCommand([git] + [
            'config', '--global', 'format.pretty',
            '%h %ad %Cgreen%aN%Creset %s'
        ], '.')
        ExecuteCommand([git] + 'config --global log.date short'.split(), '.')

    wrap = raw_input(
        '\nShow logs wrapped? (i.e.: set less -r): (default: y, options: y, n)'
    ).strip().lower()
    if not wrap:
        wrap = 'y'
    if wrap == 'y':
        ExecuteCommand([git, 'config', '--global', 'core.pager', 'less -r'],
                       '.')

    wrap = raw_input(
        '\nCreate aliases? (default: y, options: y, n)').strip().lower()
    if not wrap:
        wrap = 'y'
    if wrap == 'y':
        ExecuteCommand([git, 'config', '--global', 'alias.st', 'status -s'],
                       '.')
        ExecuteCommand([
            git, 'config', '--global', 'alias.create-branch', 'checkout -b    '
        ], '.')
Exemple #7
0
def Run(params):
    '''
    Submit to reviewboard
    Note: must have already committed the work. 
    
    By default will do a diff from the current_branch to origin/current_branch.
    
    Note: reviewboard must be already configured:
        mu config reviewboard.url http://reviewboard.hdqt.appcelerator.com/
        
    Options:
        #-o: open browser
        #-g: guess description and title
        
    Maybe in the future we could support:
        #--server=http://reviewboard.hdqt.appcelerator.com/
        #--diff-filename=
        
    Should do:
    d:\bin\Python265\Scripts\post-review.exe -g -o --branch=development --tracking-branch=origin/development --bugs-closed=4654 --target-groups=Studio
    
    d:\bin\Python265\Scripts\post-review -g -o --diff-filename=mycode.diff --bugs-closed=4654 --target-groups=Studio
    '''

    args = params.args

    dirty_flag = False
    for arg in args:
        if arg == '--dirty':
            dirty_flag = True
            args.remove(arg)
            break

    if len(args) < 3:
        Print(
            '''Expecting 2 parameters: bugs_closed and target_groups (i.e.: mu post-review 4689 Studio)
Optional: --dirty: to post a review while there are changes in the working dir.'''
        )
        return
    bug_closed = args[1]
    target_group = args[2]

    repos_and_curr_branch = GetReposAndCurrBranch(params)
    repos_with_changes = ComputeReposWithChanges(repos_and_curr_branch, params)

    if not dirty_flag:
        changed = [
            repo for repo, has_change in repos_with_changes.items()
            if has_change
        ]
        if changed:
            Print(
                '''Unable to post review. All the contents must be committed before generating a review.
Note: pass '--dirty' flag to commit with changed resources (will still get changes from branch origin/branch).
Changed repos:
%s''' % (' '.join(changed), ))
            return

    repos_with_changes = ComputeReposWithChangesFromCurrentBranchToOrigin(
        repos_and_curr_branch, params)
    if not repos_with_changes:
        Print(
            'Unable to post review. Did not detect change in any repository.')
        return

    Print('Posting review for repos: %s ' % (' '.join(repos_with_changes), ))

    as_dict = dict(repos_and_curr_branch)
    for repo in repos_with_changes:
        branch = as_dict[repo]
        try:
            ExecuteCommand(
                [
                    'post-review',
                    '-g',
                    '-o',
                    '--branch=' + branch,
                    '--tracking-branch=origin/' + branch,
                    '--bugs-closed=' + bug_closed,
                    '--target-groups=' + target_group,
                ],
                repo,
                return_stdout=False,
                verbose=True,
            )
        except:
            Print(
                'Some error happened executing the post-review command. Please check if it is in your PATH.'
            )
            return
def Run(params, add, commit, push):
    from .print_ import Print, CreateJoinedReposMsg

    args = params.args[1:]
    if push:
        force_push=False
        for force_flag in ('--force', '-f'):
            if force_flag in args:
                args.remove(force_flag)
                force_push = True
                
    if commit and not args:
        git = params.config.git
        from mu_repo.execute_command import ExecuteCommand
        output = ExecuteCommand(
            [git] + 'config --get-regexp editor'.split(), '.', return_stdout=True)

        editors = []
        for line in output.splitlines():
            if line.startswith(b'core.editor '):
                line = line[len(b'core.editor '):]
                editors.append(line)

        if not editors:
            Print('Message for commit is required for git add -A & git commit -m command (or git core.editor must be configured).')
            return
        else:
            import tempfile
            import subprocess
            with tempfile.NamedTemporaryFile(delete=False, suffix='.txt') as f:
                f.write(b'\n\n')
                f.write(b'# Please enter the commit message for your changes. Lines starting\n')
                f.write(b'# with "#" will be ignored, and an empty message aborts the commit.\n')
            import sys
            args = editors[0].decode(sys.getfilesystemencoding())
            
            # Handle having something as: git config core.editor "'C:\Program File\Notepad++\notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
            # where we have to replace ' for " so that the command can be properly recognized by the shell.
            if sys.platform == 'win32':
                args = args.replace(u'\'', u'"')
            args += u' '
            filename = f.name
            if isinstance(filename, bytes):
                filename = filename.decode(sys.getfilesystemencoding())
            args += filename
            if hasattr(subprocess, 'run'):
                subprocess.run(args)
            else:
                subprocess.call(args)
            with open(f.name, 'r') as stream:
                lines = [x for x in stream.read().strip().splitlines() if not x.startswith('#')]

            contents = '\n'.join(lines)
            import os
            os.remove(f.name)
            if not contents:
                Print('Commit message not provided. Commit aborted.')
                return
            else:
                args = [contents]

    from .execute_parallel_command import ParallelCmd, ExecuteInParallelStackingMessages

    serial = params.config.serial
    if add:
        commands = [ParallelCmd(repo, [params.config.git, 'add', '-A']) for repo in params.config.repos]
        ExecuteInParallelStackingMessages(
            commands,
            lambda output: not output.stdout.strip(),
            lambda repos: Print(CreateJoinedReposMsg('Executed "git add -A" in:', repos)),
            serial=serial,
        )


    if commit:
        commit_msg = ' '.join(args)
        commands = [ParallelCmd(repo, [params.config.git, 'commit', '-m', commit_msg])
            for repo in params.config.repos]

        ExecuteInParallelStackingMessages(
            commands,
            lambda output: 'nothing to commit (working directory clean)' in output.stdout,
            lambda repos: Print(CreateJoinedReposMsg('Nothing to commit at:', repos)),
            serial=serial,
        )


    if push:
        from .get_repos_and_curr_branch import GetReposAndCurrBranch
        repos_and_curr_branch = GetReposAndCurrBranch(params)
        
        if force_push:
            force_args = ['--force']
        else:
            force_args = []

        commands = [ParallelCmd(repo, [params.config.git, 'push', 'origin', branch] + force_args)
            for (repo, branch) in repos_and_curr_branch]

        ExecuteInParallelStackingMessages(
            commands,
            lambda output: not output.stdout.strip() and output.stderr.strip() == 'Everything up-to-date',
            lambda repos: Print(CreateJoinedReposMsg('Up-to-date:', repos)),
            serial=serial,
        )
Exemple #9
0
def Run(params, add, commit, push):
    from .print_ import Print, CreateJoinedReposMsg

    args = params.args[1:]
    if commit and not args:
        git = params.config.git
        from mu_repo.execute_command import ExecuteCommand
        output = ExecuteCommand([git] + 'config --get-regexp editor'.split(),
                                '.',
                                return_stdout=True)

        editors = []
        for line in output.splitlines():
            if line.startswith(b'core.editor '):
                line = line[len(b'core.editor '):]
                editors.append(line)

        if not editors:
            Print(
                'Message for commit is required for git add -A & git commit -m command (or git core.editor must be configured).'
            )
            return
        else:
            import tempfile
            import subprocess
            with tempfile.NamedTemporaryFile(delete=False, suffix='.txt') as f:
                f.write(b'\n\n')
                f.write(
                    b'# Please enter the commit message for your changes. Lines starting\n'
                )
                f.write(
                    b'# with "#" will be ignored, and an empty message aborts the commit.\n'
                )
            import sys
            args = editors[0].decode(
                sys.getfilesystemencoding()) + ' ' + f.name
            if hasattr(subprocess, 'run'):
                subprocess.run(args)
            else:
                subprocess.call(args)
            with open(f.name, 'r') as stream:
                lines = [
                    x for x in stream.read().strip().splitlines()
                    if not x.startswith('#')
                ]

            contents = '\n'.join(lines)
            import os
            os.remove(f.name)
            if not contents:
                Print('Commit message not provided. Commit aborted.')
                return
            else:
                args = [contents]

    from .execute_parallel_command import ParallelCmd, ExecuteInParallelStackingMessages

    serial = params.config.serial
    if add:
        commands = [
            ParallelCmd(repo, [params.config.git, 'add', '-A'])
            for repo in params.config.repos
        ]
        ExecuteInParallelStackingMessages(
            commands,
            lambda output: not output.stdout.strip(),
            lambda repos: Print(
                CreateJoinedReposMsg('Executed "git add -A" in:', repos)),
            serial=serial,
        )

    if commit:
        commit_msg = ' '.join(args)
        commands = [
            ParallelCmd(repo, [params.config.git, 'commit', '-m', commit_msg])
            for repo in params.config.repos
        ]

        ExecuteInParallelStackingMessages(
            commands,
            lambda output: 'nothing to commit (working directory clean)' in
            output.stdout,
            lambda repos: Print(
                CreateJoinedReposMsg('Nothing to commit at:', repos)),
            serial=serial,
        )

    if push:
        from .get_repos_and_curr_branch import GetReposAndCurrBranch
        repos_and_curr_branch = GetReposAndCurrBranch(params)

        commands = [
            ParallelCmd(repo, [params.config.git, 'push', 'origin', branch])
            for (repo, branch) in repos_and_curr_branch
        ]

        ExecuteInParallelStackingMessages(
            commands,
            lambda output: not output.stdout.strip() and output.stderr.strip()
            == 'Everything up-to-date',
            lambda repos: Print(CreateJoinedReposMsg('Up-to-date:', repos)),
            serial=serial,
        )
def Run(params, add, commit, push):
    from .print_ import Print, CreateJoinedReposMsg

    args = params.args[1:]
    if push:
        force_push = False
        for force_flag in ('--force', '-f'):
            if force_flag in args:
                args.remove(force_flag)
                force_push = True

    if commit and not args:
        git = params.config.git
        from mu_repo.execute_command import ExecuteCommand
        output = ExecuteCommand([git] + 'config --get-regexp editor'.split(),
                                '.',
                                return_stdout=True)

        editors = []
        for line in output.splitlines():
            if line.startswith(b'core.editor '):
                line = line[len(b'core.editor '):]
                editors.append(line)

        if not editors:
            Print(
                'Message for commit is required for git add -A & git commit -m command (or git core.editor must be configured).'
            )
            return
        else:
            import tempfile
            import subprocess
            with tempfile.NamedTemporaryFile(delete=False, suffix='.txt') as f:
                f.write(b'\n\n')
                f.write(
                    b'# Please enter the commit message for your changes. Lines starting\n'
                )
                f.write(
                    b'# with "#" will be ignored, and an empty message aborts the commit.\n'
                )
            import sys
            args = editors[0].decode(sys.getfilesystemencoding())

            # Handle having something as: git config core.editor "'C:\Program File\Notepad++\notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
            # where we have to replace ' for " so that the command can be properly recognized by the shell.
            if sys.platform == 'win32':
                args = args.replace(u'\'', u'"')
            args += u' '
            filename = f.name
            if isinstance(filename, bytes):
                filename = filename.decode(sys.getfilesystemencoding())
            args += filename
            if hasattr(subprocess, 'run'):
                subprocess.run(args)
            else:
                subprocess.call(args)
            with open(f.name, 'r') as stream:
                lines = [
                    x for x in stream.read().strip().splitlines()
                    if not x.startswith('#')
                ]

            contents = '\n'.join(lines)
            import os
            os.remove(f.name)
            if not contents:
                Print('Commit message not provided. Commit aborted.')
                return
            else:
                args = [contents]

    from .execute_parallel_command import ParallelCmd, ExecuteInParallelStackingMessages

    serial = params.config.serial
    if add:
        commands = [
            ParallelCmd(repo, [params.config.git, 'add', '-A'])
            for repo in params.config.repos
        ]
        ExecuteInParallelStackingMessages(
            commands,
            lambda output: not output.stdout.strip(),
            lambda repos: Print(
                CreateJoinedReposMsg('Executed "git add -A" in:', repos)),
            serial=serial,
        )

    if commit:
        commit_msg = ' '.join(args)
        commands = [
            ParallelCmd(repo, [params.config.git, 'commit', '-m', commit_msg])
            for repo in params.config.repos
        ]

        ExecuteInParallelStackingMessages(
            commands,
            lambda output: 'nothing to commit (working directory clean)' in
            output.stdout,
            lambda repos: Print(
                CreateJoinedReposMsg('Nothing to commit at:', repos)),
            serial=serial,
        )

    if push:
        from .get_repos_and_curr_branch import GetReposAndCurrBranch
        repos_and_curr_branch = GetReposAndCurrBranch(params)

        if force_push:
            force_args = ['--force']
        else:
            force_args = []

        commands = [
            ParallelCmd(repo, [params.config.git, 'push', 'origin', branch] +
                        force_args) for (repo, branch) in repos_and_curr_branch
        ]

        ExecuteInParallelStackingMessages(
            commands,
            lambda output: not output.stdout.strip() and output.stderr.strip()
            == 'Everything up-to-date',
            lambda repos: Print(CreateJoinedReposMsg('Up-to-date:', repos)),
            serial=serial,
        )
Exemple #11
0
def Run(params, add, commit, push):
    from .print_ import Print, CreateJoinedReposMsg

    args = params.args[1:]
    if commit and not args:
        git = params.config.git
        from mu_repo.execute_command import ExecuteCommand
        output = ExecuteCommand(
            [git] + 'config --get-regexp editor'.split(), '.', return_stdout=True)

        editors = []
        for line in output.splitlines():
            if line.startswith(b'core.editor '):
                line = line[len(b'core.editor '):]
                editors.append(line)

        if not editors:
            Print('Message for commit is required for git add -A & git commit -m command (or git core.editor must be configured).')
            return
        else:
            import tempfile
            import subprocess
            with tempfile.NamedTemporaryFile(delete=False, suffix='.txt') as f:
                f.write(b'\n\n')
                f.write(b'# Please enter the commit message for your changes. Lines starting\n')
                f.write(b'# with "#" will be ignored, and an empty message aborts the commit.\n')
            import sys
            args = editors[0].decode(sys.getfilesystemencoding()) + ' ' + f.name
            if hasattr(subprocess, 'run'):
                subprocess.run(args)
            else:
                subprocess.call(args)
            with open(f.name, 'r') as stream:
                lines = [x for x in stream.read().strip().splitlines() if not x.startswith('#')]

            contents = '\n'.join(lines)
            import os
            os.remove(f.name)
            if not contents:
                Print('Commit message not provided. Commit aborted.')
                return
            else:
                args = [contents]

    from .execute_parallel_command import ParallelCmd, ExecuteInParallelStackingMessages

    serial = params.config.serial
    if add:
        commands = [ParallelCmd(repo, [params.config.git, 'add', '-A']) for repo in params.config.repos]
        ExecuteInParallelStackingMessages(
            commands,
            lambda output: not output.stdout.strip(),
            lambda repos: Print(CreateJoinedReposMsg('Executed "git add -A" in:', repos)),
            serial=serial,
        )


    if commit:
        commit_msg = ' '.join(args)
        commands = [ParallelCmd(repo, [params.config.git, 'commit', '-m', commit_msg])
            for repo in params.config.repos]

        ExecuteInParallelStackingMessages(
            commands,
            lambda output: 'nothing to commit (working directory clean)' in output.stdout,
            lambda repos: Print(CreateJoinedReposMsg('Nothing to commit at:', repos)),
            serial=serial,
        )


    if push:
        from .get_repos_and_curr_branch import GetReposAndCurrBranch
        repos_and_curr_branch = GetReposAndCurrBranch(params)

        commands = [ParallelCmd(repo, [params.config.git, 'push', 'origin', branch])
            for (repo, branch) in repos_and_curr_branch]

        ExecuteInParallelStackingMessages(
            commands,
            lambda output: not output.stdout.strip() and output.stderr.strip() == 'Everything up-to-date',
            lambda repos: Print(CreateJoinedReposMsg('Up-to-date:', repos)),
            serial=serial,
        )