Skip to content
This repository was archived by the owner on Mar 12, 2021. It is now read-only.
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
50 changes: 35 additions & 15 deletions README
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
============
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.
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.


Using a custom project template
Expand All @@ -29,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
--------------------------------

Expand All @@ -41,8 +58,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.

See the files included in the project_template directory of StartProject for
an example.
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.
35 changes: 23 additions & 12 deletions django_startproject/management.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,28 @@
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',
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)
project_name = args[0]
target_dir = args[0]
project_name = os.path.split(target_dir)[1].strip()

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 = {}
Expand All @@ -42,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)

utils.copy_template(src, dest, replace)
os.system('''
cd %s >/dev/null &&
git remote add origin %s &&
echo "Local repo origin set to %s"
''' % (target_dir, replace['myrepoloc'], replace['myrepoloc']))
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
myproject Project name
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)
7 changes: 5 additions & 2 deletions django_startproject/project_template/.startproject_defaults
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
myproject PROJECT
#
# "$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
2 changes: 1 addition & 1 deletion django_startproject/project_template/docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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::

Expand Down
38 changes: 24 additions & 14 deletions django_startproject/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,30 @@ 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]
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.
for old_val, new_val in replace.items():
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):
Expand Down Expand Up @@ -79,22 +84,27 @@ 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):
line = line.lstrip()
match = re.match(r'(\w+)\s*(.*)$', line)
if match and not line.startswith('#'):
var, default = match.groups()
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):
boilerplate_file = open(boilerplate_path, 'r')
for line in boilerplate_file:
match = re.match(r'\s*(\w+)\s*(.*)$', line)
if match:
for line in open(boilerplate_path):
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
10 changes: 1 addition & 9 deletions setup.py
Original file line number Diff line number Diff line change
@@ -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 = []
Expand All @@ -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'],
Expand Down