Example #1
0
    def _update(self, git_settings: GitSettings) -> None:
        """Update with overrides from given GitSettings

        :return: Config processed to create strings
        :raise UnknownArgumentError:
        :raise UnknownTypeError:
        """

        if git_settings.submodules is not None:
            submodules = copy.deepcopy(git_settings.submodules)
            if isinstance(submodules, bool):
                self.submodules = submodules
                self.recursive = False
            elif isinstance(submodules, str):
                if submodules == "recursive":
                    self.submodules = True
                    self.recursive = True
                else:
                    raise UnknownArgumentError(
                        f"Unknown submodules argument: {submodules}")
            else:
                raise UnknownTypeError("Unknown submodules type")
        if git_settings.lfs is not None:
            self.lfs = copy.deepcopy(git_settings.lfs)
        if git_settings.depth is not None:
            self.depth = copy.deepcopy(git_settings.depth)
        if git_settings.config is not None:
            if self.config is None:
                self.config = copy.deepcopy(git_settings.config)
            else:
                for (k, v) in git_settings.config.items():
                    self.config[k] = v

        self._clean_config()
Example #2
0
    def __init__(self, name: str, yaml: Union[dict, List[Project]]):
        """Group __init__

        :param str name: Section name
        :param Union[dict, List[Project]] yaml: Parsed YAML python object for group
        :raise UnknownTypeError:
        """

        self.name: str = name

        if isinstance(yaml, dict):
            path = yaml.get('path', None)
            self.path: Optional[Path] = None if path is None else Path(path)
            self.groups: Optional[List[str]] = yaml.get('groups', None)
            defaults = yaml.get("defaults", None)
            self.defaults: Optional[
                Defaults] = None if defaults is None else Defaults(defaults)
            self.projects: List[Project] = [
                Project(p) for p in yaml["projects"]
            ]
            self._has_projects_key: bool = True
        elif isinstance(yaml, list):
            self.path: Optional[Path] = None
            self.groups: Optional[List[str]] = None
            self.defaults: Optional[Defaults] = None
            self.projects: List[Project] = [Project(p) for p in yaml]
            self._has_projects_key: bool = False
        else:
            raise UnknownTypeError("Unknown group type")
Example #3
0
    def __init__(self,
                 branch: Optional[str] = None,
                 tag: Optional[str] = None,
                 commit: Optional[str] = None):
        """GitRepo __init__

        :param Optional[str] branch: Branch
        :param Optional[str] tag: Tag
        :param Optional[str] commit: Commit
        :raise CommandArgumentError:
        :raise UnknownTypeError:
        """

        arguments_count = len(
            [ref for ref in [branch, tag, commit] if ref is not None])
        if arguments_count == 0:
            raise CommandArgumentError('GitRef init requires one argument')
        elif arguments_count > 1:
            raise CommandArgumentError('GitRef init only allows one argument')

        self.branch: Optional[str] = branch
        self.tag: Optional[str] = tag
        self.commit: Optional[str] = commit

        if self.branch is not None:
            self.ref_type: GitRefEnum = GitRefEnum.BRANCH
        elif self.tag is not None:
            self.ref_type: GitRefEnum = GitRefEnum.TAG
        elif self.commit is not None:
            self.ref_type: GitRefEnum = GitRefEnum.COMMIT
        else:
            raise UnknownTypeError('Invalid GitRef type')

        self.check_ref_format(self.formatted_ref)
Example #4
0
    def _herd(self, remote: str, ref: GitRef, depth: int = 0, fetch: bool = True, rebase: bool = False) -> None:
        """Herd ref

        :param str remote: Remote name
        :param GitRef ref: Git ref
        :param int depth: Git clone depth. 0 indicates full clone, otherwise must be a positive integer
        :param bool fetch: Whether to fetch
        :param bool rebase: Whether to use rebase instead of pulling latest changes
        :raise UnknownTypeError:
        """

        if ref.ref_type == GitRefEnum.TAG:
            self.fetch(remote, depth=depth, ref=ref)
            self._checkout_tag(ref.short_ref)
        elif ref.ref_type == GitRefEnum.COMMIT:
            self.fetch(remote, depth=depth, ref=ref)
            self._checkout_sha(ref.formatted_ref)
        elif ref.ref_type == GitRefEnum.BRANCH:
            branch = ref.short_ref
            if not self.has_local_branch(branch):
                self._create_branch_local_tracking(branch, remote, depth=depth, fetch=fetch)
                return
            self._herd_existing_local(remote, branch, depth=depth, rebase=rebase)
        else:
            raise UnknownTypeError('Unknown GitRefEnum type')
