File manipulation code, I've noticed, has two salient properties:
- It's everywhere, and vitally important to functional software
- It has lots of exceptions.
Please give me some pointers on how I can better improve the usability of this rough draft I wrote yesterday. It assumes some very basic things, and was scrapped together after browsing Google as I stumbled through the concepts.
makeproject.py
'''create a simple setup folder for a new project
Follows the guide posted at:
http://guide.python-distribute.org/quickstart.html#lay-out-your-project
The structure built will match the following:
| ProjectName/
|---> LICENSE.txt
| README.txt
| setup.py
| projectname/
| ---> __init__.py
#For the sake of best practices, __init__.py is left empty.
'''
#! usr/bin/env python
import sys, os, errno
class NewProject(object):
'''interface for building a directory with a new project in it'''
def __init__(self, projectname, directory):
self.project = projectname
self.base = check_path(directory)
#project defaults: I don't want them here as class attributes!
self.SETUP = {
'README.txt' :
'''This is an unmodified README text file.
It contains a list of changes to the program.
It also contains help for dealing with the application.
''',
'LISCENSE.txt' :
'''Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
'''
}
def newproject(self):
'''creates a file structure for a new project at `directory`
'''
self.name = self.project.replace(' ', '')
self.path = os.sep.join([self.base, self.name])
sub = self.name.lower()
subpath = os.sep.join([self.path, sub])
check_build_path(subpath)
for filename, content in self.SETUP.items():
self.buildfile(filename, content, directory=self.path)
#setup takes arguments, it has its own method
setup = self.buildsetup()
self.buildfile('setup.py', setup)
self.buildfile('__init__.py', directory=subpath)
def buildfile(self, name, content="", directory = ""):
'''opens and creates a new file at `directory` with `contents`'''
#assumes bad directories have been purified
if directory == "":
loc = os.sep.join([self.path, name])
w = open(loc, 'w')
else:
directory = os.sep.join([directory, name])
w = open(directory, 'w')
w.write(content)
w.close()
def buildsetup(self):
return '''from distutils.core import setup
setup(
name='{0}',
version='0.1dev',
packages=['{1}',],
license=open('LISCENSE.txt').read(),
long_description=open('README.txt').read(),
)
'''.format(self.project, self.name.lower())
def check_path(loc):
'''recursively check if last character in `loc` is like os.sep character.
If so, remove.'''
if loc[-1] == os.sep:
return check_path(loc[:-1])
return loc
def check_build_path(loc):
d = os.path.normpath(loc)
if not os.path.exists(d):
os.makedirs(d)
else:
try:
os.rmdir(d)
except OSError as ex:
if ex.errno == errno.ENOTEMPTY:
print "Directory specified must be new or empty"
sys.exit(1)
#if delete was successful, build the directory
check_build_path(loc)
if __name__ == '__main__':
if len(sys.argv) != 3:
print "Usage: string 'Project Name', string '/abs/path'"
sys.exit(1)
project = NewProject(sys.argv[1], sys.argv[2])
project.newproject()