def clone(ws_id: int, url: str, name: str = None): """ Clones a repository by url into given workspace :param name: Optional name of the local repository name, otherwise the remote name is taken :param user_data: Session data to get access token for GitHub :param ws_id: Destination workspace to clone :param url: URL of the source repository :return: True if successful, otherwise NameConflict is thrown """ workspace = get_workspace(ws_id) url_decode = parse.urlparse(url) if is_github(url_decode.netloc): # Take the suffix of url as first name candidate github_project_name = name if github_project_name is None: github_project_name = _repo_name_from_url(url_decode) dbsession = db_session() pj = dbsession.query(Project).join(Workspace)\ .filter(Workspace.id == workspace.id).filter( Project.name == github_project_name).first() dbsession.commit() # Error when the project name in given workspace already exists if pj is not None: raise NameConflict('A project with name {} already exists'.format(github_project_name)) project_target_path = os.path.join(workspace.path, PROJECT_REL_PATH, github_project_name) logger.info('Cloning from github repo...') # If url in GitHub domain, access by token url_with_token = _get_repo_url(url_decode) out, err, exitcode = git_command(['clone', url_with_token, project_target_path]) if exitcode is 0: setup_git_user_email(project_target_path) # Check if the project is a valid son project check_son_validity(project_target_path) # Create project and scan it. dbsession = db_session() try: pj = Project(github_project_name, github_project_name, workspace) pj.repo_url = url sync_project_descriptor(pj) dbsession.add(pj) scan_project_dir(project_target_path, pj) dbsession.commit() # Check if the project is valid result = create_info_dict(out=out) result["id"] = pj.id return result except: dbsession.rollback() shutil.rmtree(project_target_path) raise Exception("Scan project failed") else: return create_info_dict(err=err, exitcode=exitcode) raise NotImplemented("Cloning from other is not implemented yet. Only github is supported for now.")
def pull(ws_id: int, project_id: int): """ Pulls data from the given project_id. :param user_data: Session data to get access token for GitHub :param ws_id: Workspace of the project :param project_id: Project to pull. :return: """ dbsession = db_session() project = get_project(ws_id, project_id, session=dbsession) project_full_path = os.path.join(project.workspace.path, PROJECT_REL_PATH, project.rel_path) # Error handling if not os.path.isdir(project_full_path): raise Exception("Could not find project directory {}".format(project_full_path)) if not project.repo_url: raise InvalidArgument("Project with id {} is missing the repo attribute".format(project_id)) # Pull in project directory # If url in GitHub domain, access by token out, err, exitcode = git_command(['pull', project.repo_url], cwd=project_full_path) # Return error if pull failed. if exitcode is not 0: return create_info_dict(err=err, exitcode=exitcode) # Rescan project try: sync_project_descriptor(project) dbsession.add(project) scan_project_dir(project_full_path, project) dbsession.commit() except: dbsession.rollback() raise Exception("Could not scan the project after pull.") return create_info_dict(out=out)
def pull(ws_id: int, project_id: int): """ Pulls data from the given project_id. :param ws_id: Workspace of the project :param project_id: Project to pull. :return: a dictionary containing the result of the operation """ dbsession = db_session() project = get_project(ws_id, project_id, session=dbsession) project_full_path = os.path.join(project.workspace.path, PROJECT_REL_PATH, project.rel_path) # Error handling if not os.path.isdir(project_full_path): raise Exception("Could not find project directory {}".format(project_full_path)) if not project.repo_url: raise InvalidArgument("Project with id {} is missing the repo attribute".format(project_id)) # Pull in project directory # If url in GitHub domain, access by token out, err, exitcode = git_command(['pull', project.repo_url], cwd=project_full_path) # Return error if pull failed. if exitcode is not 0: return create_info_dict(err=err, exitcode=exitcode) # Rescan project try: sync_project_descriptor(project) dbsession.add(project) scan_project_dir(project_full_path, project) dbsession.commit() except: dbsession.rollback() raise Exception("Could not scan the project after pull.") return create_info_dict(out=out)