Example #5
0
    def reset(self, depth: int = 0) -> None:
        """Reset branch to upstream or checkout tag/sha as detached HEAD

        :param int depth: Git clone depth. 0 indicates full clone, otherwise must be a positive integer
        :raise ClowderGitError:
        :raise UnknownTypeError:
        """

        if self.default_ref.ref_type is GitRefEnum.TAG:
            self.fetch(self.remote, ref=self.default_ref, depth=depth)
            self._checkout_tag(self.default_ref.short_ref)
        elif self.default_ref.ref_type is GitRefEnum.COMMIT:
            self.fetch(self.remote, ref=self.default_ref, depth=depth)
            self._checkout_sha(self.default_ref.short_ref)
        elif self.default_ref.ref_type is GitRefEnum.BRANCH:
            branch = self.default_ref.short_ref
            if not self.has_local_branch(branch):
                self._create_branch_local_tracking(branch, self.remote, depth=depth, fetch=True)
                return
            self._checkout_branch(branch)
            if not self.has_remote_branch(branch, self.remote):
                raise ClowderGitError(f'No existing remote branch {fmt.remote(self.remote)} {fmt.ref(branch)}')
            self.fetch(self.remote, ref=self.default_ref, depth=depth)
            CONSOLE.stdout(f' - Reset branch {fmt.ref(branch)} to {fmt.remote(self.remote)} {fmt.ref(branch)}')
            self._reset_head(branch=f'{self.remote}/{branch}')
        else:
            raise UnknownTypeError('Unknown GitRefEnum type')
Example #6
0
    def get_source(self, source: Union[SourceName, Source]) -> Source:
        """Returns Source by name

        :param Union[SourceName, Source] source: Source to return
        :return: Source with supplied name
        :raise SourcesValidatedError:
        :raise UnknownTypeError:
        :raise UnknownSourceError:
        """

        if not self._has_been_validated:
            raise SourcesValidatedError(
                "Called get_source() but SOURCE_CONTROLLER has not been validated"
            )

        if isinstance(source, SourceName):
            source_name = source
        elif isinstance(source, Source):
            source_name = source.name
        else:
            raise UnknownTypeError("Unknown source type")

        if source_name not in self._sources:
            raise UnknownSourceError(f"Unknown source: {source_name}")

        return self._sources[source_name]
Example #7
0
    def __init__(self, yaml: Union[dict, str]):
        """Project __init__

        :param Union[dict, str] yaml: Parsed YAML python object for project
        :raise UnknownTypeError:
        """

        self.resolved_project_id: Optional[int] = None
        self._is_string = False

        if isinstance(yaml, str):
            self._is_string = True
            self.name: str = yaml
            self.branch: Optional[str] = None
            self.tag: Optional[str] = None
            self.commit: Optional[str] = None
            self.groups: Optional[List[str]] = None
            self.remote: Optional[str] = None
            self.path: Optional[Path] = None
            self.source: Optional[Union[Source, SourceName]] = None
            self.git_settings: Optional[GitSettings] = None
            self.upstream: Optional[Upstream] = None
            return

        self.name: str = yaml['name']
        self.branch: Optional[str] = yaml.get("branch", None)
        self.tag: Optional[str] = yaml.get("tag", None)
        self.commit: Optional[str] = yaml.get("commit", None)
        self.groups: Optional[List[str]] = yaml.get('groups', None)
        self.remote: Optional[str] = yaml.get('remote', None)

        path = yaml.get('path', None)
        self.path: Optional[Path] = Path(path) if path is not None else None

        self.source: Optional[Union[Source, SourceName]] = None
        source = yaml.get('source', None)
        if source is not None:
            if isinstance(source, SourceName):
                self.source: Optional[Union[Source,
                                            SourceName]] = SourceName(source)
            elif isinstance(source, dict):
                # Use project instance id as source name
                name = SourceName(id(self))
                self.source: Optional[Union[Source, SourceName]] = Source(
                    name, source)
            else:
                raise UnknownTypeError("Unknown source type")

        git = yaml.get('git', None)
        self.git_settings: Optional[GitSettings] = GitSettings(
            git) if git is not None else None

        upstream = yaml.get('upstream', None)
        self.upstream: Optional[Upstream] = Upstream(
            upstream) if upstream is not None else None
Example #8
0
    def get_yaml(self, resolved: bool = False) -> Union[dict, str]:
        """Return python object representation for saving yaml

        :param bool resolved: Whether to get resolved commit hashes
        :return: YAML python object
        :raise UnknownTypeError:
        """

        from clowder.clowder_controller import CLOWDER_CONTROLLER

        if self._is_string:
            if not resolved:
                return self.name

            return {
                "name":
                self.name,
                "commit":
                CLOWDER_CONTROLLER.get_project_sha(self.resolved_project_id)
            }

        yaml = {"name": self.name}

        if self.path is not None:
            yaml['path'] = str(self.path)
        if resolved:
            yaml['commit'] = CLOWDER_CONTROLLER.get_project_sha(
                self.resolved_project_id)
        else:
            if self.branch is not None:
                yaml['branch'] = self.branch
            if self.tag is not None:
                yaml['tag'] = self.tag
            if self.commit is not None:
                yaml['commit'] = self.commit
        if self.groups is not None:
            yaml['groups'] = self.groups
        if self.remote is not None:
            yaml['remote'] = self.remote
        if self.source is not None:
            if isinstance(self.source, SourceName):
                yaml['source'] = self.source
            elif isinstance(self.source, Source):
                yaml['source'] = self.source.get_yaml()
            else:
                raise UnknownTypeError('Unknown source type')
        if self.git_settings is not None:
            yaml['git'] = self.git_settings.get_yaml()
        if self.upstream is not None:
            yaml['upstream'] = self.upstream.get_yaml()

        return yaml
