Skip to content

Commit

Permalink
Merge de1cd76 into cf1fb09
Browse files Browse the repository at this point in the history
  • Loading branch information
pokoli committed Aug 27, 2013
2 parents cf1fb09 + de1cd76 commit 2452700
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 16 deletions.
14 changes: 9 additions & 5 deletions cookiecutter/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@
from .find import find_template
from .prompt import prompt_for_config
from .generate import generate_context, generate_files
from .vcs import git_clone
from .vcs import git_clone, hg_clone


logger = logging.getLogger(__name__)

def cookiecutter(input_dir):
"""
API equivalent to using Cookiecutter at the command line.
:param input_dir: A directory containing a project template dir,
:param input_dir: A directory containing a project template dir,
or a URL to git repo.
"""

Expand All @@ -38,6 +38,10 @@ def cookiecutter(input_dir):
got_repo_arg = True
repo_dir = git_clone(input_dir)
project_template = find_template(repo_dir)
elif input_dir.endswith('.hg'):
got_repo_arg = True
repo_dir = hg_clone(input_dir)
project_template = find_template(repo_dir)
else:
got_repo_arg = False
project_template = find_template(input_dir)
Expand Down Expand Up @@ -78,15 +82,15 @@ def parse_cookiecutter_args(args):
help='Cookiecutter project dir, e.g. cookiecutter-pypackage/'
)
return parser.parse_args(args)

def main():
""" Entry point for the package, as defined in setup.py. """

# Log info and above to console
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)

args = parse_cookiecutter_args(sys.argv[1:])

cookiecutter(args.input_dir)

if __name__ == '__main__':
Expand Down
38 changes: 31 additions & 7 deletions cookiecutter/vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,50 @@
from .prompt import query_yes_no


def delete_repo(repo_dir):
ok_to_delete = query_yes_no("You've cloned {0} before. "
"Is it okay to delete and re-clone it?".format(repo_dir))
if ok_to_delete:
shutil.rmtree(repo_dir)
else:
sys.exit()


def git_clone(repo):
"""
Clone a git repo to the current directory.
:param repo: Git repo URL ending with .git.
"""


# Return repo dir
tail = os.path.split(repo)[1]
repo_dir = tail.rsplit('.git')[0]
logging.debug('repo_dir is {0}'.format(repo_dir))

if os.path.isdir(repo_dir):
ok_to_delete = query_yes_no("You've cloned {0} before. Is it okay to delete and re-clone it?".format(repo_dir))
if ok_to_delete:
shutil.rmtree(repo_dir)
else:
sys.exit()
delete_repo(repo_dir)

os.system('git clone {0}'.format(repo))

return repo_dir


def hg_clone(repo):
"""
Clone a mercurial repo to the current directory.
:param repo: repo URL ending with .hg.
"""

# Return repo dir
tail = os.path.split(repo)[1]
repo_dir = tail.rsplit('.hg')[0]
logging.debug('repo_dir is {0}'.format(repo_dir))

if os.path.isdir(repo_dir):
delete_repo(repo_dir)

os.system('hg clone {0}'.format(repo[0:-3]))

return repo_dir
23 changes: 19 additions & 4 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
input_str = '__builtin__.raw_input'
from cStringIO import StringIO


# Log debug and above to console
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)

Expand All @@ -51,14 +51,14 @@ def test_cookiecutter_no_slash(self):
self.assertTrue(os.path.isdir('tests/fake-repo-pre/fake-project'))
self.assertTrue(os.path.isfile('tests/fake-repo-pre/fake-project/README.rst'))
self.assertFalse(os.path.exists('tests/fake-repo-pre/fake-project/json/'))

def tearDown(self):
if os.path.isdir('tests/fake-repo-pre/fake-project'):
shutil.rmtree('tests/fake-repo-pre/fake-project')


class TestArgParsing(unittest.TestCase):

