1 """Quickstart command to generate a new project.
2
3 Quickstart takes the files from turbogears.quickstart and processes them to produce
4 a new, ready-to-run project.
5
6 """
7
8 import optparse
9 import os
10 import re
11 import shutil
12 import stat
13 import sys
14
15 import pkg_resources
16 import turbogears
17
18 from paste.script import templates, create_distro
19
20
21 beginning_letter = re.compile(r"^[^a-z]*")
22 valid_only = re.compile(r"[^a-z0-9_]")
23
24
26 - def run(self, command, output_dirs, vars):
27 vars.setdefault('einame', vars['project'].replace('-', '_'))
28 vars.setdefault('turbogearsversion',
29 pkg_resources.get_distribution('turbogears').version)
30 vars.setdefault('sys_executable', os.path.normpath(sys.executable))
31 super(TGTemplate, self).run(command, output_dirs, vars)
32
33
42
43
51
52
54 required_templates = ["turbogears"]
55 _template_dir = pkg_resources.resource_filename(
56 "turbogears.qstemplates",
57 "quickstartbig")
58 summary = "For more complex projects"
59 use_cheetah = True
60
61 - def post(self, command, output_dir, vars):
62 packagedir = os.path.join(output_dir, vars["package"])
63 controllersdir = os.path.join(packagedir, "controllers")
64 controllersfile = os.path.join(packagedir, "controllers.py")
65 rootfile = os.path.join(controllersdir, "root.py")
66 if os.path.exists(controllersdir) and \
67 os.path.exists(controllersfile):
68 controllerstext = open(controllersfile).read()
69 roottext = open(rootfile).read()
70 from paste.script.copydir import query_interactive
71 thesame = controllerstext == roottext
72 if not thesame:
73 print "\nYou seem to be upgrading from a smaller quickstart."
74 print "There is currently a controllers package and a"
75 print "controllers module, which would get confusing."
76 if not command.simulate and (controllerstext == roottext
77 or query_interactive(controllersfile, rootfile,
78 controllerstext, roottext, False)):
79 shutil.copyfile(controllersfile, rootfile)
80 try:
81 if not os.path.exists(os.path.join(os.path.dirname(
82 os.path.abspath(controllersfile)), '.svn')):
83 raise OSError
84 command.run_command('svn', 'revert', controllersfile)
85 command.run_command('svn', 'delete', controllersfile)
86 except OSError:
87 os.unlink(controllersfile)
88 controllerspyc = controllersfile + "c"
89 if os.path.exists(controllerspyc):
90 os.unlink(controllerspyc)
91
92
99
100
102 dist = pkg_resources.get_distribution("TurboGears")
103 for r in set(dist.requires((name,))) - set(dist.requires()):
104 if r.project_name.lower() == (pkg or name):
105 return r
106 raise ValueError("Did not find matching %s requirement"
107 " in the TurboGears setup.py:extras_require." % name)
108
109
111 "Implementation of quickstart."
112
113 desc = "Create a new TurboGears project"
114
115 name = None
116 package = None
117 templates = "turbogears"
118 svn_repository = None
119 sqlalchemy = False
120 sqlobject = False
121 elixir = False
122 identity = False
123
124 prompt_identity = True
125
127 parser = optparse.OptionParser(
128 usage="%prog quickstart [options] [project name]",
129 version="%prog " + version)
130 parser.add_option("-s", "--sqlalchemy",
131 help="use SQLAlchemy instead of SQLObject",
132 action="store_true", dest="sqlalchemy", default=False)
133 parser.add_option("-e", "--elixir",
134 help="use SQLAlchemy Elixir instead of SQLObject",
135 action="store_true", dest="elixir", default=False)
136 parser.add_option("-o", "--sqlobject",
137 help="use SQLObject instead of SQLAlchemy",
138 action="store_true", dest="sqlobject", default=False)
139 parser.add_option("-i", "--identity",
140 help="provide Identity support",
141 action="store_true", dest="identity", default=False)
142 parser.add_option(
143 "", "--no-identity",
144 help="Don't prompt for Identity support (ignored if -i is on)",
145 action="store_false", dest="prompt_identity", default=True)
146 parser.add_option("-p", "--package",
147 help="package name for the code",
148 dest="package")
149 parser.add_option("-t", "--templates",
150 help="user specific templates",
151 dest="templates", default=self.templates)
152 parser.add_option("-r", "--svn-repository", metavar="REPOS",
153 help="create project in given SVN repository",
154 dest="svn_repository", default=self.svn_repository)
155 parser.add_option("--dry-run",
156 help="dry run (don't actually do anything)",
157 action="store_true", dest="dry_run")
158
159 options, args = parser.parse_args()
160 self.__dict__.update(options.__dict__)
161
162 if not True in [self.elixir, self.sqlalchemy, self.sqlobject]:
163 self.sqlalchemy = True
164
165 if self.elixir:
166 self.sqlalchemy = True
167 self.sqlobject = False
168 elif self.sqlalchemy:
169 self.sqlobject = False
170 if self.sqlobject:
171 self.sqlalchemy = False
172
173 if args:
174 self.name = args[0]
175 self.turbogearsversion = version
176
178 "Quickstarts the new project."
179
180 while not self.name:
181 self.name = raw_input("Enter project name: ")
182
183 while not self.package:
184 package = self.name.lower()
185 package = beginning_letter.sub("", package)
186 package = valid_only.sub("", package)
187 self.package = raw_input("Enter package name [%s]: " % package)
188 if not self.package:
189 self.package = package
190
191 doidentity = self.identity
192 while self.prompt_identity and not doidentity:
193 doidentity = raw_input("Do you need Identity "
194 "(usernames/passwords) in this project? [no] ")
195
196 doidentity = doidentity.lower()
197
198 if not doidentity or doidentity.startswith('n'):
199 self.identity = "none"
200 break
201
202 if doidentity.startswith("y"):
203 doidentity = True
204 break
205
206 print "Please enter y(es) or n(o)."
207 doidentity = None
208
209 if doidentity is True:
210 if self.sqlalchemy or self.elixir:
211 self.identity = "sqlalchemy"
212 else:
213 self.identity = "sqlobject"
214 else:
215 self.identity = "none"
216
217 self.name = pkg_resources.safe_name(self.name)
218
219 env = pkg_resources.Environment()
220 if self.name.lower() in env:
221 print 'The name "%s" is already in use by' % self.name,
222 for dist in env[self.name]:
223 print dist
224 return
225
226 import imp
227 try:
228 if imp.find_module(self.package):
229 print 'The package name "%s" is already in use' % self.package
230 return
231 except ImportError:
232 pass
233
234 if os.path.exists(self.name):
235 print 'A directory called "%s" already exists. Exiting.' % self.name
236 return
237
238 command = create_distro.CreateDistroCommand("quickstart")
239 cmd_args = []
240 for template in self.templates.split(" "):
241 cmd_args.append("--template=%s" % template)
242 if self.svn_repository:
243 cmd_args.append("--svn-repository=%s" % self.svn_repository)
244 if self.dry_run:
245 cmd_args.append("--simulate")
246 cmd_args.append("-q")
247 cmd_args.append(self.name)
248 cmd_args.append("sqlalchemy=%s" % self.sqlalchemy)
249 cmd_args.append("elixir=%s" % self.elixir)
250 cmd_args.append("sqlobject=%s" % self.sqlobject)
251 cmd_args.append("identity=%s" % self.identity)
252 cmd_args.append("package=%s" % self.package)
253
254
255
256 if self.sqlobject:
257 sqlobjectversion = str(get_requirement('sqlobject'))
258 cmd_args.append("sqlobjectversion=%s" % sqlobjectversion)
259 if self.sqlalchemy:
260 sqlalchemyversion = str(get_requirement('sqlalchemy'))
261 cmd_args.append("sqlalchemyversion=%s" % sqlalchemyversion)
262 if self.elixir:
263 elixirversion = str(get_requirement('sqlalchemy', 'elixir'))
264 cmd_args.append("elixirversion=%s" % elixirversion)
265
266 command.run(cmd_args)
267
268 if not self.dry_run:
269 os.chdir(self.name)
270 if self.sqlobject:
271
272
273
274 sodir = '%s/sqlobject-history' % self.package
275 if not os.path.exists(sodir):
276 os.mkdir(sodir)
277 try:
278 if not os.path.exists(os.path.join(os.path.dirname(
279 os.path.abspath(sodir)), '.svn')):
280 raise OSError
281 command.run_command('svn', 'add', sodir)
282 except OSError:
283 pass
284
285 startscript = "start-%s.py" % self.package
286 if os.path.exists(startscript):
287 oldmode = os.stat(startscript).st_mode
288 os.chmod(startscript,
289 oldmode | stat.S_IXUSR)
290 sys.argv = ["setup.py", "egg_info"]
291 import imp
292 imp.load_module("setup", *imp.find_module("setup", ["."]))
293
294
295 for base, path, files in os.walk("./"):
296 for file in files:
297 if file == "empty":
298 os.remove(os.path.join(base, file))
299
300
302 "Implementation of update"
303
304 desc = "Update an existing turbogears project"
305 need_project = True
306
307 name = None
308 templates = "turbogears"
309 identity = False
310 sqlalchemy = True
311 sqlobject = False
312 elixir = True
313
315 self.parser = parser = optparse.OptionParser(usage="%prog update [options]",
316 version="%prog " + version)
317 parser.add_option("-s", "--sqlalchemy",
318 help="use SQLAlchemy instead of SQLObject",
319 action="store_true", dest="sqlalchemy", default=False)
320 parser.add_option("-e", "--elixir",
321 help="use SQLAlchemy Elixir instead of SQLObject",
322 action="store_true", dest="elixir", default=False)
323 parser.add_option("-o", "--sqlobject",
324 help="use SQLObject instead of SQLAlchemy",
325 action="store_true", dest="sqlobject", default=False)
326 parser.add_option("-i", "--identity",
327 help="provide Identity support",
328 action="store_true", dest="identity", default=False)
329 parser.add_option("-t", "--templates", help="user specific templates",
330 dest="templates", default=self.templates)
331
332 self.turbogearsversion = version
333
335 "Updates an existing project"
336 self.name = turbogears.util.get_project_name()
337 self.package = turbogears.util.get_package_name()
338 turbogears.command.base.load_project_config()
339
340 try:
341 project_dist = pkg_resources.get_distribution(self.name)
342 project_requires = [r.project_name.lower()
343 for r in project_dist.requires()]
344 self.parser.set_defaults(
345 sqlobject = 'sqlobject' in project_requires,
346 sqlalchemy = 'sqlalchemy' in project_requires,
347 elixir = 'elixir' in project_requires)
348 except pkg_resources.DistributionNotFound:
349 print "Could not determine requirements for your application."
350 print "Please run 'python setup.py develop' to make your " + \
351 "application known to setuptools."
352
353 options, args = self.parser.parse_args()
354 self.__dict__.update(options.__dict__)
355
356 if not True in [self.elixir, self.sqlalchemy, self.sqlobject]:
357 if turbogears.config.get('sqlobject.dburi'):
358 self.sqlobject = True
359 else:
360 self.sqlalchemy = True
361
362 if self.elixir:
363 self.sqlalchemy = True
364 self.sqlobject = False
365 elif self.sqlalchemy:
366 self.sqlobject = False
367 if self.sqlobject:
368 self.sqlalchemy = False
369
370 if not self.identity:
371 if turbogears.config.get('identity.on'):
372 self.identity = True
373
374 if self.identity:
375 if self.sqlalchemy:
376 self.identity = 'sqlalchemy'
377 else:
378 self.identity = 'sqlobject'
379 else:
380 self.identity = 'none'
381
382 currentdir = os.path.basename(os.getcwd())
383 if not currentdir == self.name:
384 print ('It looks like your project directory "%s" is named '
385 'incorrectly.' % currentdir)
386 print 'Please rename it to "%s".' % self.name
387 return
388
389 command = create_distro.CreateDistroCommand("update")
390 cmd_args = []
391 cmd_args.append("-o../")
392 for template in self.templates.split(" "):
393 cmd_args.append("--template=%s" % template)
394 cmd_args.append(self.name)
395 cmd_args.append("sqlalchemy=%s" % self.sqlalchemy)
396 cmd_args.append("elixir=%s" % self.elixir)
397 cmd_args.append("sqlobject=%s" % self.sqlobject)
398 cmd_args.append("identity=%s" % self.identity)
399 cmd_args.append("package=%s" % self.package)
400
401
402
403 if self.sqlobject:
404 sqlobjectversion = str(get_requirement('sqlobject'))
405 cmd_args.append("sqlobjectversion=%s" % sqlobjectversion)
406
407 if self.sqlalchemy:
408 sqlalchemyversion = str(get_requirement('sqlalchemy'))
409 cmd_args.append("sqlalchemyversion=%s" % sqlalchemyversion)
410
411 if self.elixir:
412 elixirversion = str(get_requirement('sqlalchemy', 'elixir'))
413 cmd_args.append("elixirversion=%s" % elixirversion)
414
415 command.run(cmd_args)
416
417 startscript = "start-%s.py" % self.package
418 if os.path.exists(startscript):
419 oldmode = os.stat(startscript).st_mode
420 os.chmod(startscript,
421 oldmode | stat.S_IXUSR)
422 sys.argv = ["setup.py", "egg_info"]
423 import imp
424 imp.load_module("setup", *imp.find_module("setup", ["."]))
425
426
427 for base, path, files in os.walk("./"):
428 for file in files:
429 if file == "empty":
430 os.remove(os.path.join(base, file))
431