def update(self, challenge=None): config = load_config() challenges = dict(config["challenges"]) for folder, url in challenges.items(): if challenge and challenge != folder: continue if url.endswith(".git"): click.echo(f"Pulling latest {url} to {folder}") head_branch = get_git_repo_head_branch(url) subprocess.call( [ "git", "subtree", "pull", "--prefix", folder, url, head_branch, "--squash", ], cwd=get_project_path(), ) subprocess.call(["git", "mergetool"], cwd=folder) subprocess.call(["git", "clean", "-f"], cwd=folder) subprocess.call(["git", "commit", "--no-edit"], cwd=folder) else: click.echo(f"Skipping {url} - {folder}")
def add(self, repo): config = load_config() if repo.endswith(".git"): # Get relative path from project root to current directory challenge_path = Path( os.path.relpath(os.getcwd(), get_project_path())) # Get new directory that will exist after clone base_repo_path = Path( os.path.basename(repo).rsplit(".", maxsplit=1)[0]) # Join targets challenge_path = challenge_path / base_repo_path print(challenge_path) config["challenges"][str(challenge_path)] = repo with open(get_config_path(), "w+") as f: config.write(f) subprocess.call(["git", "clone", "--depth", "1", repo]) shutil.rmtree(str(base_repo_path / ".git")) elif Path(repo).exists(): config["challenges"][repo] = repo with open(get_config_path(), "w+") as f: config.write(f) else: click.secho( "Couldn't process that challenge path. Please check it for errors.", fg="red", )
def sync(self, challenge=None, ignore=()): if challenge is None: # Get all challenges if not specifying a challenge config = load_config() challenges = dict(config["challenges"]).keys() else: challenges = [challenge] if isinstance(ignore, str): ignore = (ignore,) for challenge in challenges: path = Path(challenge) if path.name.endswith(".yml") is False: path = path / "challenge.yml" click.secho(f"Found {path}") challenge = load_challenge(path) click.secho(f'Loaded {challenge["name"]}', fg="yellow") installed_challenges = load_installed_challenges() for c in installed_challenges: if c["name"] == challenge["name"]: break else: click.secho( f'Couldn\'t find existing challenge {c["name"]}. Perhaps you meant install instead of sync?', fg="red", ) continue # Go to the next challenge in the overall list click.secho(f'Syncing {challenge["name"]}', fg="yellow") sync_challenge(challenge=challenge, ignore=ignore) click.secho(f"Success!", fg="green")
def update(self, challenge=None): config = load_config() challenges = dict(config["challenges"]) for folder, url in challenges.items(): if challenge and challenge != folder: continue if url.endswith(".git"): click.echo(f"Cloning {url} to {folder}") subprocess.call(["git", "init"], cwd=folder) subprocess.call(["git", "remote", "add", "origin", url], cwd=folder) subprocess.call(["git", "add", "-A"], cwd=folder) subprocess.call( ["git", "commit", "-m", "Persist local changes (ctfcli)"], cwd=folder, ) subprocess.call( ["git", "pull", "--allow-unrelated-histories", "origin", "master"], cwd=folder, ) subprocess.call(["git", "mergetool"], cwd=folder) subprocess.call(["git", "clean", "-f"], cwd=folder) subprocess.call(["git", "commit", "--no-edit"], cwd=folder) shutil.rmtree(str(Path(folder) / ".git")) else: click.echo(f"Skipping {url} - {folder}")
def restore(self): config = load_config() challenges = dict(config["challenges"]) for folder, url in challenges.items(): if url.endswith(".git"): click.echo(f"Cloning {url} to {folder}") subprocess.call(["git", "clone", "--depth", "1", url, folder]) shutil.rmtree(str(Path(folder) / ".git")) else: click.echo(f"Skipping {url} - {folder}")
def update(self): config = load_config() challenges = dict(config["challenges"]) for folder, url in challenges.items(): if url.endswith(".git"): click.echo(f"Cloning {url} to {folder}") subprocess.call(["git", "init"], cwd=folder) subprocess.call(["git", "remote", "add", "origin", url], cwd=folder) subprocess.call(["git", "pull"], cwd=folder) shutil.rmtree(str(Path(folder) / ".git")) else: click.echo(f"Skipping {url} - {folder}")
def add(self, repo): config = load_config() if repo.endswith(".git"): # Get relative path from project root to current directory challenge_path = Path(os.path.relpath(os.getcwd(), get_project_path())) # Get new directory that will add the git subtree base_repo_path = Path(os.path.basename(repo).rsplit(".", maxsplit=1)[0]) # Join targets challenge_path = challenge_path / base_repo_path print(challenge_path) config["challenges"][str(challenge_path)] = repo head_branch = get_git_repo_head_branch(repo) subprocess.call( [ "git", "subtree", "add", "--prefix", challenge_path, repo, head_branch, "--squash", ], cwd=get_project_path(), ) with open(get_config_path(), "w+") as f: config.write(f) subprocess.call( ["git", "add", ".ctf/config"], cwd=get_project_path(), ) subprocess.call( ["git", "commit", "-m", f"Added {str(challenge_path)}"], cwd=get_project_path(), ) elif Path(repo).exists(): config["challenges"][repo] = repo with open(get_config_path(), "w+") as f: config.write(f) else: click.secho( "Couldn't process that challenge path. Please check it for errors.", fg="red", )
def push(self, challenge=None): config = load_config() challenges = dict(config["challenges"]) if challenge is None: # Get relative path from project root to current directory challenge_path = Path(os.path.relpath(os.getcwd(), get_project_path())) challenge = str(challenge_path) try: url = challenges[challenge] head_branch = get_git_repo_head_branch(url) subprocess.call( ["git", "subtree", "push", "--prefix", challenge, url, head_branch], cwd=get_project_path(), ) except KeyError: click.echo( "Couldn't process that challenge path. Please check that the challenge is added to .ctf/config and that your path matches." )
def install(self, challenge=None, force=False, ignore=()): if challenge is None: # Get all challenges if not specifying a challenge config = load_config() challenges = dict(config["challenges"]).keys() else: challenges = [challenge] if isinstance(ignore, str): ignore = (ignore,) for challenge in challenges: path = Path(challenge) if path.name.endswith(".yml") is False: path = path / "challenge.yml" click.secho(f"Found {path}") challenge = load_challenge(path) click.secho(f'Loaded {challenge["name"]}', fg="yellow") installed_challenges = load_installed_challenges() for c in installed_challenges: if c["name"] == challenge["name"]: click.secho( f'Already found existing challenge with same name ({challenge["name"]}). Perhaps you meant sync instead of install?', fg="red", ) if force is True: click.secho( "Ignoring existing challenge because of --force", fg="yellow", ) else: break else: # If we don't break because of duplicated challenge names click.secho(f'Installing {challenge["name"]}', fg="yellow") create_challenge(challenge=challenge, ignore=ignore) click.secho(f"Success!", fg="green")
def restore(self, challenge=None): config = load_config() challenges = dict(config["challenges"]) for folder, url in challenges.items(): if url.endswith(".git"): if challenge is not None and folder != challenge: continue click.echo(f"Adding git repo {url} to {folder} as subtree") head_branch = get_git_repo_head_branch(url) subprocess.call( [ "git", "subtree", "add", "--prefix", folder, url, head_branch, "--squash", ], cwd=get_project_path(), ) else: click.echo(f"Skipping {url} - {folder}")