Exemple #1
0
    def main():
        """
        Main method
        """
        sys.argv[0] = "c3pm"

        if len(sys.argv) < 2:
            CLIMessage.error_message(
                "At least one CLI argument expected")  # TODO show usage
            sys.exit()
        if sys.argv[1] == "init" and len(sys.argv) == 2:
            CLIMain.__init_project()
            return
        if sys.argv[1] == "add":
            if sys.argv[2] == "git-c3pm":
                if sys.argv[5] == "master" and len(sys.argv) == 6:
                    CLIMain.__add_git_c3pm_dependency(sys.argv[3], sys.argv[4])
                    return
        if sys.argv[1] == "remove" and len(sys.argv) == 4:
            CLIMain.__remove_dependency(sys.argv[2], sys.argv[3])
            return
        if sys.argv[1] == "update" and len(sys.argv) == 2:
            CLIMain.__update_dependencies()
            return
        if sys.argv[1] == "list" and len(sys.argv) == 2:
            CLIMain.__list_dependencies()
            return
        CLIMessage.error_message("bad CLI usage")
Exemple #2
0
 def __list_dependencies():
     """
     Lists all dependencies to CLI
     """
     try:
         c3pm_project = C3PMProject(is_object=True)
         project_dependencies_dict = c3pm_project.list_all_dependencies()
         if project_dependencies_dict:
             ColorP.print("Dependencies for " + c3pm_project.name + ":",
                          ColorP.BOLD_CYAN)
             for dependency_name in project_dependencies_dict:
                 if project_dependencies_dict[dependency_name][
                         "type"] == "git-c3pm":
                     ColorP.print("├─── ", ColorP.BOLD_CYAN, line_end="")
                     print(
                         C3PMProject.dependency_str_representation(
                             dependency_name,
                             project_dependencies_dict[dependency_name],
                             colored=True))
         else:
             ColorP.print(
                 "Project " + c3pm_project.name +
                 " doesn't have any dependencies", ColorP.BOLD_CYAN)
     except C3PMProject.BadC3PMProject as err:
         CLIMessage.error_message("bad project: " + err.problem)
         sys.exit()
     except Exception:
         CLIMessage.error_message(
             "unknown error happen, please, report the following on " +
             CLIMain.ISSUES_LINK)
         raise
Exemple #3
0
 def __add_git_c3pm_dependency(name: str,
                               git_url: str,
                               version: str = "master"):
     """
     Add dependency of type c3pm_dependency
     :param name: name for new dependency
     :param git_url: url of .git repository
     :param version: have to "master" at this moment
     """
     try:
         c3pm_project = C3PMProject(is_object=True)
         c3pm_project.add_c3pm_dependency(name, git_url, version)
         c3pm_project.write()
     except C3PMProject.BadC3PMProject as err:
         CLIMessage.error_message("bad project: " + err.problem)
         sys.exit()
     except C3PMProject.BadValue as err:
         CLIMessage.error_message("bad argument: " + str(err))
         sys.exit()
     except Exception:
         CLIMessage.error_message(
             "unknown error happen, please, report the following on " +
             CLIMain.ISSUES_LINK)
         raise
     else:
         CLIMessage.success_message(
             "dependency " + C3PMProject.dependency_str_representation(
                 name, c3pm_project.dependency_data(name)) +
             " successfully added to project")
Exemple #4
0
    def clone_git_repository(name: str, url: str, target_directory_name: str):
        """
        Clones git repository by url and checks is it cloned correct
        :param name: name of project which will be cloned
        :param url: url of .git repository
        :param target_directory_name: a directory name for cloning
        :raises C3PMProject.BadValue: if cloning failed
        """

        CLIMessage.info_message("cloning " + name + " (" + url + ") to " +
                                target_directory_name)
        os.system("git clone " + url + " " + target_directory_name)
        clone_dir_ls = subprocess.check_output(["ls"]).split()
        if len(clone_dir_ls) == 0:
            raise C3PMProject.BadValue(
                "url", "cloning " + name + " (" + url + ") to " +
                target_directory_name + " failed: nothing cloned.")
        if len(clone_dir_ls) != 1:
            raise C3PMProject.BadValue(
                "url", "cloning " + name + " (" + url + ") to " +
                target_directory_name + " failed: to many directories in "
                "clone directory.")
        CLIMessage.success_message(name + " cloned")
