def run(self, argv):
     
     _root = get_playbook_root(os.getcwd())
     _roles_directory = os.path.join(_root, 'roles')
     for _item in os.listdir(_roles_directory):
         _item = os.path.join(_roles_directory, _item)
         if not os.path.islink(_item):
             continue
                           
         # _item vs realpath(_item)
         alias = None
         if os.path.basename(_item) != os.path.basename(os.path.realpath(_item)):
             alias = os.path.basename(_item)
             
         
         # if git
         if os.path.exists(os.path.join(os.path.realpath(_item),'.git')):
             repo = git_repo(os.path.realpath(_item))
             origin = repo.remotes[0].config_reader.config.get('remote "origin"','url')
             commit = repo.head.commit.hexsha
             if not alias:
                 print "git+%s@%s" % (origin,commit)
                 continue
             print "git+%s@%s#alias=%s" % (origin,commit,alias)
         
         # if mercurial
         if os.path.exists(os.path.join(os.path.realpath(_item),'.hg')):
             repo = hg_repo(os.path.realpath(_item))
             
             print repo
             
             if not alias:
                 print "hg+%s@%s" % (origin,commit)
                 continue
             print "hg+%s@%s#alias=%s" % (origin,commit,alias)
    def _delete_testing_branch(self, repo_dir, branch_name):
        clean_branch_list = self._get_branches_list(repo_dir)

        repo = git_repo(repo_dir)
        gitobj = repo.git

        just_deleted = False
        if branch_name in clean_branch_list:
            gitobj.branch('-d', branch_name)
            just_deleted = True
        return just_deleted
 def revert_src_list_files(self):
     self.lock.acquire()
     try:
         repo = git_repo(self.repository_rootdir)
         gitobj = repo.git
         #for src in self.source_files_list:
         #    self._unlocked_revert_repository_file(src, gitobj=gitobj)
         self._unlocked_revert_repository_file(self.source_files_list, \
                                                             gitobj=gitobj)
     finally:
         self.lock.release()
 def _unlocked_revert_repository_file(self, file_rel_path, gitobj=None):
     if gitobj is None:
         repo = git_repo(self.repository_rootdir)
         gitobj = repo.git
     try:
         gitobj.checkout('--', file_rel_path)
     except OSError as e:
         logging.error("ENV is: \n {} \n".format(os.environ))
         ERROR_HANDLER.error_exit("git checkout command " + \
                                 "(-- {}) failed ".format(file_rel_path) + \
                                 "with error: {}".format(str(e)), __file__)
    def _get_branches_list(self, repo_dir):
        repo = git_repo(repo_dir)
        gitobj = repo.git

        git_branch_string = gitobj.branch()
        git_branch_list = git_branch_string.split("\n")
        clean_branch_list = []
        for branch in git_branch_list:
            branch = branch.replace('*', '')
            branch = branch.replace(' ', '')
            clean_branch_list.append(branch)
        return clean_branch_list
    def _make_testing_branch(self, repo_dir, branch_name):
        # create 'test' branch if it doesn't exist
        # so that it can be used for tests in this module
        clean_branch_list = self._get_branches_list(repo_dir)

        repo = git_repo(repo_dir)
        gitobj = repo.git

        if branch_name in clean_branch_list:
            newly_made = False
        else:
            gitobj.branch(branch_name)
            newly_made = True
        return newly_made
    def run(self, argv):

        _root = get_playbook_root(os.getcwd())
        if not _root:
            print(
                textwrap.dedent('''\
            can't find playbook. 
            use `arm init` to create recommended structure.'''))
            return 1
        _roles_directory = os.path.join(_root, 'roles')
        for _item in os.listdir(_roles_directory):
            _item = os.path.join(_roles_directory, _item)
            if not os.path.islink(_item):
                continue

            # _item vs realpath(_item)
            alias = None
            if os.path.basename(_item) != os.path.basename(
                    os.path.realpath(_item)):
                alias = os.path.basename(_item)

            # if git
            if os.path.exists(os.path.join(os.path.realpath(_item), '.git')):
                repo = git_repo(os.path.realpath(_item))
                origin = repo.remotes[0].config_reader.config.get(
                    'remote "origin"', 'url')
                commit = repo.head.commit.hexsha
                if not alias:
                    print "git+%s@%s" % (origin, commit)
                    continue
                print "git+%s@%s#alias=%s" % (origin, commit, alias)

            # if mercurial
            if os.path.exists(os.path.join(os.path.realpath(_item), '.hg')):
                repo = hg_repo(os.path.realpath(_item))

                print repo

                if not alias:
                    print "hg+%s@%s" % (origin, commit)
                    continue
                print "hg+%s@%s#alias=%s" % (origin, commit, alias)
    def _setup_repository(self):
        # Make sure the repo dir exists
        ERROR_HANDLER.assert_true(os.path.isdir(self.repository_rootdir), \
                        "given repository dir is not existing: {}". format( \
                            self.repository_rootdir), __file__)

        # make sure the repo dir is a git repo
        # if no, ask the user whether to initialize and initialize or abort
        # if yes or user accepted initialize, get the git object for the repo
        try:
            repo = git_repo(self.repository_rootdir)
            gitobj = repo.git
        except git_exc.InvalidGitRepositoryError:
            make_it_git = common_mix.confirm_execution("{} {} {} {}".format(\
                                    "The given repository directory is not", \
                                    "a git repository, this must be a git", \
                                    "repository to proceed.\n Do you want to",\
                                    "set is as git repository?"))
            if make_it_git:
                repo = git_repo.init(self.repository_rootdir)
                gitobj = repo.git
            else:
                ERROR_HANDLER.error_exit("{} {}".format(\
                            "Must make the repository as git repository,", \
                            "then re-run"), __file__)

        # Check whether the repo is already managed by muteria
        ## if using branch
        if self.delete_created_on_revert_as_initial:
            if self.test_branch_name not in self._get_branches_list(\
                                                self.repository_rootdir):
                ## Not managed, create branch
                self._make_testing_branch(self.repository_rootdir, \
                                                        self.test_branch_name)

            # checkout
            gitobj.checkout(self.test_branch_name)

        # Actual Check whether the repo is already managed by muteria
        # There must be a directory DEFAULT_MUTERIA_REPO_META_FOLDER
        src_in_prev = set()
        if os.path.isdir(self.muteria_metadir):
            ## Managed
            prev_src_list, prev_use_branch = \
                            common_fs.loadJSON(self.muteria_metadir_info_file)
            ERROR_HANDLER.assert_true(prev_use_branch == \
                        self.delete_created_on_revert_as_initial, \
                        "{} {} {} {} {}".format(\
                            "unmatching repo backup type.", \
                            "previously, use branch was", \
                            prev_use_branch, ", now it is",\
                            self.delete_created_on_revert_as_initial), \
                                                                    __file__)
            src_in_prev = set(prev_src_list) & set(self.source_files_list)
            prev_src_list = set(prev_src_list) - set(self.source_files_list)
            remain_prev_src_set = {src for src in prev_src_list \
                                    if os.path.isfile(self.repo_abs_path(src))}
            # make sure that all prev_src are in initial state
            untracked_diff_files = self._get_untracked_and_diffed(repo)
            prev_untracked_diff = remain_prev_src_set & untracked_diff_files
            if len(prev_untracked_diff) > 0:
                bypass = common_mix.confirm_execution(\
                            "{} {} {} {} {}".format(
                                "the following files were previously used as",\
                                "src files by muteria and are now untracked:",\
                                prev_untracked_diff, \
                                "\nDo you want to handle it or bypass it?",\
                                "Choose yes to bypass: "******"{} {}".format(\
                                "Do you want to automatically restore the",\
                                "The untracked previous source and continue?"))
                    if revert_them:
                        for src in prev_untracked_diff:
                            self.revert_repository_file(src, gitobj=gitobj)
                    else:
                        ERROR_HANDLER.error_exit(\
                                "Handle it manually and restart the execution")

            # update the info_file
            if set(prev_src_list) != set(self.source_files_list):
                common_fs.dumpJSON([self.source_files_list, \
                                    self.delete_created_on_revert_as_initial],\
                                                self.muteria_metadir_info_file)
        else:
            ## Not managed
            os.mkdir(self.muteria_metadir)
            common_fs.dumpJSON([self.source_files_list, \
                                    self.delete_created_on_revert_as_initial],\
                                                self.muteria_metadir_info_file)

        # Make sure all source files of interest are tracked
        untracked_diff_files = self._get_untracked_and_diffed(repo)
        untracked_diff_src_in_prev = untracked_diff_files & src_in_prev
        if len(untracked_diff_src_in_prev) > 0:
            if common_mix.confirm_execution(\
                            "{} {} {} {} {}".format("The following source",\
                                        "files of interest are untracked", \
                    "and will be reverted (previous execution unfinished):", \
                                        src_in_prev, \
                                        "do you want to revert them?")):
                for src in src_in_prev:
                    self.revert_repository_file(src, gitobj=gitobj)
            else:
                ERROR_HANDLER.error_exit("{} {}".format(\
                                    "Handle untracked source files manually", \
                                                "then restart the execution"))

        untracked_diff_files = self._get_untracked_and_diffed(repo)
        untracked_diff_src_files = set(self.source_files_list) & \
                                                        untracked_diff_files
        if len(untracked_diff_src_files) > 0:
            if common_mix.confirm_execution(\
                                "{} {} {} {}".format("The following source",\
                                        "files of interest are untracked:", \
                                        untracked_diff_src_files, \
                                        "do you want to track them?")):
                repo.index.add(list(untracked_diff_src_files))
            else:
                ERROR_HANDLER.error_exit("{} {}".format(\
                                    "Handle untracked source files manually", \
                                                "then restart the execution"))
 def _unlocked_revert_repository_file (self, file_rel_path, gitobj=None):
     if gitobj is None:
         repo = git_repo(self.repository_rootdir)
         gitobj = repo.git
     gitobj.checkout('--', file_rel_path)