def update_informations(self, create=False, path=None): """ Updates class-attributes with new informations collected from meta.yaml, git config and current datetime. Parameters ---------- create: bool If project isn't created yet the name of the environment can't be extracted from the meta.yaml. In this case it has to be combined from companyname, namespace and projectname. path: pathlib.Path The projects-path. Note ---- Uses :class:`conda.MetaYaml` to collect the name of environment from the current project if **create** is False. To collect git-specific informations :class:`git.GitRepo` is used. Checks for valid project-definition with :class:`validators.SProject`. """ self.environment = f'{self.company}-{self.namespace}-{self.project}' if create: if not path: path = self.path.parent self.git = git.GitRepo(path=self.path) else: #if not self.environment in str(self.path): # self.path = self.path / self.environment if not path: path = self.path meta_yaml = conda.MetaYaml(path=path / CONFIG['meta_yaml_path']) self.environment = meta_yaml.package_name self.git = git.GitRepo(path=self.path) self.version = self.git.get_tag() now = dt.datetime.now() self.year = now.strftime('%Y') self.today = now.strftime('%Y-%m-%d %H:%M') self.username = self.git.get_username() self.email = self.git.get_email() try: validators.SProject(strict=True).load(self.__dict__) except ValidationError as err: inform.error('Can\'t collect project information.') inform.error('Invalid value for following params:') for key, value in err.messages.items(): inform.error(f'{key}: {value}') inform.critical()
def test_gitrepo_initialize_ok(cleanup, tmpdir): os.chdir(tmpdir) curr_git = git.GitRepo(path=Path(tmpdir)) curr_git.initialize() assert curr_git.status() (Path(tmpdir) / 'testfile.txt').touch() assert not curr_git.status()
def test_create_on_vcs_ok(self, tmpdir): curr_git = git.GitRepo(path=Path(tmpdir)) git.create_on_remote_vcs( company='ouroboros', namespace='testing', project=f'pytesttesting{random.randint(1, 100000)}', username=curr_git.get_username())
def test_gitrepo_ok(cleanup, tmpdir): path, prj, tdir = created_project(tmpdir) os.chdir(path) prj.new_version(vtype='major') curr_git = git.GitRepo(path=path) assert curr_git.get_tag() == '1.0.0' (Path(path) / 'testfile.txt').touch() assert not curr_git.status() curr_git.add_all() curr_git.commit() assert curr_git.status() curr_git.create_tag(tag='20.0.0', message='bla') assert curr_git.get_tag() == '20.0.0' assert curr_git.get_username() assert curr_git.get_email() tdir.remove()
def release_log(self, ssh, action, projectpath): """ Write information about ssh-interaction on the destination host as passed in ssh. ssh: paramiko.SSHClient Connection via ssh where to log the output to. action: str action as a string to log into the log-file. Example: "create" projectpath: str Path of currrent project. """ git_repo = git.GitRepo(path=projectpath) log_entry = (f'{dt.datetime.utcnow().isoformat()} ' f'[{getpass.getuser()}@{socket.gethostname()}] ' f'{action.upper()} {self.name} ' f'[SOURCE: {git_repo.get_branch()} {git_repo.get_tag()}]') cmd = f'echo "{log_entry}" >> ~/.pproject.log' _, stdout, stderr = ssh.exec_command(cmd) stdout.channel.recv_exit_status() err = stderr.read().strip().decode('ascii')
def __attrs_post_init__(self): envname = f'{self.company}-{self.namespace}-{self.project}' #if not envname in str(self.path): # self.path = Path(self.path) / envname self.git = git.GitRepo(path=self.path)
def create(self, on_vcs=False, path=None): """ Creates new project based on a defined skeleton either local or on gitlab with cookiecutter, creates the base-conda-environment for developing the new project and manages corresponding git-tasks. Parameters ---------- on_vcs: bool Flag to define if project should be added to remote vcs after creation. path: pathlib.Path The projects path. Note ---- Calls :func:`Project.update_informations` with **create=True** to update the **attributes** of the project. For git operations the function :func:`utils.run_in_bash` is called. After creation :func:`Project.update` with **path** set to current working directory is called to create the conda-environment of the project. """ if not path: path = self.path.parent self.update_informations(create=True, path=path) assert isinstance(path, Path) if not (path / self.environment).exists(): if on_vcs: if not git.check_remote_vcs(): inform.error('Remote vcs not accessable') inform.critical() inform.info(f'Creating project {self.environment}') cookiecutter(CONFIG['skeleton_repo'], checkout=str(self.pythonversion), output_dir=str(Path.cwd()), no_input=True, extra_context=self.__dict__) inform.info('Created folder') os.chdir(str((path / self.environment).absolute())) if not self.environment in str(self.path): self.path = self.path / self.environment self.git = git.GitRepo(path=self.path) if on_vcs: create_on_remote_res = git.create_on_remote_vcs( company=self.company, namespace=self.namespace, project=self.project, username=self.git.get_username()) inform.info('Initializing git') self.git.initialize() inform.info('Adding files') self.git.add_all() inform.info('Commiting') self.git.commit() vcs_ssh = VCS_SETTINGS['ssh'] vcs = CONFIG['vcs']['use'] vcs_use_groups = VCS_SETTINGS['use_groups'] if on_vcs: if vcs == 'gitlab' and vcs_use_groups: git_repo = f'{create_on_remote_res}/{self.project}.git' else: git_repo = f'{create_on_remote_res}.git' if ':' in vcs_ssh: git_origin = f'{vcs_ssh}/{git_repo}' else: git_origin = f'{vcs_ssh}:{git_repo}' inform.info(f'Setting origin to {git_origin}') self.git.set_origin(git_origin) inform.info(f'Pushing to origin') self.git.push_to_branch('master') inform.finished() self.update(path=(path / self.environment).absolute()) else: inform.error('Folder already exists') inform.critical()