From 235e790cbd4cdb67e6835117a3ee95275f22e516 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Tue, 7 Jun 2011 18:49:05 -0400 Subject: [PATCH 1/4] adding style(text, effect) function --- gitup.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/gitup.py b/gitup.py index 2386e74..0c6b166 100644 --- a/gitup.py +++ b/gitup.py @@ -20,15 +20,6 @@ __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", -} - def out(indent, msg): """Print a message at a given indentation level.""" width = 4 # amount to indent at each level @@ -39,6 +30,22 @@ def out(indent, msg): msg = re.sub("\s+", " ", msg) # collapse multiple spaces into one print spacing + msg +def style(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 exec_shell(command): """Execute a shell command and get the output.""" command = shlex.split(command) From 1e8695bceea1841fedb75789f4476eb310c40877 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Tue, 7 Jun 2011 19:12:47 -0400 Subject: [PATCH 2/4] converting old formatting to style(), hopefully this makes things neater --- gitup.py | 71 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/gitup.py b/gitup.py index 0c6b166..0065b86 100644 --- a/gitup.py +++ b/gitup.py @@ -64,7 +64,8 @@ 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'])) + bold_name = style(repo_name, "bold") + out(1, "{}:".format(bold_name)) os.chdir(repo_path) # cd into our folder so git commands target the correct # repo @@ -74,34 +75,36 @@ 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'])) + error_msg = style("Error:", "red") + out(2, """{} cannot fetch; do you have a remote repository configured + correctly?""".format(error_msg)) 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)) + nochanges_msg = style("No new changes.", "blue") + out(2, "{} Last commit was {}.".format(nochanges_msg, 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, style("Pulling new changes...", "green")) 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'])) + warning_msg = style("Warning:", "red") + out(2, "{} You have uncommitted changes in this repository!".format( + warning_msg)) out(2, "Ignoring.") def update_directory(dir_path, dir_name, is_bookmark=False): @@ -110,16 +113,18 @@ 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" + + error = style("Error:", "red") + bold_path_name = style(dir_path, "bold") 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, "{} cannot enter {} '{}'; does it exist?".format(error, + dir_type, bold_path_name)) return if not os.path.isdir(dir_path): @@ -128,14 +133,13 @@ def update_directory(dir_path, dir_name, is_bookmark=False): else: error_message = "does not exist" - out(0, "{}Error{}: {} '{}{}{}' {}!".format(ansi['red'], ansi['reset'], - dir_source, ansi['bold'], dir_path, ansi['reset'], + out(0, "{} {} '{}' {}!".format(error, dir_type, bold_path_name, error_message)) 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, "{} '{}' is a git repository:".format(dir_type.capitalize(), + bold_path_name)) update_repository(dir_path, dir_name) else: @@ -148,14 +152,14 @@ 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: + pluralized = "repository" else: - pluralize = "repositories" + pluralized = "repositories" - out(0, "{} '{}{}{}' contains {} git {}:".format(dir_source, - ansi['bold'], dir_path, ansi['reset'], repo_count, pluralize)) + out(0, "{} '{}' contains {} git {}:".format(dir_type.capitalize(), + bold_path_name, num_of_repos, pluralized)) repositories.sort() # go alphabetically instead of randomly for repo_path, repo_name in repositories: @@ -203,7 +207,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, style("Added bookmarks:", "yellow")) + for path in paths: path = os.path.abspath(path) # convert relative to absolute path if config.has_option("bookmarks", path): @@ -211,7 +216,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, style(path, "bold")) save_config_file(config) @@ -220,12 +225,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, style("Deleted bookmarks:", "yellow")) 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, style(path, "bold")) else: out(1, "'{}' is not bookmarked.".format(path)) save_config_file(config) @@ -242,7 +247,7 @@ def list_bookmarks(): bookmarks = [] if bookmarks: - out(0, "{}Current bookmarks:{}".format(ansi['yellow'], ansi['reset'])) + out(0, style("Current bookmarks:", "yellow")) for bookmark_path, bookmark_name in bookmarks: out(1, bookmark_path) else: @@ -284,7 +289,7 @@ def main(): args = parser.parse_args() - print "{}gitup{}: the git-repo-updater".format(ansi['bold'], ansi['reset']) + print "{}: the git-repo-updater".format(style("gitup", "bold")) if args.bookmarks_to_add: add_bookmarks(args.bookmarks_to_add) From 96078165a1a26f3f003ef84622cd45305ecffe6b Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Tue, 7 Jun 2011 19:14:00 -0400 Subject: [PATCH 3/4] whitespace paranoia --- gitup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gitup.py b/gitup.py index 0065b86..b6a296a 100644 --- a/gitup.py +++ b/gitup.py @@ -94,7 +94,6 @@ def update_repository(repo_path, repo_name): status = exec_shell("git status") if status.endswith("nothing to commit (working directory clean)"): - out(2, style("Pulling new changes...", "green")) result = exec_shell("git pull") out(2, "The following changes have been made since {}:".format( From faf962749136cc46d689cb7dd9e740672746f32f Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Tue, 7 Jun 2011 20:13:48 -0400 Subject: [PATCH 4/4] made per-style functions (bold(), red(), blue()...) and (tried to) clean up styling more --- gitup.py | 89 +++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/gitup.py b/gitup.py index b6a296a..4675dd0 100644 --- a/gitup.py +++ b/gitup.py @@ -20,17 +20,14 @@ __email__ = "ben.kurtovic@verizon.net" config_filename = os.path.join(os.path.expanduser("~"), ".gitup") -def out(indent, msg): - """Print a message at a given indentation level.""" - width = 4 # amount to indent at each level - if indent == 0: - spacing = "\n" - else: - spacing = " " * width * indent - msg = re.sub("\s+", " ", msg) # collapse multiple spaces into one - print spacing + msg +# 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, effect): +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", @@ -46,6 +43,16 @@ def style(text, effect): except KeyError: return text +def out(indent, msg): + """Print a message at a given indentation level.""" + width = 4 # amount to indent at each level + if indent == 0: + spacing = "\n" + else: + spacing = " " * width * indent + msg = re.sub("\s+", " ", msg) # collapse multiple spaces into one + print spacing + msg + def exec_shell(command): """Execute a shell command and get the output.""" command = shlex.split(command) @@ -64,8 +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.""" - bold_name = style(repo_name, "bold") - out(1, "{}:".format(bold_name)) + out(1, bold(repo_name) + ":") os.chdir(repo_path) # cd into our folder so git commands target the correct # repo @@ -75,9 +81,8 @@ def update_repository(repo_path, repo_name): # anything to pull, but # don't do it yet except subprocess.CalledProcessError: - error_msg = style("Error:", "red") - out(2, """{} cannot fetch; do you have a remote repository configured - correctly?""".format(error_msg)) + out(2, red("Error: ") + "cannot fetch; do you have a remote " + + "repository configured correctly?") return try: @@ -86,24 +91,23 @@ def update_repository(repo_path, repo_name): last_commit = "never" # couldn't get a log, so no commits if not dry_fetch: # no new changes to pull - nochanges_msg = style("No new changes.", "blue") - out(2, "{} Last commit was {}.".format(nochanges_msg, last_commit)) + 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, style("Pulling new changes...", "green")) + out(2, green("Pulling new changes...")) result = exec_shell("git pull") out(2, "The following changes have been made since {}:".format( last_commit)) print result else: - warning_msg = style("Warning:", "red") - out(2, "{} You have uncommitted changes in this repository!".format( - warning_msg)) + out(2, red("Warning: ") + "you have uncommitted changes in this " + + "repository!") out(2, "Ignoring.") def update_directory(dir_path, dir_name, is_bookmark=False): @@ -116,29 +120,24 @@ def update_directory(dir_path, dir_name, is_bookmark=False): else: dir_type = "directory" - error = style("Error:", "red") - bold_path_name = style(dir_path, "bold") + 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, "{} cannot enter {} '{}'; does it exist?".format(error, - dir_type, bold_path_name)) + 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, "{} {} '{}' {}!".format(error, dir_type, bold_path_name, - 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_type.capitalize(), - bold_path_name)) + out(0, dir_long_name.capitalize() + " is a git repository:") update_repository(dir_path, dir_name) else: @@ -153,13 +152,11 @@ def update_directory(dir_path, dir_name, is_bookmark=False): num_of_repos = len(repositories) if num_of_repos == 1: - pluralized = "repository" + out(0, dir_long_name.capitalize() + " contains 1 git repository:") else: - pluralized = "repositories" - - out(0, "{} '{}' contains {} git {}:".format(dir_type.capitalize(), - bold_path_name, num_of_repos, pluralized)) - + 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) @@ -182,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 @@ -206,7 +203,7 @@ def add_bookmarks(paths): if not config.has_section("bookmarks"): config.add_section("bookmarks") - out(0, style("Added bookmarks:", "yellow")) + out(0, yellow("Added bookmarks:")) for path in paths: path = os.path.abspath(path) # convert relative to absolute path @@ -215,7 +212,7 @@ def add_bookmarks(paths): else: path_name = os.path.split(path)[1] config.set("bookmarks", path, path_name) - out(1, style(path, "bold")) + out(1, bold(path)) save_config_file(config) @@ -224,12 +221,12 @@ def delete_bookmarks(paths): config = load_config_file() if config.has_section("bookmarks"): - out(0, style("Deleted bookmarks:", "yellow")) + 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, style(path, "bold")) + out(1, bold(path)) else: out(1, "'{}' is not bookmarked.".format(path)) save_config_file(config) @@ -246,7 +243,7 @@ def list_bookmarks(): bookmarks = [] if bookmarks: - out(0, style("Current bookmarks:", "yellow")) + out(0, yellow("Current bookmarks:")) for bookmark_path, bookmark_name in bookmarks: out(1, bookmark_path) else: @@ -288,7 +285,7 @@ def main(): args = parser.parse_args() - print "{}: the git-repo-updater".format(style("gitup", "bold")) + print bold("gitup") + ": the git-repo-updater" if args.bookmarks_to_add: add_bookmarks(args.bookmarks_to_add)