Exemple #5
0
    def __init_project():
        """
        Initialize a new c3pm project by creating c3pm.json by users data via CLI,
        (if not exist) "src" and "src/exports". Adds IMPORT_DIR and CLONE_DIR to .gitignore
        """

        try:
            c3pm_project = C3PMProject(is_object=True, init_new_project=True)
            c3pm_project.write()
        except C3PMProject.BadC3PMProject as err:
            CLIMessage.error_message("bad project directory: " + err.problem)
            sys.exit()
        except Exception:
            CLIMessage.error_message(
                "unknown error happen, please, report the following on " +
                CLIMain.ISSUES_LINK)
            raise
        else:
            CLIMessage.success_message(C3PMProject.C3PM_JSON_FILENAME +
                                       " successfully written")
            CLIMessage.success_message("project " + c3pm_project.name +
                                       " successfully initialized")
Exemple #6
0
 def __update_dependencies():
     """
     Updates all dependencies in project
     """
     try:
         c3pm_project = C3PMProject(is_object=True)
         c3pm_project.update_dependencies()
     except C3PMProject.BadC3PMProject as err:
         CLIMessage.error_message("bad project: " + err.problem)
         sys.exit()
     except Exception:
         CLIMessage.error_message(
             "unknown error happen, please, report the following on " +
             CLIMain.ISSUES_LINK)
         raise
     else:
         CLIMessage.success_message("project successfully updated")
Exemple #7
0
 def __remove_dependency(name: str, version: str = "master"):
     """
     Removes dependencies from project
     :param name: name of dependency to be removed
     :param version: version of dependency to be removed, have to be "master" at this moment
     """
     try:
         c3pm_project = C3PMProject(is_object=True)
         c3pm_project.remove_dependency(name, version)
         c3pm_project.write()
     except C3PMProject.BadC3PMProject as err:
         CLIMessage.error_message("bad project: " + err.problem)
         sys.exit()
     except C3PMProject.BadValue as err:
         CLIMessage.error_message("bad argument: " + str(err))
         sys.exit()
     except Exception:
         CLIMessage.error_message(
             "unknown error happen, please, report the following on " +
             CLIMain.ISSUES_LINK)
         raise
     else:
         CLIMessage.success_message("dependency " + name + "(version " +
                                    version + " successfully removed")
