def handle_status(self, args): if self.is_initialized(): try: level = self.get_level() level.status() except KeyError: level_name = operations.get_operator().read_level_file() print( 'Currently on unregistered level: "{}"'.format(level_name)) else: print("Git Gud not initialized.") print('Initialize using "git gud init"')
def load_level(self, level): # Clear remotes self.assert_initialized(skip_level_check=True) file_operator = operations.get_operator() level_repo = file_operator.setup_repo() if level_repo: for remote in level_repo.remotes: level_repo.delete_remote(remote) else: file_operator.setup_repo() file_operator.clear_tracked_commits() level.setup() file_operator.write_level(level)
def assert_initialized(self, skip_level_check=False): if not self.is_initialized(): raise InitializationError( 'Git gud has not been initialized. Use "git gud init" to initialize' ) # noqa: E501 if not skip_level_check: try: self.get_level() except KeyError: level_name = operations.get_operator().read_level_file() raise InitializationError( 'Currently loaded level does not exist: "{}"'.format( level_name))
def _setup(self): file_operator = operations.get_operator(initialize_repo=True) commits, head = parse_spec(self.file('setup.spec')) file_operator.create_tree(commits, head) latest_commit = '0' for commit_name, _, _, _ in commits: try: if int(commit_name) > int(latest_commit): latest_commit = commit_name except ValueError: pass # Commit is merge and doesn't have number file_operator.write_last_commit(latest_commit)
def test_load(gg): load_tests = [ ('git gud load 1', all_skills["1"]["1"]), ('git gud load rampup', all_skills["rampup"]["1"]), ('git gud load 2 detaching', all_skills["2"]["detaching"]), ('git gud load rampup 4', all_skills["rampup"]["4"]), ('git gud load 5-octopus', all_skills["5"]["octopus"]), ('git gud load rampup-4', all_skills["rampup"]["4"]), ('git gud load -2', all_skills["rampup"]["2"]) ] for command, level in load_tests: subprocess.call(command, shell=True) op = operations.get_operator() assert level == op.get_level()
def parse(self): args, _ = self.parser.parse_known_args() if args.command is None: if operations.get_operator() is None: print('Currently in an uninitialized directory.') print( 'Get started by running "git gud init" in an empty directory!' ) # noqa: E501 else: self.parser.print_help() else: try: self.command_dict[args.command](args) except InitializationError as error: print(error)
def parse(self): if len(sys.argv) >= 2 and sys.argv[1] in self.aliases: sys.argv[1] = self.aliases[sys.argv[1]] args, _ = self.parser.parse_known_args(sys.argv[1:]) if args.command is None: if get_operator() is None: print('Currently in an uninitialized directory.') print( 'Get started by running "git gud init" in an empty directory!' ) # noqa: E501 else: self.parser.print_help() else: try: self.command_dict[args.command](args) except InitializationError as error: print(error)
def handle_load(self, args): self.assert_initialized() args.skill_name = args.skill_name.lower() if args.level_name: args.level_name = args.level_name.lower() if args.skill_name in {"next", "prev", "previous"}: self.load_level_by_direction(args.skill_name, args.force) return # No matter what, the dash separates the skill and level if '-' in args.skill_name: identifier = args.skill_name + (args.level_name or '') else: identifier = args.skill_name + '-' + (args.level_name or '') if identifier.count('-') != 1: print("Load formula must not contain more than one dash.") return args.skill_name, args.level_name = identifier.split('-') if not args.skill_name: args.skill_name, loaded_level_name = get_operator() \ .get_level_identifier() print("Inferring skill from currently loaded level: {} {}".format( args.skill_name, loaded_level_name)) if not args.level_name: args.level_name = '1' # Skill doesn't exist if args.skill_name not in all_skills.keys(): print('Skill "{}" does not exist'.format(args.skill_name)) print('\nTo view levels/skills, use "git gud levels --all"') return # Level doesn't exist skill = all_skills[args.skill_name] if args.level_name not in skill.keys(): print('Level "{}" does not exist.'.format(args.level_name)) print('\nTo view levels/skills, use "git gud levels --all"') return level = skill[args.level_name] self.load_level(level)
def setup_rebase_conflict(): file_operator = get_operator() with open("foo", "w") as f: f.write("branch 1") file_operator.repo.index.add("foo") file_operator.repo.index.commit("Add a file") file_operator.repo.git.checkout('-b', 'branch', 'HEAD~') with open("foo", "w") as f: f.write("branch 2") file_operator.repo.index.add("foo") file_operator.repo.index.commit("Add a file") try: file_operator.repo.git.rebase('master') except GitCommandError: # This will happen every time pass
def handle_commit(self, args): self.assert_initialized() file_operator = get_operator() last_commit = file_operator.get_last_commit() commit_name = str(int(last_commit) + 1) if args.file is not None: try: int(args.file) commit_name = args.file except ValueError: pass commit = file_operator.add_and_commit(commit_name, silent=False) file_operator.track_commit(commit_name, commit.hexsha) # Next "git gud commit" name if int(commit_name) > int(last_commit): file_operator.write_last_commit(commit_name)
def handle_init(self, args): # Make sure it's safe to initialize file_operator = get_operator() if file_operator: if not args.force: repo_already_initialized() return else: force_initializing() elif len(list(Path.cwd().iterdir())) != 0: if not (args.force and args.prettyplease): cant_init_repo_not_empty() return else: deleting_and_initializing() file_operator = Operator(Path.cwd()) file_operator.init_gg() self.load_level(all_skills["0"]["1"])
def _setup(self): file_operator = operations.get_operator() file_operator.use_repo() commits, head = parse_spec(self.file('setup.spec')) details_path = self.file('details.yaml') if details_path.is_file(): details = yaml.safe_load(details_path.open()) else: details = None file_operator.create_tree(commits, head, details, self.level_dir) latest_commit = '0' for commit_name, _, _, _ in commits: try: if int(commit_name) > int(latest_commit): latest_commit = commit_name except ValueError: pass # Commit is merge and doesn't have number file_operator.write_last_commit(latest_commit)
def handle_commit(self, args): self.assert_initialized() file_operator = operations.get_operator() last_commit = file_operator.get_last_commit() commit_name = str(int(last_commit) + 1) if args.file is not None: try: int(args.file) commit_name = args.file except ValueError: pass print_info('Created file "{}"'.format(commit_name)) mock_simulate('git add {}'.format(commit_name)) mock_simulate('git commit -m "{}"'.format(commit_name)) commit = file_operator.add_and_commit(commit_name) print_info("New Commit: {}".format(commit.hexsha[:7])) file_operator.track_commit(commit_name, commit.hexsha) # Next "git gud commit" name if int(commit_name) > int(last_commit): file_operator.write_last_commit(commit_name)
def mark_visited(self): file_operator = operations.get_operator() file_operator.mark_level(self, "visited")
def handle_load(self, args): self.assert_initialized(skip_level_check=True) args.skill_name = args.skill_name.lower() if args.skill_name: if args.skill_name in {"next", "prev", "previous"}: if args.skill_name == "prev": args.skill_name = "previous" self.assert_initialized("Cannot load {} level.".format( args.skill_name)) level = get_operator().get_level() if args.skill_name == "next": if not args.force and not level.has_ever_been_completed(): handle_load_confirm() return level_to_load = level.next_level else: level_to_load = level.prev_level if level_to_load is not None: self.load_level(level_to_load) else: if args.skill_name == "next": all_levels_complete() else: print( 'Already on the first level. To reload the level, use "git gud reload".' ) # noqa: E501 print('\nTo view levels/skills, use "git gud levels --all"' ) # noqa: E501 return # No matter what, the dash separates the skill and level if '-' in args.skill_name: identifier = args.skill_name + (args.level_name or '') else: identifier = args.skill_name + '-' + (args.level_name or '') if identifier.count('-') != 1: print("Load formula must not contain more than one dash.") return args.skill_name, args.level_name = identifier.split('-') if not args.skill_name: args.skill_name, loaded_level_name = get_operator() \ .get_level_identifier() print("Inferring skill from currently loaded level: {} {}".format( args.skill_name, loaded_level_name)) if not args.level_name: args.level_name = '1' if args.skill_name in all_skills.keys(): skill = all_skills[args.skill_name] if args.level_name in skill.keys(): level = skill[args.level_name] self.load_level(level) else: print('Level "{}" does not exist.'.format(args.level_name)) print('\nTo view levels/skills, use "git gud levels --all"') else: print('Skill "{}" does not exist'.format(args.skill_name)) print('\nTo view levels/skills, use "git gud levels --all"')
def handle_level(self, args): self.assert_initialized() level = get_operator().get_level() skill = level.skill show_skill_tree([skill, level], expand_skills=False)
def handle_test(self, args): self.assert_initialized() level = get_operator().get_level() level.test()
def handle_reset(self, args): self.assert_initialized() level = get_operator().get_level() self.load_level(level)
def handle_goal(self, args): self.assert_initialized() get_operator().get_level().goal()
def handle_explain(self, args): self.assert_initialized() get_operator().get_level().explain()
def display_staging_area_content(**kwargs): file_operator = operations.get_operator() staging_area = file_operator.get_staging_content() display_tree_content("Staging Area:", staging_area, **kwargs)
def target_branch_str(): file_operator = operations.get_operator() referred_by = file_operator.get_branches_by_commit() for target in referred_by: referred_by[target] = ", ".join(referred_by[target]) return referred_by
def _setup(self): # Make sure we are not in a git repo file_operator = operations.get_operator() file_operator.destroy_repo()
def mark_partial(self): file_operator = operations.get_operator() file_operator.mark_level(self, "partial")
def _test(self): # Check if we are in a git repo file_operator = operations.get_operator() return file_operator.repo is not None
def get_progress(self): file_operator = operations.get_operator() return file_operator.get_level_progress(self)
def display_working_directory_content(**kwargs): file_operator = operations.get_operator() working_dir = file_operator.get_working_directory_content() display_tree_content("Working Directory:", working_dir, **kwargs)
def is_initialized(self): return get_operator() is not None
def __init__(self): self.file_operator = get_operator( ) # Only gets operator if in a valid gitgud repo self.parser = argparse.ArgumentParser(prog='git gud') subparsers = self.parser.add_subparsers(title='Subcommands', metavar='<command>', dest='command') # TODO Add git gud help <command>, which would return the same output as git gud <command> -- help # TODO Display help message for subcommand when it fails. # ie `git gud load level1 challenge1 random-input` should have output similar to `git gud load --help` start_parser = subparsers.add_parser('start', help='Git started!') status_parser = subparsers.add_parser( 'status', help='Print out the current level') instructions_parser = subparsers.add_parser( 'instructions', help='Show the instructions for the current level') reset_parser = subparsers.add_parser('reset', help='Reset the current level') test_parser = subparsers.add_parser( 'test', help= 'Test to see if you\'ve successfully completed the current level') progress_parser = subparsers.add_parser( 'progress', help='Continue to the next level') levels_parser = subparsers.add_parser('levels', help='List levels') challenges_parser = subparsers.add_parser( 'challenges', help= 'List challenges in current level or in other level if specified') load_parser = subparsers.add_parser( 'load', help='Load a specific level or challenge') commit_parser = subparsers.add_parser( 'commit', help='Quickly create and commit a file') goal_parser = subparsers.add_parser( 'goal', help='Show a description of the current goal') show_tree_parser = subparsers.add_parser( 'show-tree', help='Show the current state of the branching tree') start_parser.add_argument('--force', action='store_true') challenges_parser.add_argument('level_name', metavar='level', nargs='?') load_parser.add_argument('level_name', metavar='level', help='Level to load') load_parser.add_argument('challenge_name', metavar='challenge', nargs='?', help='Challenge to load') commit_parser.add_argument('file', nargs='?') self.command_dict = { 'start': self.handle_start, 'status': self.handle_status, 'instructions': self.handle_instructions, 'reset': self.handle_reset, 'test': self.handle_test, 'progress': self.handle_progress, 'levels': self.handle_levels, 'challenges': self.handle_challenges, 'load': self.handle_load, 'commit': self.handle_commit, 'goal': self.handle_goal, 'show_tree': self.handle_show_tree, }
def load_level(self, level): self.assert_initialized(skip_level_check=True) file_operator = get_operator() file_operator.clear_tracked_commits() level.setup() file_operator.write_level(level)