Пример #1
0
class BaseCommand(object):

    interface = simpcli.Interface()
    command = simpcli.Command(True)
    config = ManagerConfig()
    projects = Projects()
    runPerProject = True

    def __init__(self):
        self.config.load()
        className = self.__class__.__name__
        if self.projects.getAll(
        ) == {} and className != 'Init' and className != 'ExtraCommand':
            self.interface.error('No projects found in your config')
            self.interface.writeOut(
                'To add a project navigate into a directory with a docker-compose.yml and execute docker-manager init.'
            )
            self.exit()

    def getRunPerProject(self):
        return self.runPerProject

    def exit(self):
        sys.exit(1)

    def bold(self, string):
        self.interface.writeOut(
            '%s%s%s' % (self.interface.BOLD, string, self.interface.ENDC))
class Cli():

    interface = simpcli.Interface()
    command = simpcli.Command(True)
    projects = Projects()
    plugins = []
    commands = [
        "status", "start", "stop", "update", "restart", "destroy", "init",
        "deinit", "projects", "pull", "cd"
    ]

    commandsNotRunningByProjects = ['init', 'deinit', 'projects']

    def getAvailableCommands(self):
        return self.commands

    def instantiateCommand(self, command: str) -> BaseCommand:
        if command == 'status':
            return StatusCommand()
        if command == 'start':
            return StartCommand()
        if command == 'stop':
            return StopCommand()
        if command == 'update':
            return UpdateCommand()
        if command == 'restart':
            return RestartCommand()
        if command == 'destroy':
            return DestroyCommand()
        if command == 'init':
            return InitCommand()
        if command == 'deinit':
            return DeinitCommand()
        if command == 'projects':
            return ProjectsCommand()
        if command == 'pull':
            return PullCommand()
        if command == 'cd':
            return ChangeDirectoryCommand()

        raise CommandNotFoundException('Command "%s" not found!' % (command))

    def bold(self, string):
        self.interface.writeOut(
            '%s%s%s' % (self.interface.BOLD, string, self.interface.ENDC))

    def dispatch(self, command: str, project: str, service: str):
        projects = []

        if project == 'all-projects':
            for project in self.projects.getAll():
                projects.append(project)
        else:
            projects.append(project)

        self.interface.header('docker-manager %s' % (command))
        extraCommandObject = ExtraCommand(command)

        if command in self.commandsNotRunningByProjects:
            self.runCommand(command, project, service)
        else:
            for project in projects:
                self.interface.writeOut('')
                self.bold(project)
                self.runCommand(command, project, service)

    def runCommand(self, command: str, project: str, service: str):
        project = self.projects.getProject(project)
        extraCommandObject = ExtraCommand(command)
        try:
            commandObject = self.instantiateCommand(command)
        except CommandNotFoundException:
            # if default command fails, try to find some extra commands
            try:
                extraCommandObject.run(project, service)
            except NoExtraCommandFoundException:
                # if not even an extraCommand is found, output an error
                errorMessage = 'Neither a command nor an extraCommand with the name "%s" was found in project "%s".'

                self.interface.error(errorMessage % (command, project))
                pass

        try:
            commandObject.run(project, service)
            self.runPlugins(command, project)
            try:
                # try running additional commands stored in projects
                extraCommandObject.run(project, service)
            except NoExtraCommandFoundException:
                pass

        # catch cli execution errors here
        except UnboundLocalError:
            pass
        except Exception as e:
            errorMessage = 'An error occured\n' + \
                ' Exception was: %s'

            self.interface.error(errorMessage % (e))

            self.interface.error(format(e))

    def runPlugins(self, command, project):
        try:
            self.plugins = [
                # BasicAuth(),
                # Nginx(),
                Hosts()
            ]

            project.changeWorkingDirectory()
            compose = Compose()
            for plugin in self.plugins:
                if not hasattr(plugin, command):
                    continue

                self.interface.writeOut('')
                self.interface.info('Running %s' % (plugin.name))

                for container in compose.getContainers():
                    success, message = plugin.run(command, container)
                    if message:
                        self.interface.writeOut(message)
        except Exception as e:
            self.interface.error('Plugin Exception')
            self.interface.writeOut(e)
            self.interface.writeOut(traceback.format_exc())

    def close(self, msg: str):
        self.interface.ok(msg)