Exemple #8
0
    def __init__(self,
                 is_object: bool = False,
                 init_new_project: bool = False):
        """
        If init_new_project is True, directory is checked and if all ok, new c3pm project is
        being initiated by creating new c3pm.json, creating directories "src" and "src/exports" (
        if they do not exist, with file "readme.txt" inside of "src/exports") and making changed
        to ".gitignore" if this file exist.
        If init_new_project is False, project is checked and c3pm.json is being read.
        :param is_object: False by default. If True, checks can c3pm commands be applied
        to this project, otherwise - is project a valid c3pm project to be cloned.
        :param init_new_project: if True, new project is being initialized, otherwise project is
        being loaded

        :raises C3PMProject.BadC3PMProject if project directory check failed
        :raises json.decoder.JSONDecodeError: if json_str is not a valid json
        :raises FileNotFoundError: if self.C3PM_JSON_FILENAME cannot be opened
        :raises AssertionError: if call parameters are forbidden
        TODO rewrite constructor removing exceptions except BadC3PMProject and AssetionError
        """

        assert type(is_object) == bool, "argument is_object have to bool"
        assert type(init_new_project
                    ) == bool, "argument init_new_project have to be bool"

        if init_new_project:

            # Checking project directory before starting dialog with user
            if os.path.isdir(self.C3PM_JSON_FILENAME):
                raise self.BadC3PMProject(self.C3PM_JSON_FILENAME +
                                          " is a directory")
            if os.path.isfile(self.C3PM_JSON_FILENAME):
                raise self.BadC3PMProject(self.C3PM_JSON_FILENAME +
                                          " already exist")
            if os.path.isfile(self.SRC_DIR):
                raise self.BadC3PMProject(self.SRC_DIR + " is a file")
            if os.path.isfile(self.SRC_DIR + "/" + self.EXPORT_DIR):
                raise self.BadC3PMProject(self.SRC_DIR + "/" +
                                          self.EXPORT_DIR + " is a file")

            self.__c3pm_dict = OrderedDict()
            self.init_new_json()

            try:
                if not os.path.isdir(self.SRC_DIR):
                    os.mkdir(self.SRC_DIR)
                    CLIMessage.success_message(self.SRC_DIR +
                                               " directory created")
            except:
                raise self.BadC3PMProject("unable to create directory " +
                                          self.SRC_DIR)
            try:
                if not os.path.isdir(self.SRC_DIR + "/" + self.EXPORT_DIR):
                    os.mkdir(self.SRC_DIR + "/" + self.EXPORT_DIR)
                    CLIMessage.success_message(self.SRC_DIR + "/" +
                                               self.EXPORT_DIR +
                                               " directory created")
                    with open(self.SRC_DIR + "/" + self.EXPORT_DIR + "/readme.txt", "w+") as \
                            readme_file:
                        readme_file.write(
                            "place your files which have to be taken by a dependent "
                            "project")
                        CLIMessage.success_message(self.SRC_DIR + "/" +
                                                   self.EXPORT_DIR +
                                                   "/readme.txt written")
            except:
                raise self.BadC3PMProject("unable to create directory " +
                                          self.SRC_DIR + "/" + self.EXPORT_DIR)

            if os.path.isdir(".git"):
                if os.path.isdir(".gitignore"):
                    CLIMessage.error_message(".gitignore is directory!!!")
                else:
                    gitignore_content = ""
                    if os.path.isfile(".gitignore"):
                        with open(".gitignore", "r") as gitignore_file:
                            gitignore_content = gitignore_file.read()
                    if gitignore_content and gitignore_content[
                            len(gitignore_content) - 1] != '\n':
                        gitignore_content += "\n"
                    if self.IMPORT_DIR + "/**" not in gitignore_content.split(
                    ):
                        gitignore_content += self.IMPORT_DIR + "/**" + "\n"
                    if self.CLONE_DIR + "/**" not in gitignore_content.split():
                        gitignore_content += self.CLONE_DIR + "/**" + "\n"
                    with open(".gitignore", "w+") as gitignore_file:
                        gitignore_file.write(gitignore_content)
                    CLIMessage.success_message(".gitinore written")

        else:
            problem_with_project = C3PMProject.ProjectChecker.problem_with_project(
            )
            if problem_with_project:
                raise self.BadC3PMProject(problem_with_project)
            with open(self.C3PM_JSON_FILENAME, "r") as c3pm_json_file:
                self.__c3pm_dict = json.loads(c3pm_json_file.read(),
                                              object_pairs_hook=OrderedDict)
                problem_with_c3pm_json = \
                    C3PMProject.C3PMJSONChecker.problem_with_c3pm_json(self.__c3pm_dict)
                if problem_with_c3pm_json:
                    raise self.BadC3PMProject("bad " +
                                              self.C3PM_JSON_FILENAME + ": " +
                                              problem_with_c3pm_json)
