def run(args: argparse.Namespace) -> None: force = args.force update_manifest = args.update_manifest groups = args.groups all_cloned = args.all_cloned regex = args.regex iregex = args.iregex workspace = get_workspace(args) num_jobs = get_num_jobs(args) if update_manifest: ui.info_2("Updating manifest") workspace.update_manifest() else: ui.info_2("Not updating manifest") workspace.repos = resolve_repos(workspace, groups=groups, all_cloned=all_cloned, regex=regex, iregex=iregex) workspace.clone_missing(num_jobs=num_jobs) workspace.set_remotes(num_jobs=num_jobs) workspace.sync(force=force, num_jobs=num_jobs) workspace.perform_filesystem_operations() ui.info_1("Workspace synchronized")
def ensure_pull_request(self) -> PullRequest: pull_request = self.find_opened_pull_request() if pull_request: ui.info_2("Found existing pull request: #%s" % pull_request.number) return pull_request else: return self.create_pull_request()
def post_push(self) -> None: merge_request = self.ensure_merge_request() assert self.gitlab_api if self.args.close: ui.info_2("Closing merge request #%s" % merge_request.iid) merge_request.state_event = "close" merge_request.save() return assignee = None if self.requested_assignee: assignee = self.handle_assignee() if assignee: ui.info_2("Assigning to", assignee.username) title = self.handle_title(merge_request) merge_request.title = title merge_request.remove_source_branch = True if self.requested_target_branch: merge_request.target_branch = self.requested_target_branch if assignee: merge_request.assignee_id = assignee.id approvers = self.handle_approvers() merge_request.approvals.set_approvers([x.id for x in approvers]) merge_request.save() if self.args.accept: merge_request.merge(merge_when_pipeline_succeeds=True) ui.info(ui.green, "::", ui.reset, "See merge request at", merge_request.web_url)
def ensure_merge_request(self) -> ProjectMergeRequest: merge_request = self.find_merge_request() if merge_request: ui.info_2("Found existing merge request: !%s" % merge_request.iid) return merge_request else: return self.create_merge_request()
def handle_ios_deps(self) -> None: ui.info_2("Installing Tanker pod dependencies") tankerci.run("pod", "install", "--repo-update", "--clean-install", cwd=self.example_path)
def info_2(self, *args: Any, **kwargs: Any) -> None: """Same as cli_ui.info_2(), except this is a no-op if the task is run in parallel with other tasks. """ if not self.parallel: ui.info_2(*args, **kwargs)
def add_remote(self, repo: tsrc.Repo, remote: tsrc.Remote) -> None: full_path = self.workspace_path / repo.src # fmt: off ui.info_2(repo.src + ":", "Add remote", ui.bold, remote.name, ui.reset, ui.brown, "(%s)" % remote.url) # fmt: on tsrc.git.run(full_path, "remote", "add", remote.name, remote.url)
def download(): cli_ui.info_2("Downloading the newest version of PortCMS") if (not checker.checkGitStatus()): cli_ui.error( "Please download and install git to continue: https://git-scm.com/downloads" ) os._exit(1) isUpdate = False try: os.mkdir("PortCMS") except: what = cli_ui.ask_choice( "PortCMS is already downloaded. What do You want to do?", choices=["Update", "Check database config"]) isUpdate = what == "Update" if (not isUpdate): os.chdir("PortCMS") dbconf() os._exit(0) if (isUpdate): os.chdir("PortCMS") os.system("git pull") else: os.system( "git clone https://github.com/PetrusTryb/portfolio.git PortCMS") os.chdir("PortCMS") cli_ui.info(cli_ui.check, "Download complete")
def main(args: argparse.Namespace) -> None: path_as_str = args.workspace_path or os.getcwd() workspace_path = Path(path_as_str) cfg_path = workspace_path / ".tsrc" / "config.yml" if cfg_path.exists(): raise tsrc.Error("Workspace already configured with file " + cfg_path) ui.info_1("Configuring workspace in", ui.bold, workspace_path) workspace_config = WorkspaceConfig( manifest_url=args.url, manifest_branch=args.branch, clone_all_repos=args.clone_all_repos, repo_groups=args.groups, shallow_clones=args.shallow, ) workspace_config.save_to_file(cfg_path) workspace = Workspace(workspace_path) workspace.update_manifest() workspace.clone_missing() workspace.set_remotes() workspace.copy_files() ui.info_2("Workspace initialized") ui.info_2("Configuration written in", ui.bold, workspace.cfg_path)
def set_remote(self, repo: tsrc.Repo, remote: tsrc.Remote) -> None: full_path = self.workspace_path / repo.src # fmt: off ui.info_2(repo.src + ":", "Update remote", ui.reset, ui.bold, remote.name, ui.reset, "to new url:", ui.bold, remote.url) # fmt: on tsrc.git.run(full_path, "remote", "set-url", remote.name, remote.url)
def run(args: argparse.Namespace) -> None: workspace_path = args.workspace_path or Path.cwd() cfg_path = workspace_path / ".tsrc" / "config.yml" if cfg_path.exists(): raise tsrc.Error( f"Workspace already configured. `{cfg_path}` already exists") ui.info_1("Configuring workspace in", ui.bold, workspace_path) workspace_config = WorkspaceConfig( manifest_url=args.manifest_url, manifest_branch=args.manifest_branch, clone_all_repos=args.clone_all_repos, repo_groups=args.groups or [], shallow_clones=args.shallow_clones, singular_remote=args.singular_remote, ) workspace_config.save_to_file(cfg_path) workspace = Workspace(workspace_path) workspace.update_manifest() manifest = workspace.get_manifest() workspace.repos = repos_from_config(manifest, workspace_config) workspace.clone_missing() workspace.set_remotes() workspace.perform_filesystem_operations() ui.info_2("Workspace initialized") ui.info_2("Configuration written in", ui.bold, workspace.cfg_path)
def copy_test_sources(self) -> None: # trick cocoapods copy the Dummy.m to avoid error during validation ui.info_1("Copying dummy test file") dummy_test_path = self.src_path / "Tanker/Tests/Dummy.m" dest_path = self.dest_path / "Tests" dest_path.mkdir(parents=True, exist_ok=True) ui.info_2(dummy_test_path, "->", dest_path) shutil.copy(dummy_test_path, dest_path)
def copy_test_sources(self) -> None: # trick cocoapods copy the Dummy.m to avoid error during validation ui.info_1("Copying dummy test file") dummy_test_path = self.src_path / "Tanker/Tests/Dummy.m" dest_path = self.dest_path / "Tests" dest_path.makedirs_p() ui.info_2(dummy_test_path, "->", dest_path) dummy_test_path.copy(dest_path)
def add_google_trends_index(df: pd.DataFrame) -> (str, pd.DataFrame): """ Calculates the current "Bitcoin" Google Trends index and appends it to the DataFrame. Args: df: DataFrame containing Bitcoin data. Returns: Tuple. The first element is a string containing the column name of the index values. The second element is a modified source DataFrame containing the index values. References: Source: https://trends.google.com/trends/explore?date=today%205-y&q=bitcoin """ target_ratio = 1 / .125 cli_ui.info_2('Fetching Google Trends data') pytrends = TrendReq() pytrends.build_payload(kw_list=['Bitcoin']) df_interest = pytrends.interest_over_time() if df_interest.shape[0] < 100: raise Exception('Google Trends API returned too little data.') df_interest.reset_index(inplace=True) df_interest.rename(columns={ 'date': 'Date', 'Bitcoin': 'Interest' }, inplace=True) df_interest = mark_highs_lows(df_interest, 'Interest', True, round(365 * 2 / 7)) ignore_marks_since = pd.Timestamp('today').floor('D') - pd.Timedelta( 365, unit='D') df_interest.loc[df_interest['Date'] > ignore_marks_since, ['High', 'Low']] = 0 df = df.join(df_interest.set_index('Date'), on='Date') df.fillna({'High': 0, 'Low': 0}, inplace=True) df['Interest'].interpolate(inplace=True) def find_previous_high(row: pd.Series): peak_indexes = df[df['High'] == 1].index bin_index = np.digitize(row.name, peak_indexes) peak_value = np.NaN if bin_index == 0 else df.loc[ peak_indexes[bin_index - 1], 'Interest'] return peak_value df['PreviousHighInterest'] = df.apply(find_previous_high, axis=1) df['GoogleTrendsIndex'] = df['Interest'] / (df['PreviousHighInterest'] * target_ratio) return 'GoogleTrendsIndex', df
def init(working_path: Path, *, current_version: str) -> None: """ Interactively creates a new tbump.toml """ ui.info_1("Generating tbump config file") tbump_path = working_path / "tbump.toml" if tbump_path.exists(): ui.fatal(tbump_path, "already exists") template = textwrap.dedent("""\ # Uncomment this if your project is hosted on GitHub: # github_url = https://github.com/<user or organization>/<project>/ [version] current = "@current_version@" # Example of a semver regexp. # Make sure this matches current_version before # using tbump regex = ''' (?P<major>\\d+) \\. (?P<minor>\\d+) \\. (?P<patch>\\d+) ''' [git] message_template = "Bump to {new_version}" tag_template = "v{new_version}" """) file_template = textwrap.dedent(""" # For each file to patch, add a [[file]] config section containing # the path of the file, relative to the tbump.toml location. [[file]] src = "..." """) hooks_template = textwrap.dedent(""" # You can specify a list of commands to # run after the files have been patched # and before the git commit is made # [[before_commit]] # name = "check changelog" # cmd = "grep -q {new_version} Changelog.rst" # Or run some commands after the git tag and the branch # have been pushed: # [[after_push]] # name = "publish" # cmd = "./publish.sh" """) to_write = template.replace("@current_version@", current_version) to_write += file_template to_write += hooks_template tbump_path.write_text(to_write) ui.info_2(ui.check, "Generated tbump.toml")
def reset_repo(self, repo: tsrc.Repo) -> None: repo_path = self.workspace_path / repo.src ref = repo.sha1 if ref: ui.info_2("Resetting", repo.src, "to", ref) try: tsrc.git.run(repo_path, "reset", "--hard", ref) except tsrc.Error: raise tsrc.Error("Resetting to", ref, "failed")
def build_and_test_pod(self) -> None: ui.info_2("building pod and launching tests") generate_test_config(self.pod_path / "Tests", config_name="dev") ci.run("pod", "lib", "lint", "--verbose", "--allow-warnings", cwd=self.pod_path)
def sync_repo_to_ref(repo_path: Path, ref: str) -> None: ui.info_2("Resetting to", ref) status = tsrc.git.get_status(repo_path) if status.dirty: raise tsrc.Error(f"{repo_path} is dirty, skipping") try: tsrc.git.run(repo_path, "reset", "--hard", ref) except tsrc.Error: raise tsrc.Error("updating ref failed")
def fetch(self, repo: tsrc.Repo) -> None: repo_path = self.workspace_path / repo.src for remote in repo.remotes: try: ui.info_2("Fetching", remote.name) tsrc.git.run(repo_path, "fetch", "--tags", "--prune", remote.name) except tsrc.Error: raise tsrc.Error("fetch from %s failed" % remote.name)
def generate_archive(self) -> Path: version = self.get_version_from_spec() ui.info_1("Generating archive, version:", version) archive_name = "tanker-ios-sdk-%s.tar.gz" % version with tankerci.working_directory(self.dest_path): tankerci.run("tar cfvz %s *" % archive_name, shell=True) shutil.copy(archive_name, self.src_path) res = self.src_path / archive_name ui.info_2("Generated", res) return res
def build_and_test_pod(self) -> None: ui.info_2("building pod and launching tests") tankerci.run( "pod", "lib", "lint", "--verbose", "--allow-warnings", str(self.pod_path / "Tanker.podspec"), )
def update(self) -> None: ui.info_2("Updating manifest") if not self.clone_path.exists(): message = "Could not find manifest in {}. " message += "Did you run `tsrc init` ?" raise tsrc.Error(message.format(self.clone_path)) cmd = ("fetch", "--prune", "origin") tsrc.git.run(self.clone_path, *cmd) cmd = ("reset", "--hard", "@{upstream}") tsrc.git.run(self.clone_path, *cmd)
def find_files(working_path: Path, current_version: str) -> List[str]: ui.info_2("Looking for files matching", ui.bold, current_version) cmd = ["grep", "--fixed-strings", "--files-with-matches", current_version] _, out = tbump.git.run_git_captured(working_path, *cmd, check=True) res = [] # type: List[str] ui.info("Found following matching files") for file in out.splitlines(): ui.info(" * ", file) res.append(file) return res
def fetch(self, repo: tsrc.Repo) -> None: repo_path = self.workspace_path / repo.dest for remote in self._pick_remotes(repo): try: ui.info_2("Fetching", remote.name) cmd = ["fetch", "--tags", "--prune", remote.name] if self.force: cmd.append("--force") tsrc.git.run(repo_path, *cmd) except tsrc.Error: raise tsrc.Error(f"fetch from '{remote.name}' failed")
def print_group(self, dry_run: bool = False) -> None: if not self.actions: return if dry_run: ui.info_2(self.dry_run_desc) else: ui.info_2(self.desc) for i, action in enumerate(self.actions): if self.should_enumerate: ui.info_count(i, len(self.actions), end="") action.print_self()
def on_success(self) -> None: erase_last_line() if not self.statuses: ui.info_2("Workspace is empty") return ui.info_2("Workspace status:") max_dest = max(len(x) for x in self.statuses.keys()) for dest, status in self.statuses.items(): message = [ui.green, "*", ui.reset, dest.ljust(max_dest)] message += describe_status(status) ui.info(*message)
def push(self) -> None: ui.info_2("Running git push") remote_name = self.remote_name or "origin" if self.args.push_spec: push_spec = self.args.push_spec else: push_spec = "%s:%s" % (self.current_branch, self.remote_branch) cmd = ["push", "-u", remote_name, push_spec] if self.args.force: cmd.append("--force") tsrc.git.run(self.repo_path, *cmd)
def _copy_folder_content(src_path: Path, dest_path: Path) -> None: ui.info_1("Moving content of", src_path, "to", dest_path) for src_dir in src_path.dirs(): dest_dir = dest_path / src_dir.basename() dest_dir.rmtree_p() ui.info_2(src_dir, "->", dest_dir) src_dir.copytree(dest_dir) for src_file in src_path.files(): dest_file = dest_path / src_file.basename() dest_file.remove_p() ui.info_2(src_file, "->", dest_file) src_file.copy2(dest_file)
def copy_sources(self) -> None: ui.info_1("Copying sources") sources_path = self.src_path / "Tanker/Sources" ui.info_2(sources_path, "->", self.dest_path) sources_path.copytree(self.dest_path / "Sources") export_list_src = self.src_path / "Tanker/export_symbols.list" export_list_dest = self.dest_path / "export_symbols.list" ui.info_2(export_list_src, "->", export_list_dest) export_list_src.copy(export_list_dest)
def set_remotes(self, num_jobs: int = 1) -> None: if self.config.singular_remote: return ui.info_2("Configuring remotes") remote_setter = RemoteSetter(self.root_path) collection = process_items(self.repos, remote_setter, num_jobs=num_jobs) collection.print_summary() if collection.errors: ui.error("Failed to set remotes for the following repos:") collection.print_errors() raise RemoteSetterError