Пример #3
0
class BaseCommand(object):

    interface = simpcli.Interface()
    config = GitcdConfig()
    configPersonal = GitcdPersonalConfig()
    updateRemote = False

    def __init__(self):
        self.instantiateRepository()
        if self.updateRemote is True:
            self.repository.update()

    def instantiateRepository(self) -> bool:
        self.repository = Repository()
        return True

    def run(self, branch: Branch):
        pass

    def getDefaultBranch(self) -> Branch:
        return self.repository.getCurrentBranch()

    def getRequestedBranch(self, branch: str) -> Branch:
        featureAsString = self.config.getString(self.config.getFeature())
        if not branch.startswith(featureAsString):
            branch = '%s%s' % (featureAsString, branch)
        return Branch(branch)

    def hasMultipleRemotes(self) -> bool:
        return len(self.repository.getRemotes()) > 1

    def getRemote(self) -> str:
        remotes = self.repository.getRemotes()

        if len(remotes) == 1:
            remote = remotes[0]
        else:
            if len(remotes) == 0:
                default = False
                choice = False
            else:
                default = remotes[0].getName()
                choice = []
                for remoteObj in remotes:
                    choice.append(remoteObj.getName())

            remoteAnswer = self.interface.askFor(
                "Which remote you want to use?", choice, default)
            for remoteObj in remotes:
                if remoteAnswer == remoteObj.getName():
                    remote = remoteObj

        return remote

    def checkTag(self, remote: Remote, tag: Tag) -> bool:
        if self.repository.hasUncommitedChanges():
            abort = self.interface.askFor(
                "You currently have uncomitted changes." +
                " Do you want me to abort and let you commit first?",
                ["yes", "no"], "yes")

            if abort == "yes":
                sys.exit(1)

        return True

    def checkRepository(self) -> bool:
        # check if repo has uncommited changes
        if self.repository.hasUncommitedChanges():
            abort = self.interface.askFor(
                "You currently have uncomitted changes." +
                " Do you want me to abort and let you commit first?",
                ["yes", "no"], "yes")

            if abort == "yes":
                sys.exit(1)

        return True

    def checkBranch(self, remote: Remote, branch: Branch) -> bool:
        # check if its a feature branch
        if not branch.isFeature():
            raise GitcdNoFeatureBranchException(
                "Your current branch is not a valid feature branch." +
                " Checkout a feature branch or pass one as param.")

        # check remote existence
        if not remote.hasBranch(branch):
            pushFeatureBranch = self.interface.askFor(
                "Your feature branch does not exists on remote." +
                " Do you want me to push it remote?", ["yes", "no"], "yes")

            if pushFeatureBranch == "yes":
                remote.push(branch)

        # check behind origin
        if remote.isBehind(branch):

            pushFeatureBranch = self.interface.askFor(
                "Your feature branch is ahead the origin/branch." +
                " Do you want me to push the changes?", ["yes", "no"], "yes")

            if pushFeatureBranch == "yes":
                remote.push(branch)

        return True

    def getTokenOrAskFor(self, tokenSpace: str) -> str:
        token = self.configPersonal.getToken(tokenSpace)
        if token is None:
            token = self.interface.askFor(
                "Your personal %s token?" % (tokenSpace), False, token)

            if (tokenSpace == 'bitbucket' and ':' not in token):
                self.interface.warning(
                    'For bitbucket you need to pass a username' +
                    ' as well like <username:app_password>')
                return self.getTokenOrAskFor(tokenSpace)

            self.configPersonal.setToken(tokenSpace, token)
            self.configPersonal.write()
        return token
Пример #4
0
class Cli():

    interface = simpcli.Interface()

    commands = [
        'init', 'clean', 'start', 'test', 'review', 'finish', 'release',
        'status', 'compare', 'upgrade', 'refresh'
    ]

    def getAvailableCommands(self):
        return self.commands

    def instantiateCommand(self, command: str) -> BaseCommand:
        if command == 'init':
            return Init()
        if command == 'clean':
            return Clean()
        if command == 'start':
            return Start()
        if command == 'test':
            return Test()
        if command == 'review':
            return Review()
        if command == 'finish':
            return Finish()
        if command == 'release':
            return Release()
        if command == 'status':
            return Status()
        if command == 'compare':
            return Compare()
        if command == 'upgrade':
            return Upgrade()
        if command == 'refresh':
            return Refresh()

    def dispatch(self, command: str, branch: str):
        # this is kind of temporary and will get removed in a few
        # releases. It ensures your access token, now stored in all repos
        # will be moved into a .gitcd directory in your home directory
        MoveGitcdPersonalPerRepo()

        try:
            commandObject = self.instantiateCommand(command)
        except Exception as e:
            errorMessage = 'Command %s does not exists,' + \
                ' see gitcd --help for more information.' + \
                ' Exception was: %s'

            self.interface.error(errorMessage % (command, e))
            sys.exit(1)

        self.interface.header('git-cd %s' % (command))

        try:
            if branch == '*':
                branch = commandObject.getDefaultBranch()
            else:
                branch = commandObject.getRequestedBranch(branch)

            commandObject.run(branch)
        # catch cli execution errors here
        except (GitcdException, CliException) as e:
            self.interface.error(format(e))

    def close(self, msg: str):
        self.interface.ok(msg)