Exemple #9
0
    def list_all_dependencies(self) -> OrderedDict:
        """
        Loads all project's dependencies recursively to list all their own dependencies. In the
        result, a list of all projects which have to be loaded is listed.
        :raises C3PMProject.BadC3PMProject:
        :return: list of all dependencies
        """

        # TODO clean clone dir

        def full_dependency_branch(dependency_name: str) -> str:
            """
            Returns one of branches to dependency
            :param dependency_name:
            :return: full branch-path to dependency
            """
            result = dependency_name
            next_dependency_name = dependency_name
            while next_dependency_name != C3PMProject.ROOT_NAME_FOR_DEPENDENCIES_LIST:
                next_dependency_name = dependency_parent_list[
                    next_dependency_name]
                result = next_dependency_name + "->" + result
            return result

        CLIMessage.info_message("Listing all dependencies for project " +
                                self.name)
        # OrderedDict of all dependencies, will be returned
        all_dependencies = OrderedDict(self.__c3pm_dict["dependencies"])
        # OrderedDict of dependencies, which are not yet checked
        unchecked_dependencies = OrderedDict(self.__c3pm_dict["dependencies"])
        # dict of dependencies parent name (dependency_name: str -> parent_dependency_name: str)
        dependency_parent_list = dict()

        os.mkdir(C3PMProject.CLONE_DIR)
        os.chdir(C3PMProject.CLONE_DIR)

        for cloned_project_dependency_name in all_dependencies:
            dependency_parent_list[cloned_project_dependency_name] = \
                C3PMProject.ROOT_NAME_FOR_DEPENDENCIES_LIST
        while len(unchecked_dependencies):
            unchecked_dependency = unchecked_dependencies.popitem(last=False)
            unchecked_dependency_name = unchecked_dependency[0]

            try:
                C3PMProject.clone_git_repository(
                    full_dependency_branch(unchecked_dependency_name),
                    unchecked_dependency[1]["url"], unchecked_dependency_name)
            except C3PMProject.BadValue as err:
                raise C3PMProject.BadC3PMProject(str(err))
            else:
                os.chdir(unchecked_dependency_name)
                try:
                    c3pm_cloned_project = C3PMProject()
                    cloned_project_dependencies_dict = \
                        c3pm_cloned_project.__c3pm_dict["dependencies"]
                    for cloned_project_dependency_name in cloned_project_dependencies_dict:
                        if cloned_project_dependency_name in all_dependencies:
                            if cloned_project_dependencies_dict[cloned_project_dependency_name] != \
                                    all_dependencies[cloned_project_dependency_name]:
                                raise C3PMProject.BadC3PMProject(
                                    "duplicated dependencies names:\n"
                                    # dependency 1 name =
                                    + full_dependency_branch(
                                        cloned_project_dependency_name) + ":\n"
                                    # dependency 1 info =
                                    + json.dumps(all_dependencies[
                                        cloned_project_dependency_name],
                                                 indent=4) + "\n"
                                    # dependency 2 name =
                                    + full_dependency_branch(
                                        c3pm_cloned_project.name) + "->" +
                                    cloned_project_dependency_name
                                    # dependency 2 info =
                                    + cloned_project_dependencies_dict[
                                        cloned_project_dependency_name])
                        else:
                            all_dependencies[
                                cloned_project_dependency_name] = OrderedDict(
                                    cloned_project_dependencies_dict[
                                        cloned_project_dependency_name])
                            unchecked_dependencies[
                                cloned_project_dependency_name] = OrderedDict(
                                    cloned_project_dependencies_dict[
                                        cloned_project_dependency_name])
                            dependency_parent_list[cloned_project_dependency_name] = \
                                c3pm_cloned_project.name
                except C3PMProject.BadC3PMProject as err:
                    raise C3PMProject.BadC3PMProject(
                        "in cloned project " +
                        full_dependency_branch(unchecked_dependency_name) +
                        ":bad project directory: " + err.problem)
                except Exception:
                    raise C3PMProject.BadC3PMProject(
                        "in cloned project " +
                        full_dependency_branch(unchecked_dependency_name) +
                        ":unknown error happen, please report that")
                os.chdir("..")
                shutil.rmtree(unchecked_dependency_name)
        os.chdir("..")
        shutil.rmtree(C3PMProject.CLONE_DIR)
        return all_dependencies