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()
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")
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)
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')
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')
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]
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
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
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')
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')
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")
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')
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")
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')
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')