Skip to content

Commit

Permalink
👍 Merge branch 'devel' ; Version bump to 1.7.0!
Browse files Browse the repository at this point in the history
* Improved CLI API ;
* Made repo slug optional for commands that don't need it ;
* Added auto configuration command.

* fixes issue #9:  Make requests for merges not needing repo slug
* fixes issue #17: Refactoring of main function
* fixes issue #21: Add auto-configuration command

Signed-off-by: Guyzmo <guyzmo+github@m0g.net>
  • Loading branch information
guyzmo committed Jun 21, 2016
2 parents b4f3727 + 44e13ac commit 0b4a9fc
Show file tree
Hide file tree
Showing 22 changed files with 1,979 additions and 276 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ README.rst
*.egg
.cache/
.coverage
contrib
docs
.gitignore
53 changes: 36 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
* https://gitlab.com/guyzmo/git-repo
* https://bitbucket.org/guyzmo/git-repo
* Issues: https://github.com/guyzmo/git-repo/issues
* [![Show Travis Build Status](https://travis-ci.org/guyzmo/git-repo.svg)](https://travis-ci.org/guyzmo/git-repo)
* [![Issues in Ready](https://badge.waffle.io/guyzmo/git-repo.png?label=ready&title=Ready)](https://waffle.io/guyzmo/git-repo) [![Issues in Progress](https://badge.waffle.io/guyzmo/git-repo.png?label=in%20progress&title=Progress)](https://waffle.io/guyzmo/git-repo) [![Show Travis Build Status](https://travis-ci.org/guyzmo/git-repo.svg)](https://travis-ci.org/guyzmo/git-repo)
* [![Pypi Version](https://img.shields.io/pypi/v/git-repo.svg) ![Pypi Downloads](https://img.shields.io/pypi/dm/git-repo.svg)](https://pypi.python.org/pypi/git-repo)

### Usage

### main commands

Control your remote git hosting services from the `git` commandline. The usage is
very simple. To clone a new project, out of github, just issue:

Expand Down Expand Up @@ -48,6 +50,13 @@ and of course, you can delete it using:

% git bb delete guyzmo/git-repo

Also, you can open the repository's page, using the `open` command:

% git lab open guyzmo/git-repo
Successfully fetched branch `2` of `guyzmo/git-repo` into `request-2`!

### Requests for merges *(aka Pull Requests aka Merge Requests)*

Once you're all set with your repository, you can check requests to merge
(aka Pull Requests on github) using the `request` command:

Expand All @@ -60,10 +69,11 @@ And fetch it locally to check and/or amend it before merging:

% git hub request guyzmo/git-repo fetch 2

Finally, you can open the repository's page, using the `open` command:
Or you can create a pull-request by doing a:

% git lab open guyzmo/git-repo
Successfully fetched branch `2` of `guyzmo/git-repo` into `request-2`!
% git hub request create guyzmo/git-repo myfeature master 'My neat feature' -m 'So much to say about that feature…'

### Gists or snippets

Finally, another extra feature you can play with is the gist handling:

Expand Down Expand Up @@ -119,8 +129,17 @@ or by getting the sources and running:

### Configuration

To configure `git-repo` you need to tweak your `~/.gitconfig`. For each service
you've got an account on, you have to make a section in the gitconfig:
To configure `git-repo` you simply have to call the following command:

% git repo config

and a wizard will run you through getting the authentication token for the
service, add the command alias or the name of the remote. Though, configuring
custom services is still not handled by the wizard…

But if you prefer manual configuration you'll have to tweak your
`~/.gitconfig`. For each service you've got an account on, you have to make a
section in the gitconfig:

[gitrepo "gitlab"]
token = YourVerySecretKey
Expand Down Expand Up @@ -218,21 +237,21 @@ To use your own credentials, you can setup the following environment variables:
* [x] refactor the code into multiple modules
* [x] add regression tests (and actually find a smart way to implement them…)
* [x] add travis build
* [x] show a nice progress bar, while it's fetching (cf [#15](https://github.com/guyzmo/git-repo/issues/15))
* [ ] add support for handling gists
* [x] github support
* [ ] gitlab support
* [ ] bitbucket support
* [ ] gitlab support (cf [#12](https://github.com/guyzmo/git-repo/issues/12))
* [ ] bitbucket support (cf [#13](https://github.com/guyzmo/git-repo/issues/13))
* [ ] add support for handling pull requests
* [x] list them
* [x] fetch them as local branches
* [x] github support
* [ ] gitlab support
* [ ] bitbucket support
* [ ] add OAuth support for bitbucket
* [ ] show a nice progress bar, while it's fetching
* partly implemented: the issue looks like that gitpython expects output from git
on stderr, whereas it's outputing on stdout.
* [ ] do what's needed to make a nice documentation (if possible in markdown !@#$)
* [ ] gitlab support (cf [#10](https://github.com/guyzmo/git-repo/issues/10))
* [ ] bitbucket support (cf [#11](https://github.com/guyzmo/git-repo/issues/11))
* [ ] add OAuth support for bitbucket (cf [#14](https://github.com/guyzmo/git-repo/issues/14))
* [ ] add support for managing SSH keys (cf [#22](https://github.com/guyzmo/git-repo/issues/15))
* [ ] add support for issues?
* [ ] add support for gogs (cf [#18](https://github.com/guyzmo/git-repo/issues/18))
* [ ] add support for gerrit (cf [#19](https://github.com/guyzmo/git-repo/issues/19))
* [ ] do what's needed to make a nice documentation — if possible in markdown !@#$
* for more features, write an issue or, even better, a PR!

### License
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.7.0
28 changes: 14 additions & 14 deletions buildout.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@ develop = .
eggs-directory = ${buildout:directory}/var/eggs
develop-eggs-directory = ${buildout:directory}/var/develop-eggs
parts-directory = ${buildout:directory}/var/parts
develop-dir = ${buildout:directory}/var/clone/
extensions=gp.vcsdevelop
vcs-extend-develop=git+https://github.com/gitpython-developers/GitPython#egg=GitPython
# develop-dir = ${buildout:directory}/var/clone/
# extensions=gp.vcsdevelop
# vcs-extend-develop=git+https://github.com/gitpython-developers/GitPython#egg=GitPython

[git_repo]
recipe = zc.recipe.egg
eggs =
${git_repo-pip:eggs}
git_repo
interpreter = python3

[pytest]
recipe = zc.recipe.egg
arguments = ['--cov=git_repo', '--cov-report', 'term-missing', '--capture=sys', 'tests']+sys.argv[1:]
eggs = pytest
pytest-cov
pytest-xdist
pytest-sugar
pytest-catchlog
pytest-datadir-ng
testfixtures
mock
betamax==0.5.1
betamax-serializers
git_repo
eggs = ${pytest-pip:eggs}
interpreter = python3

[git_repo-pip]
recipe = collective.recipe.pip
configs = ${buildout:directory}/requirements.txt

[pytest-pip]
recipe = collective.recipe.pip
configs = ${buildout:directory}/requirements-test.txt


97 changes: 97 additions & 0 deletions git_repo/kwargparse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env python

import logging
log = logging.getLogger('git_repo.kwargparse')

class KeywordArgumentParser:
'''
Argument parser tailored for use with docopt:
Will parse all arguments returned by docopt, and will store them as instance
attributes. Then it will launch actions based on the keyword argument list.
* Parameter arguments (starting with -- or within <>) will automagically be
parsed, dashes will be converted to underscores and stored as attributes of
the parser instance.
* Though if a parameter is matching a method decorated with "store_parameter",
it won't be automagically setup, but will use that method instead.
Then the keywords used as arguments of the program will be used to call an
"action" method, which have been decorated with "register_action".
'''
_action_dict = dict()
_parameter_dict = dict()

def __init__(self, args):
'''
Stores the docopt args as class member
'''
self.args = args

def init(self):
'''
method to be defined for anything that needs to be done before launching
the parser.
'''
pass

def run(self):
'''
This method iterates over the docopt's arguments and matches them against
the parameters list. All leftover values are used to resolve the action to
run, and it will run the action, or run the fallback() method if no action
is found.
'''
self.init()

args = []
missed = []

# go through setters
for arg, value in self.args.items():
if arg in self._parameter_dict:
self._parameter_dict[arg](self, value)
#log.debug('calling setter: {} → {}'.format(arg, value))
elif arg.startswith('--') or arg.startswith('<'):
arg_renamed = arg.lstrip('-<').rstrip('>').replace('-', '_')
if not hasattr(self, arg_renamed):
setattr(self, arg_renamed, value)
#log.debug('auto-setting: self.{} → {}'.format(arg_renamed, value))
else:
#log.debug('keeping: {} → {}'.format(arg, value))
if self.args[arg]:
args.append(arg)

if frozenset(args) in self._action_dict:
#log.debug('running action: {}'.format(self._action_dict[frozenset(args)]))
return self._action_dict[frozenset(args)](self)
else:
return self.fallback()

def fallback(self):
log.error('Unknown action.')
log.error('Please consult help page (--help).')
return 1



def store_parameter(parameter):
'''
Decorator for a parameter, use the full length parameter name as specified in the
docopt configuration, like '--verbose'
'''
def decorator(fun):
KeywordArgumentParser._parameter_dict[parameter] = fun
return fun
return decorator

def register_action(*args, **kwarg):
'''
Decorator for an action, the arguments order is not relevant, but it's best
to use the same order as in the docopt for clarity.
'''
def decorator(fun):
KeywordArgumentParser._action_dict[frozenset(args)] = fun
return fun
return decorator
Loading

0 comments on commit 0b4a9fc

Please sign in to comment.