Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 72 additions & 5 deletions bin/ghar
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ __version__= '1'
import sys
import os
import re
import pipes
import datetime
from urlparse import urlparse
import subprocess
from stat import *
Expand Down Expand Up @@ -155,16 +157,42 @@ class Repo:
return (True, ret)
return (False, ret)

def pull(self):
def pull(self, args):
cmd = 'git pull'
return self._git_cmd(cmd)

def clean(self):
def push(self, args):
cmd = 'git push'
return self._git_cmd(cmd)

def commit(self, args):
if self.is_clean():
return (True, "nothing to commit (working directory clean)")
message = ''
if args.auto:
now = datetime.datetime.now()
message = "Changes up to %s" % now.strftime("%Y-$m-%d %H:%I")
elif args.message:
message = args.message
cmd = 'git add -A . && git commit -m ' + pipes.quote(message)
return self._git_cmd(cmd)

def cap(self, args):
failure1, ret1 = self.commit(args)
if failure1:
return (failure1, ret1)
else:
return self.push(args)

def clean(self, args):
cmd = 'git status -s 2> /dev/null'
ok, ret = self._git_cmd(cmd)
if len(ret) > 0: return (False, "dirty")
if len(ret) > 0: return (False, "dirty", ret)
return (True, "clean")

def is_clean(self):
return self.clean(None)[0]

# This function processes all the links in a directory from the repository,
# depending on whether the corresponding directory already exists in $HOME.
# If the directory _doesn't_ already exist, simply symlink it.
Expand All @@ -181,7 +209,7 @@ class Repo:
new_path = os.path.join(path, fname)
dir_links += self.list_directory_links(new_path)
elif link_status.startswith("link to "):
print "We can't yet handle non-ghar symlinks."
print fname,"- we can't yet non-ghar symlinks."
else:
dir_links.append(Link(os.path.join(path, fname), base=self.path))
return dir_links
Expand Down Expand Up @@ -231,8 +259,12 @@ def _git_subcommand(args, action):

for r in pull_repos:
try:
status, string = getattr(r, action)()
resp = getattr(r, action)(args)
status, string = resp[:2]
extra = resp[2:]
print "%s: %s" % (str(r), string)
if extra:
print extra[0]
except NoGitException as e:
print "%s is not a git repo" % str(r)
return 0
Expand All @@ -244,6 +276,41 @@ def pull(args):
_git_subcommand(args, "pull")
argp_pull.set_defaults(func=pull)

argp_push = argp_sub.add_parser('push', help='push all or a few repos')
argp_push.add_argument('repos', metavar='repos', nargs='*',
help='repos to push [defaults to pushing all repos]')
def push(args):
_git_subcommand(args, "push")
argp_push.set_defaults(func=push)

argp_commit = argp_sub.add_parser('commit', help='commit all or a few repos')
argp_commit.add_argument('repos', metavar='repos', nargs='*',
help='repos to commit [defaults to committing all repos]')
argp_commit.add_argument('-m','--message', metavar='message',
help='commit message [defaults to opening an editor]')
argp_commit.add_argument('-a','--auto', action="store_true", default=False,
help='automatically generate commit message from current date+time [defaults to False]')
def commit(args):
if not args.message and not args.auto:
print "error: must give a commit message; use -m/--message or -a/--auto"
return
_git_subcommand(args, "commit")
argp_commit.set_defaults(func=commit)

argp_cap = argp_sub.add_parser('cap', help='commit and push all or a few repos')
argp_cap.add_argument('repos', metavar='repos', nargs='*',
help='repos to cap [defaults to committing and pushing all repos]')
argp_cap.add_argument('-m','--message', metavar='message',
help='commit message [defaults to opening an editor]')
argp_cap.add_argument('-a','--auto', action="store_true", default=False,
help='automatically generate commit message from current date+time [defaults to False]')
def cap(args):
if not args.message and not args.auto:
print "error: must give a commit message; use -m/--message or -a/--auto"
return
_git_subcommand(args, "cap")
argp_cap.set_defaults(func=cap)

argp_status = argp_sub.add_parser('status', help='clean/dirty status of repos')
argp_status.add_argument('repos', metavar='repos', nargs='*',
help='repos to check [defaults to checking all repos]')
Expand Down
8 changes: 4 additions & 4 deletions ghar-bash-completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Expand All @@ -25,14 +25,14 @@ function _ghar {
top="${COMP_WORDS[1]}"

if [ $COMP_CWORD -eq 1 ]; then
opts="status pull list add install uninstall"
opts="status pull list add install uninstall commit push cap"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi

case "$top" in

status|pull|install|uninstall) # one or more repos
status|pull|install|uninstall|commit|push|cap) # one or more repos

# only present --status right after top level install command
if [ "$top" = "install" -a $COMP_CWORD -eq 2 ]; then
Expand Down