diff --git a/gitup.py b/gitup.py index 2386e74..4675dd0 100644 --- a/gitup.py +++ b/gitup.py @@ -20,14 +20,28 @@ __email__ = "ben.kurtovic@verizon.net" config_filename = os.path.join(os.path.expanduser("~"), ".gitup") -ansi = { # ANSI escape codes to make terminal output colorful - "reset": "\x1b[0m", - "bold": "\x1b[1m", - "red": "\x1b[1m\x1b[31m", - "green": "\x1b[1m\x1b[32m", - "yellow": "\x1b[1m\x1b[33m", - "blue": "\x1b[1m\x1b[34m", -} +# Text formatting functions +bold = lambda t: style_text(t, "bold") +red = lambda t: style_text(t, "red") +green = lambda t: style_text(t, "green") +yellow = lambda t: style_text(t, "yellow") +blue = lambda t: style_text(t, "blue") + +def style_text(text, effect): + """Give a text string a certain effect, such as boldness, or a color.""" + ansi = { # ANSI escape codes to make terminal output fancy + "reset": "\x1b[0m", + "bold": "\x1b[1m", + "red": "\x1b[1m\x1b[31m", + "green": "\x1b[1m\x1b[32m", + "yellow": "\x1b[1m\x1b[33m", + "blue": "\x1b[1m\x1b[34m", + } + + try: # pad text with effect, unless effect does not exist + return "{}{}{}".format(ansi[effect], text, ansi['reset']) + except KeyError: + return text def out(indent, msg): """Print a message at a given indentation level.""" @@ -57,7 +71,7 @@ def directory_is_git_repo(directory_path): def update_repository(repo_path, repo_name): """Update a single git repository by pulling from the remote.""" - out(1, "{}{}{}:".format(ansi['bold'], repo_name, ansi['reset'])) + out(1, bold(repo_name) + ":") os.chdir(repo_path) # cd into our folder so git commands target the correct # repo @@ -67,34 +81,33 @@ def update_repository(repo_path, repo_name): # anything to pull, but # don't do it yet except subprocess.CalledProcessError: - out(2, """{}Error:{} cannot fetch; do you have a remote repository - configured correctly?""".format(ansi['red'], ansi['reset'])) + out(2, red("Error: ") + "cannot fetch; do you have a remote " + + "repository configured correctly?") return try: - last = exec_shell("git log -n 1 --pretty=\"%ar\"") # last commit time + last_commit = exec_shell("git log -n 1 --pretty=\"%ar\"") except subprocess.CalledProcessError: - last = "never" # couldn't get a log, so no commits + last_commit = "never" # couldn't get a log, so no commits if not dry_fetch: # no new changes to pull - out(2, "{}No new changes.{} Last commit was {}.".format(ansi['blue'], - ansi['reset'], last)) + out(2, blue("No new changes.") + " Last commit was {}.".format( + last_commit)) else: # stuff has happened! out(2, "There are new changes upstream...") status = exec_shell("git status") if status.endswith("nothing to commit (working directory clean)"): - out(2, "{}Pulling new changes...{}".format(ansi['green'], - ansi['reset'])) + out(2, green("Pulling new changes...")) result = exec_shell("git pull") out(2, "The following changes have been made since {}:".format( - last)) + last_commit)) print result else: - out(2, """{}Warning:{} You have uncommitted changes in this - repository!""".format(ansi['red'], ansi['reset'])) + out(2, red("Warning: ") + "you have uncommitted changes in this " + + "repository!") out(2, "Ignoring.") def update_directory(dir_path, dir_name, is_bookmark=False): @@ -103,32 +116,28 @@ def update_directory(dir_path, dir_name, is_bookmark=False): of git repositories. If the former, update the single repository; if the latter, update all repositories contained within.""" if is_bookmark: - dir_source = "Bookmark" # where did we get this directory from? + dir_type = "bookmark" # where did we get this directory from? else: - dir_source = "Directory" + dir_type = "directory" + + dir_long_name = "{} '{}'".format(dir_type, bold(dir_path)) try: os.listdir(dir_path) # test if we can access this directory except OSError: - out(0, "{}Error:{} cannot enter {} '{}{}{}'; does it exist?".format( - ansi['red'], ansi['reset'], dir_source.lower(), ansi['bold'], dir_path, - ansi['reset'])) + out(0, red("Error: ") + "cannot enter {}; does it exist?".format( + dir_long_name)) return if not os.path.isdir(dir_path): if os.path.exists(dir_path): - error_message = "is not a directory" + out(0, red("Error: ") + dir_long_name + " is not a directory!") else: - error_message = "does not exist" - - out(0, "{}Error{}: {} '{}{}{}' {}!".format(ansi['red'], ansi['reset'], - dir_source, ansi['bold'], dir_path, ansi['reset'], - error_message)) + out(0, red("Error: ") + dir_long_name + " does not exist!") return if directory_is_git_repo(dir_path): - out(0, "{} '{}{}{}' is a git repository:".format(dir_source, - ansi['bold'], dir_path, ansi['reset'])) + out(0, dir_long_name.capitalize() + " is a git repository:") update_repository(dir_path, dir_name) else: @@ -141,15 +150,13 @@ def update_directory(dir_path, dir_name, is_bookmark=False): if directory_is_git_repo(repo_path): # filter out non-repositories repositories.append((repo_path, repo_name)) - repo_count = len(repositories) - if repo_count == 1: - pluralize = "repository" + num_of_repos = len(repositories) + if num_of_repos == 1: + out(0, dir_long_name.capitalize() + " contains 1 git repository:") else: - pluralize = "repositories" - - out(0, "{} '{}{}{}' contains {} git {}:".format(dir_source, - ansi['bold'], dir_path, ansi['reset'], repo_count, pluralize)) - + out(0, dir_long_name.capitalize() + + " contains {} git repositories:".format(num_of_repos)) + repositories.sort() # go alphabetically instead of randomly for repo_path, repo_name in repositories: update_repository(repo_path, repo_name) @@ -172,8 +179,8 @@ def update_bookmarks(): for bookmark_path, bookmark_name in bookmarks: update_directory(bookmark_path, bookmark_name, is_bookmark=True) else: - out(0, """You don't have any bookmarks configured! Get help with - 'gitup -h'.""") + out(0, "You don't have any bookmarks configured! Get help with " + + "'gitup -h'.") def load_config_file(): """Read the file storing our config options from config_filename and return @@ -196,7 +203,8 @@ def add_bookmarks(paths): if not config.has_section("bookmarks"): config.add_section("bookmarks") - out(0, "{}Added bookmarks:{}".format(ansi['yellow'], ansi['reset'])) + out(0, yellow("Added bookmarks:")) + for path in paths: path = os.path.abspath(path) # convert relative to absolute path if config.has_option("bookmarks", path): @@ -204,7 +212,7 @@ def add_bookmarks(paths): else: path_name = os.path.split(path)[1] config.set("bookmarks", path, path_name) - out(1, "{}{}{}".format(ansi['bold'], path, ansi['reset'])) + out(1, bold(path)) save_config_file(config) @@ -213,12 +221,12 @@ def delete_bookmarks(paths): config = load_config_file() if config.has_section("bookmarks"): - out(0, "{}Deleted bookmarks:{}".format(ansi['yellow'], ansi['reset'])) + out(0, yellow("Deleted bookmarks:")) for path in paths: path = os.path.abspath(path) # convert relative to absolute path config_was_changed = config.remove_option("bookmarks", path) if config_was_changed: - out(1, "{}{}{}".format(ansi['bold'], path, ansi['reset'])) + out(1, bold(path)) else: out(1, "'{}' is not bookmarked.".format(path)) save_config_file(config) @@ -235,7 +243,7 @@ def list_bookmarks(): bookmarks = [] if bookmarks: - out(0, "{}Current bookmarks:{}".format(ansi['yellow'], ansi['reset'])) + out(0, yellow("Current bookmarks:")) for bookmark_path, bookmark_name in bookmarks: out(1, bookmark_path) else: @@ -277,7 +285,7 @@ def main(): args = parser.parse_args() - print "{}gitup{}: the git-repo-updater".format(ansi['bold'], ansi['reset']) + print bold("gitup") + ": the git-repo-updater" if args.bookmarks_to_add: add_bookmarks(args.bookmarks_to_add)