Example #9
0
    def short_ref(self) -> str:
        """Short git ref

        :raise UnknownTypeError:
        """
        if self.ref_type is GitRefEnum.BRANCH:
            return self.truncate_ref(self.branch)
        elif self.ref_type is GitRefEnum.TAG:
            return self.truncate_ref(self.tag)
        elif self.ref_type is GitRefEnum.COMMIT:
            return self.commit
        else:
            raise UnknownTypeError('Invalid GitRefEnum type')
Example #10
0
    def formatted_ref(self) -> str:
        """Formatted git ref

        :raise UnknownTypeError:
        """

        if self.ref_type is GitRefEnum.BRANCH:
            return self.format_git_branch(self.branch)
        elif self.ref_type is GitRefEnum.TAG:
            return self.format_git_tag(self.tag)
        elif self.ref_type is GitRefEnum.COMMIT:
            return self.commit
        else:
            raise UnknownTypeError('Invalid GitRefEnum type')
Example #11
0
    def __init__(self, yaml: Union[str, dict]):
        """Upstream __init__

        :param Union[str, dict] yaml: Parsed YAML python object for upstream
        :raise UnknownTypeError:
        """

        self._is_string = False

        if isinstance(yaml, str):
            self._is_string = True
            self.name: str = yaml
            self.remote: Optional[str] = None
            self.source: Optional[Union[Source, SourceName]] = None
            return

        if isinstance(yaml, dict):
            self.name: str = yaml['name']
            self.remote: Optional[str] = yaml.get('remote', None)

            self.source: Optional[Union[Source, SourceName]] = None
            source = yaml.get('source', None)
            if source is not None:
                if isinstance(source, SourceName):
                    self.source: Optional[Union[
                        Source, SourceName]] = SourceName(source)
                elif isinstance(source, dict):
                    # Use upstream instance id as source name
                    name = SourceName(id(self))
                    self.source: Optional[Union[Source, SourceName]] = Source(
                        name, source)
                else:
                    raise UnknownTypeError("Unknown source type")
            return

        raise UnknownTypeError("Unknown upstream type")
Example #12
0
    def format_url(self, url: str, name: str) -> str:
        """Return formatted git url

        :param str url: Repo url
        :param str name: Repo name
        :return: Full git repo url for specified protocol
        :raise UnknownTypeError:
        """

        if self is GitProtocol.SSH:
            return f"git@{url}:{name}.git"
        elif self is GitProtocol.HTTPS:
            return f"https://{url}/{name}.git"
        else:
            raise UnknownTypeError('Invalid git protocol')
Example #13
0
    def __init__(self, yaml: Union[dict, List[Project]]):
        """Upstream __init__

        :param Union[dict, List[Project]] yaml: Parsed YAML python object for clowder
        """

        if isinstance(yaml, dict):
            self.projects: Optional[List[Project]] = None
            self.sections: Optional[List[Section]] = [
                Section(name, section) for name, section in yaml.items()
            ]
        elif isinstance(yaml, list):
            self.projects: Optional[List[Project]] = [Project(p) for p in yaml]
            self.sections: Optional[List[Section]] = None
        else:
            raise UnknownTypeError("Unknown group type")
Example #14
0
    def _herd_initial(self, url: str, depth: int = 0) -> None:
        """Herd ref initial

        :param str url: URL of repo
        :param int depth: Git clone depth. 0 indicates full clone, otherwise must be a positive integer
        :raise UnknownTypeError:
        """

        self._init_repo()
        self._create_remote(self.remote, url, remove_dir=True)
        if self.default_ref.ref_type is GitRefEnum.BRANCH:
            self._checkout_new_repo_branch(self.default_ref.short_ref, depth)
        elif self.default_ref.ref_type is GitRefEnum.TAG:
            self._checkout_new_repo_tag(self.default_ref.short_ref, self.remote, depth, remove_dir=True)
        elif self.default_ref.ref_type is GitRefEnum.COMMIT:
            self._checkout_new_repo_commit(self.default_ref.short_ref, self.remote, depth)
        else:
            raise UnknownTypeError('Unknown GitRefEnum type')
Example #15
0
    def add_source(self, source: Optional[Union[Source, SourceName]]):
        """Register source with controller

        :param Optional[Union[Source, SourceName]] source: Source to add
        :raise SourcesValidatedError:
        :raise UnknownTypeError:
        """

        if self._has_been_validated:
            raise SourcesValidatedError(
                'Called add_source() but SOURCE_CONTROLLER has already been validated'
            )

        if source is None:
            return

        if isinstance(source, SourceName):
            self._source_names.add(source)
        elif isinstance(source, Source):
            self._source_names.add(source.name)
            self._sources[source.name] = source
        else:
            raise UnknownTypeError('Unknown source type')