From cbc243b375bddf1739476f7e9d44867a0441b2b2 Mon Sep 17 00:00:00 2001 From: Vlada Macek Date: Mon, 8 Nov 2010 14:35:50 +0100 Subject: [PATCH 1/3] Minor changes to README and setup.py. --- README | 25 +++++++++++++------------ setup.py | 10 +--------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/README b/README index f8a170d..7581fee 100644 --- a/README +++ b/README @@ -1,22 +1,23 @@ -============ -StartProject -============ +=================== +django-startproject +=================== -StartProject installs a script which allows the easy creation of a standard -Django project layout based on Lincoln Loop standards. +django-startproject installs a script which allows the easy creation +of a standard Django project layout based on Lincoln Loop standards. Script usage ============ -After installing StartProject, simply run the following command (from within -the directory in where the new project directory should be created):: +After installing django-startproject, simply run the following command +(from within the directory in where the new project directory should +be created):: django-startproject.py project_name -The script will prompt for values to replace boilerplate variables with. These -variables allow for both the file contents and path names to be customized to -this specific project. +The script will prompt for values to replace boilerplate variables with. +These variables allow for both the file contents and path names +to be customized to this specific project. Using a custom project template @@ -44,5 +45,5 @@ determine the boilerplate variables: whitespace. If the default value contains ``PROJECT``, it is replaced with the project name. -See the files included in the project_template directory of StartProject for -an example. +See the files included in the django_startproject/project_template directory +for an example. diff --git a/setup.py b/setup.py index 04c1936..1627375 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,6 @@ from setuptools import setup import os - -README_FILE = open('README') -try: - LONG_DESCRIPTION = README_FILE.read() -finally: - README_FILE.close() - ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) DATA_DIR = os.path.join(ROOT_DIR, 'django_startproject', 'project_template') STARTPROJECT_DATA = [] @@ -21,14 +14,13 @@ # Get files starting with '.' too (they are excluded from the *.* glob). STARTPROJECT_DATA.append(os.path.join('project_template', path, '.*')) - setup(name='django-startproject', version='1.0a', author='Lincoln Loop', author_email='info@lincolnloop.com', description=('Create a Django project layout based on Lincoln Loop ' 'best practices.'), - long_description=LONG_DESCRIPTION, + long_description=open('README').read(), packages=['django_startproject'], package_data={'django_startproject': STARTPROJECT_DATA}, scripts=['bin/django-startproject.py'], From 2ea444cf451e9b0bf29785ba6e5f00cce570c1ff Mon Sep 17 00:00:00 2001 From: Vlada Macek Date: Mon, 8 Nov 2010 15:55:12 +0100 Subject: [PATCH 2/3] Made creating from project template more flexible: Made project name default really working and derived from the path. Added default overriding with values from ~/.django_startproject_defaults. Creating dirs recursively in case of nesting. Added informative printout on finish. Updated README. --- README | 15 ++++++++-- django_startproject/management.py | 15 +++------- .../.startproject_boilerplate | 4 +-- .../project_template/.startproject_defaults | 2 +- django_startproject/utils.py | 29 ++++++++++++------- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/README b/README index 7581fee..acaf416 100644 --- a/README +++ b/README @@ -15,6 +15,14 @@ be created):: django-startproject.py project_name +Alternatively from the repo root and without installation:: + + PYTHONPATH=. bin/django-startproject.py path/to/new/project_name + +The argument is the path, where the new project tree should be generated. +The path must be exist and its parent must be writable. Last segment of the +path will be considered as the project name. Should be identifier-safe. + The script will prompt for values to replace boilerplate variables with. These variables allow for both the file contents and path names to be customized to this specific project. @@ -42,8 +50,11 @@ determine the boilerplate variables: ``.startproject_defaults`` Each line should contain a variable and the default value, separated by - whitespace. If the default value contains ``PROJECT``, it is replaced with - the project name. + whitespace. If the value contains ``PROJECT_NAME``, it is replaced with + the project name (last segment of the path given on the command line). + To override some of these template defaults with your local machine + defaults, create file named ``.django_startproject_defaults`` in your + home directory. See the files included in the django_startproject/project_template directory for an example. diff --git a/django_startproject/management.py b/django_startproject/management.py index 3cfb0aa..57139a9 100644 --- a/django_startproject/management.py +++ b/django_startproject/management.py @@ -3,17 +3,14 @@ import os import sys - TEMPLATE_DIR = os.path.join(os.path.dirname(os.path.realpath(utils.__file__)), 'project_template') - def start_project(): """ Copy a project template, replacing boilerplate variables. - """ - usage = "usage: %prog [options] project_name [base_destination_dir]" + usage = "usage: %prog [options] path/to/new/project_name" parser = optparse.OptionParser(usage=usage) parser.add_option('-t', '--template-dir', dest='src_dir', help='project template directory to use', @@ -22,14 +19,10 @@ def start_project(): if len(args) not in (1, 2): parser.print_help() sys.exit(1) - project_name = args[0] + target_dir = args[0] + project_name = os.path.split(target_dir)[1] src = options.src_dir - if len(args) > 1: - base_dest_dir = args[1] - else: - base_dest_dir = '' - dest = os.path.join(base_dest_dir, project_name) # Get any boilerplate replacement variables: replace = {} @@ -44,4 +37,4 @@ def start_project(): value = raw_input(prompt) or default replace[var] = value - utils.copy_template(src, dest, replace) + utils.copy_template(src, target_dir, replace) diff --git a/django_startproject/project_template/.startproject_boilerplate b/django_startproject/project_template/.startproject_boilerplate index c273132..345d869 100644 --- a/django_startproject/project_template/.startproject_boilerplate +++ b/django_startproject/project_template/.startproject_boilerplate @@ -1,4 +1,4 @@ -myproject Project name +myproject Project name (identifier-safe, lowercase recommended) myauthor Project author mydevhost Development server -myrepohost Repository location \ No newline at end of file +myrepohost Repository location diff --git a/django_startproject/project_template/.startproject_defaults b/django_startproject/project_template/.startproject_defaults index 8a9823c..353db2a 100644 --- a/django_startproject/project_template/.startproject_defaults +++ b/django_startproject/project_template/.startproject_defaults @@ -1,4 +1,4 @@ -myproject PROJECT +myproject PROJECT_NAME myauthor Lincoln Loop mydevhost dev.lincolnloop.com myrepohost cambridge.lincolnloop.com diff --git a/django_startproject/utils.py b/django_startproject/utils.py index 2181d60..576f3c4 100644 --- a/django_startproject/utils.py +++ b/django_startproject/utils.py @@ -16,12 +16,13 @@ def copy_template(src, dest, replace=None): replacements, so directories and file names may also be modified. """ + fcnt = 0 for path, dirs, files in os.walk(src): relative_path = path[len(src):].lstrip('/') # Replace boilerplate strings in destination directory. for old_val, new_val in replace.items(): relative_path = relative_path.replace(old_val, new_val) - os.mkdir(os.path.join(dest, relative_path)) + os.makedirs(os.path.join(dest, relative_path)) for i, subdir in enumerate(dirs): if subdir.startswith('.'): del dirs[i] @@ -35,6 +36,9 @@ def copy_template(src, dest, replace=None): filename = filename.replace(old_val, new_val) dest_file_path = os.path.join(dest, relative_path, filename) copy_template_file(src_file_path, dest_file_path, replace) + fcnt += 1 + + print "\nSuccessfully created %d files under %s" % (fcnt, dest) def copy_template_file(src, dest, replace=None): @@ -79,19 +83,22 @@ def get_boilerplate(path, project_name): """ defaults = {} - defaults_path = os.path.join(path, '.startproject_defaults') - if os.path.isfile(defaults_path): - defaults_file = open(defaults_path, 'r') - for line in defaults_file: - match = re.match(r'\s*(\w+)\s*(.*)$', line) - if match: - var, default = match.groups() - defaults[var] = default + defaults_paths = (os.path.join(path, '.startproject_defaults'), + os.path.join(os.getenv('HOME'), '.django_startproject_defaults')) + for defaults_path in defaults_paths: + if os.path.isfile(defaults_path): + for line in open(defaults_path): + match = re.match(r'\s*(\w+)\s*(.*)$', line) + if match: + var, default = match.groups() + if default == 'PROJECT_NAME': + default = project_name + defaults[var] = default + boilerplate = [] boilerplate_path = os.path.join(path, '.startproject_boilerplate') if os.path.isfile(boilerplate_path): - boilerplate_file = open(boilerplate_path, 'r') - for line in boilerplate_file: + for line in open(boilerplate_path): match = re.match(r'\s*(\w+)\s*(.*)$', line) if match: var, description = match.groups() From b7de7d5d2c213f6f78a2fa454b99630dbc8eeb9d Mon Sep 17 00:00:00 2001 From: Vlada Macek Date: Mon, 8 Nov 2010 17:05:40 +0100 Subject: [PATCH 3/3] Added -g option for auto git repo init, commit and origin. myrepohost variable changed to full myrepoloc. Changed the magic tag to $PROJECT_NAME (added dollar). The magic tag can now be in the middle of other text. Small code fixes. Updated README. .startproject_* files can contain #-comments now. Skipping *~ files when copying the template. --- README | 10 ++++++++- django_startproject/management.py | 22 +++++++++++++++++-- .../.startproject_boilerplate | 2 +- .../project_template/.startproject_defaults | 7 ++++-- .../project_template/docs/install.rst | 2 +- django_startproject/utils.py | 17 ++++++++------ 6 files changed, 46 insertions(+), 14 deletions(-) diff --git a/README b/README index acaf416..1885a97 100644 --- a/README +++ b/README @@ -38,6 +38,14 @@ command script like this:: django-startproject.py --template-dir=/your/custom/template project_name +Automatic local git repository creation +======================================= + +In case ``-g`` option is given, a git repo is initialized in the just created +project directory. Then all files are added, initial commit is done and +the repo is bound to the origin from the myrepoloc boilerplate variable. + + Specifying boilerplate variables -------------------------------- @@ -50,7 +58,7 @@ determine the boilerplate variables: ``.startproject_defaults`` Each line should contain a variable and the default value, separated by - whitespace. If the value contains ``PROJECT_NAME``, it is replaced with + whitespace. If the value contains ``$PROJECT_NAME``, it is replaced with the project name (last segment of the path given on the command line). To override some of these template defaults with your local machine defaults, create file named ``.django_startproject_defaults`` in your diff --git a/django_startproject/management.py b/django_startproject/management.py index 57139a9..5032716 100644 --- a/django_startproject/management.py +++ b/django_startproject/management.py @@ -15,12 +15,14 @@ def start_project(): parser.add_option('-t', '--template-dir', dest='src_dir', help='project template directory to use', default=TEMPLATE_DIR) + parser.add_option('-g', '--initial-git', action='store_true', + help='create git repo with a first commit when the new project is generated') options, args = parser.parse_args() if len(args) not in (1, 2): parser.print_help() sys.exit(1) target_dir = args[0] - project_name = os.path.split(target_dir)[1] + project_name = os.path.split(target_dir)[1].strip() src = options.src_dir @@ -35,6 +37,22 @@ def start_project(): value = None while not value: value = raw_input(prompt) or default - replace[var] = value + replace[var] = value.strip() utils.copy_template(src, target_dir, replace) + + if options.initial_git: + os.system(''' + echo + cd %s >/dev/null && + git init && + git add . && + git commit -q -m "Initial commit of project as created by django-startproject." && + echo "The initial project state has been committed under git." + ''' % target_dir) + + os.system(''' + cd %s >/dev/null && + git remote add origin %s && + echo "Local repo origin set to %s" + ''' % (target_dir, replace['myrepoloc'], replace['myrepoloc'])) diff --git a/django_startproject/project_template/.startproject_boilerplate b/django_startproject/project_template/.startproject_boilerplate index 345d869..ee288da 100644 --- a/django_startproject/project_template/.startproject_boilerplate +++ b/django_startproject/project_template/.startproject_boilerplate @@ -1,4 +1,4 @@ myproject Project name (identifier-safe, lowercase recommended) myauthor Project author mydevhost Development server -myrepohost Repository location +myrepoloc Repository location (e.g. git+ssh://git@host/$PROJECT_NAME#egg=$PROJECT_NAME) diff --git a/django_startproject/project_template/.startproject_defaults b/django_startproject/project_template/.startproject_defaults index 353db2a..07b517b 100644 --- a/django_startproject/project_template/.startproject_defaults +++ b/django_startproject/project_template/.startproject_defaults @@ -1,4 +1,7 @@ -myproject PROJECT_NAME +# +# "$PROJECT_NAME" will get replaced by the guessed project name from cmdline. +# +myproject $PROJECT_NAME myauthor Lincoln Loop mydevhost dev.lincolnloop.com -myrepohost cambridge.lincolnloop.com +myrepoloc git+ssh://git@cambridge.lincolnloop.com/$PROJECT_NAME.git#egg=$PROJECT_NAME diff --git a/django_startproject/project_template/docs/install.rst b/django_startproject/project_template/docs/install.rst index 3055dd9..781db5a 100644 --- a/django_startproject/project_template/docs/install.rst +++ b/django_startproject/project_template/docs/install.rst @@ -41,7 +41,7 @@ If you have the project source checked out already, place it in a ``myproject`` directory inside the virtual environment source (``src``) directory. Otherwise, checkout the source now:: - pip install -e git+ssh://git@myrepohost/myproject.git#egg=myproject + pip install -e myrepoloc Next, install the requirements and the project source:: diff --git a/django_startproject/utils.py b/django_startproject/utils.py index 576f3c4..6da694b 100644 --- a/django_startproject/utils.py +++ b/django_startproject/utils.py @@ -28,7 +28,8 @@ def copy_template(src, dest, replace=None): del dirs[i] for filename in files: if (filename.startswith('.startproject') or - filename.endswith('.pyc')): + filename.endswith('.pyc') or + filename.endswith('~')): continue src_file_path = os.path.join(path, filename) # Replace boilerplate strings in destination filename. @@ -88,20 +89,22 @@ def get_boilerplate(path, project_name): for defaults_path in defaults_paths: if os.path.isfile(defaults_path): for line in open(defaults_path): - match = re.match(r'\s*(\w+)\s*(.*)$', line) - if match: + line = line.lstrip() + match = re.match(r'(\w+)\s*(.*)$', line) + if match and not line.startswith('#'): var, default = match.groups() - if default == 'PROJECT_NAME': - default = project_name + default = default.replace('$PROJECT_NAME', project_name) defaults[var] = default boilerplate = [] boilerplate_path = os.path.join(path, '.startproject_boilerplate') if os.path.isfile(boilerplate_path): for line in open(boilerplate_path): - match = re.match(r'\s*(\w+)\s*(.*)$', line) - if match: + line = line.lstrip() + match = re.match(r'(\w+)\s*(.*)$', line) + if match and not line.startswith('#'): var, description = match.groups() default = defaults.get(var) boilerplate.append((var, description, default)) + return boilerplate