def test_parse_cookiecutter_args(self):
args = main.parse_cookiecutter_args(['project/'])
self.assertEqual(args.input_dir, 'project/')
Expand All @@ -76,12 +76,27 @@ def test_cookiecutter_git(self):
self.assertTrue(os.path.isdir('boilerplate'))
self.assertTrue(os.path.isfile('boilerplate/README.rst'))
self.assertTrue(os.path.exists('boilerplate/setup.py'))


@patch(input_str, lambda x: '')
def test_cookiecutter_mercurial(self):
if not PY3:
sys.stdin = StringIO('\n\n\n\n\n\n\n\n\n')
main.cookiecutter('https://bitbucket.org/pokoli/cookiecutter-trytonmodule.hg')
logging.debug('Current dir is {0}'.format(os.getcwd()))
self.assertFalse(os.path.exists('cookiecutter-trytonmodule'))
self.assertTrue(os.path.isdir('module_name'))
self.assertTrue(os.path.isfile('module_name/README'))
self.assertTrue(os.path.exists('module_name/setup.py'))

def tearDown(self):
if os.path.isdir('cookiecutter-pypackage'):
shutil.rmtree('cookiecutter-pypackage')
if os.path.isdir('cookiecutter-trytonmodule'):
shutil.rmtree('cookiecutter-trytonmodule')
if os.path.isdir('boilerplate'):
shutil.rmtree('boilerplate')
if os.path.isdir('module_name'):
shutil.rmtree('module_name')

if __name__ == '__main__':
unittest.main()
34 changes: 34 additions & 0 deletions tests/test_vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,25 @@ def test_git_clone(self):
if os.path.isdir('cookiecutter-pypackage'):
shutil.rmtree('cookiecutter-pypackage')

def test_hg_clone(self):
repo_dir = vcs.hg_clone(
'https://bitbucket.org/pokoli/cookiecutter-trytonmodule.hg'
)
self.assertEqual(repo_dir, 'cookiecutter-trytonmodule')
self.assertTrue(os.path.isfile('cookiecutter-trytonmodule/README.rst'))
if os.path.isdir('cookiecutter-trytonmodule'):
shutil.rmtree('cookiecutter-trytonmodule')


class TestVCSPrompt(unittest.TestCase):

def setUp(self):
if os.path.isdir('cookiecutter-pypackage'):
shutil.rmtree('cookiecutter-pypackage')
os.mkdir('cookiecutter-pypackage/')
if os.path.isdir('cookiecutter-trytonmodule'):
shutil.rmtree('cookiecutter-trytonmodule')
os.mkdir('cookiecutter-trytonmodule/')

@patch(input_str, lambda: 'y')
def test_git_clone_overwrite(self):
Expand All @@ -70,9 +82,31 @@ def test_git_clone_cancel(self):
'https://github.com/audreyr/cookiecutter-pypackage.git'
)

@patch(input_str, lambda: 'y')
def test_hg_clone_overwrite(self):
if not PY3:
sys.stdin = StringIO('y\n\n')
repo_dir = vcs.hg_clone(
'https://bitbucket.org/pokoli/cookiecutter-trytonmodule.hg'
)
self.assertEqual(repo_dir, 'cookiecutter-trytonmodule')
self.assertTrue(os.path.isfile('cookiecutter-trytonmodule/README.rst'))

@patch(input_str, lambda: 'n')
def test_hg_clone_cancel(self):
if not PY3:
sys.stdin = StringIO('n\n\n')
self.assertRaises(
SystemExit,
vcs.hg_clone,
'https://bitbucket.org/pokoli/cookiecutter-trytonmodule.hg'
)

def tearDown(self):
if os.path.isdir('cookiecutter-pypackage'):
shutil.rmtree('cookiecutter-pypackage')
if os.path.isdir('cookiecutter-trytonmodule'):
shutil.rmtree('cookiecutter-trytonmodule')


if __name__ == '__main__':
Expand Down

0 comments on commit 2452700

Please sign in to comment.