|
|
@@ -6,12 +6,13 @@ |
|
|
|
from __future__ import print_function |
|
|
|
|
|
|
|
import os |
|
|
|
import shlex |
|
|
|
|
|
|
|
from colorama import Fore, Style |
|
|
|
from git import RemoteReference as RemoteRef, Repo, exc |
|
|
|
from git.util import RemoteProgress |
|
|
|
|
|
|
|
__all__ = ["update_bookmarks", "update_directories"] |
|
|
|
__all__ = ["update_bookmarks", "update_directories", "run_command"] |
|
|
|
|
|
|
|
BOLD = Style.BRIGHT |
|
|
|
BLUE = Fore.BLUE + BOLD |
|
|
@@ -176,8 +177,23 @@ def _update_repository(repo, current_only, fetch_only, prune): |
|
|
|
for branch in sorted(repo.heads, key=lambda b: b.name): |
|
|
|
_update_branch(repo, branch, branch == active) |
|
|
|
|
|
|
|
def _update_subdirectories(path, update_args): |
|
|
|
"""Update all subdirectories that are git repos in a given directory.""" |
|
|
|
def _run_command(repo, command): |
|
|
|
"""Run an arbitrary shell command on the given repository.""" |
|
|
|
print(INDENT1, BOLD + os.path.split(repo.working_dir)[1] + ":") |
|
|
|
|
|
|
|
cmd = shlex.split(command) |
|
|
|
try: |
|
|
|
out = repo.git.execute( |
|
|
|
cmd, with_extended_output=True, with_exceptions=False) |
|
|
|
except exc.GitCommandNotFound as err: |
|
|
|
print(INDENT2, ERROR, err) |
|
|
|
return |
|
|
|
|
|
|
|
for line in out[1].splitlines() + out[2].splitlines(): |
|
|
|
print(INDENT2, line) |
|
|
|
|
|
|
|
def _dispatch_to_subdirs(path, callback, *args): |
|
|
|
"""Apply the callback to all git repo subdirectories in the directory.""" |
|
|
|
repos = [] |
|
|
|
for item in os.listdir(path): |
|
|
|
try: |
|
|
@@ -189,15 +205,17 @@ def _update_subdirectories(path, update_args): |
|
|
|
suffix = "" if len(repos) == 1 else "s" |
|
|
|
print(BOLD + path, "({0} repo{1}):".format(len(repos), suffix)) |
|
|
|
for repo in sorted(repos, key=lambda r: os.path.split(r.working_dir)[1]): |
|
|
|
_update_repository(repo, *update_args) |
|
|
|
callback(repo, *args) |
|
|
|
|
|
|
|
def _update_directory(path, update_args): |
|
|
|
"""Update a particular directory. |
|
|
|
def _dispatch(path, callback, *args): |
|
|
|
"""Apply a callback function on each valid repo in the given path. |
|
|
|
|
|
|
|
Determine whether the directory is a git repo on its own, a directory of |
|
|
|
git repositories, or something invalid. If the first, update the single |
|
|
|
repository; if the second, update all repositories contained within; if the |
|
|
|
third, print an error. |
|
|
|
git repositories, or something invalid. If the first, apply the callback on |
|
|
|
it; if the second, apply the callback on all repositories contained within; |
|
|
|
if the third, print an error. |
|
|
|
|
|
|
|
The given args are passed directly to the callback function after the repo. |
|
|
|
""" |
|
|
|
try: |
|
|
|
repo = Repo(path) |
|
|
@@ -205,18 +223,18 @@ def _update_directory(path, update_args): |
|
|
|
print(ERROR, BOLD + path, "doesn't exist!") |
|
|
|
except exc.InvalidGitRepositoryError: |
|
|
|
if os.path.isdir(path): |
|
|
|
_update_subdirectories(path, update_args) |
|
|
|
_dispatch_to_subdirs(path, callback, *args) |
|
|
|
else: |
|
|
|
print(ERROR, BOLD + path, "isn't a repository!") |
|
|
|
else: |
|
|
|
print(BOLD + repo.working_dir, "(1 repo):") |
|
|
|
_update_repository(repo, *update_args) |
|
|
|
callback(repo, *args) |
|
|
|
|
|
|
|
def update_bookmarks(bookmarks, update_args): |
|
|
|
"""Loop through and update all bookmarks.""" |
|
|
|
if bookmarks: |
|
|
|
for path in bookmarks: |
|
|
|
_update_directory(path, update_args) |
|
|
|
_dispatch(path, _update_repository, *update_args) |
|
|
|
else: |
|
|
|
print("You don't have any bookmarks configured! Get help with 'gitup -h'.") |
|
|
|
|
|
|
@@ -224,4 +242,10 @@ def update_directories(paths, update_args): |
|
|
|
"""Update a list of directories supplied by command arguments.""" |
|
|
|
for path in paths: |
|
|
|
full_path = os.path.abspath(path) |
|
|
|
_update_directory(full_path, update_args) |
|
|
|
_dispatch(full_path, _update_repository, *update_args) |
|
|
|
|
|
|
|
def run_command(paths, command): |
|
|
|
"""Run an arbitrary shell command on all repos.""" |
|
|
|
for path in paths: |
|
|
|
full_path = os.path.abspath(path) |
|
|
|
_dispatch(full_path, _run_command, command) |