def write_files(self, command, output_dir, vars): """ Override so as to put the files in '.' """ type_dir = os.path.join(self.module_dir(), "./skel/%s" % vars['type']) assert os.path.isdir(type_dir) # First write generic stuff, then specific # Template.write_files(self, command, ".", vars) self._template_dir = type_dir Template.write_files(self, command, ".", vars)
def check_vars(self, vars, cmd): vars = Template.check_vars(self, vars, cmd) # workaround for a paster issue https://github.com/ckan/ckan/issues/2636 # this is only used from a short-lived paster command try: reload(sys) # Python 2 sys.setdefaultencoding('utf-8') except NameError: pass # Python 3 if not vars['project'].startswith('ckanext-'): print("\nError: Project name must start with 'ckanext-'") sys.exit(1) # The project name without the ckanext-. vars['project_shortname'] = vars['project'][len('ckanext-'):] # Make sure keywords contains "CKAN" (upper-case) once only. keywords = vars['keywords'].strip().split() keywords = [ keyword for keyword in keywords if keyword not in ('ckan', 'CKAN') ] keywords.insert(0, 'CKAN') vars['keywords'] = u' '.join(keywords) # For an extension named ckanext-example we want a plugin class # named ExamplePlugin. vars['plugin_class_name'] = vars['project_shortname'].title( ) + 'Plugin' return vars
def check_vars(self, vars, cmd): vars = Template.check_vars(self, vars, cmd) # workaround for a paster issue https://github.com/ckan/ckan/issues/2636 # this is only used from a short-lived paster command reload(sys) sys.setdefaultencoding('utf-8') if not vars['project'].startswith('ckanext-'): print "\nError: Project name must start with 'ckanext-'" sys.exit(1) # The project name without the ckanext-. vars['project_shortname'] = vars['project'][len('ckanext-'):] # Make sure keywords contains "CKAN" (upper-case) once only. keywords = vars['keywords'].strip().split() keywords = [keyword for keyword in keywords if keyword not in ('ckan', 'CKAN')] keywords.insert(0, 'CKAN') vars['keywords'] = u' '.join(keywords) # For an extension named ckanext-example we want a plugin class # named ExamplePlugin. vars['plugin_class_name'] = vars['project_shortname'].title() + 'Plugin' return vars
def check_vars(self, vars, cmd): vars = Template.check_vars(self, vars, cmd) if not vars['project'].startswith('ckanext-'): print "\nError: Expected the project name to start with 'ckanext-'" sys.exit(1) vars['project'] = vars['project'][len('ckanext-'):] return vars
def pre(self, command, output_dir, vars): vars['random_string'] = os.urandom(20).encode('hex') package_logger = vars['package'] if package_logger == 'root': # Rename the app logger in the rare case a project is named 'root' package_logger = 'app' vars['package_logger'] = package_logger return Template.pre(self, command, output_dir, vars)
def pre(self, command, output_dir, vars): # pragma: no cover vars["random_string"] = os.urandom(20).encode("hex") package_logger = vars["package"] if package_logger == "root": # Rename the app logger in the rare case a project is named 'root' package_logger = "app" vars["package_logger"] = package_logger return Template.pre(self, command, output_dir, vars)
def check_vars(self, user_vars, command): checked_vars = Template.check_vars(self, user_vars, command) msg = 'Context defined by PasteScript(This may be harmful to Jinja2):' keys = sorted(standard_vars) max_len = len(max(keys, key=len)) print(msg) for k in keys: print(' {0}:{1} {2}'.format(k, ' ' * (max_len - len(k)), standard_vars[k])) return checked_vars
def check_vars(self, vars, command): """ Reset the package variable in interactive so that project and package names can be different (GitHub and Python Have different restriction on names). """ if not command.options.no_interactive and \ not hasattr(command, '_deleted_once'): del vars['package'] command._deleted_once = True return Template.check_vars(self, vars, command)
def __init__(self, string, name=None, summary='', interactive=False, vars=None): self.string = string self.cmd = create_distro_command(interactive) # make a temporary directory + file for the string directory = tempfile.mkdtemp() if not name: name = tempfile.mktemp(dir=directory) fd = file(os.path.join(directory, name), 'w') print >> fd, string fd.close() self.name = name # variables for PasteScript's template Template.__init__(self, name) self._template_dir = directory self.summary = summary self.vars = vars or []
def read_vars(self, command=None): vars = Template.read_vars(self, command) infos = {} project = '' if command: project = command.args[0] from paste.script import pluginlib self.module = self.__class__.__module__ def wrap_egg_info_dir(c, n): print "%s" % ( " Monkey patching egg_info_dir " ) return None pluginlib.egg_info_dir = wrap_egg_info_dir return vars
def check_vars(self, vars, cmd): vars = Template.check_vars(self, vars, cmd) PREFIX = 'tethysapp-' PREFIX_NO_DASH = 'tethysapp' if not vars['project'].startswith(PREFIX): print('\nError: Expected the project name to start with "{0}". Please add the "{0}" ' 'as a prefix and try again'.format(PREFIX)) sys.exit(1) # Validate project name project_error_regex = re.compile(r'^[a-zA-Z0-9_]+$') project_warning_regex = re.compile(r'^[a-zA-Z0-9_-]+$') project = vars['project'][len(PREFIX):] # Only letters, numbers and underscores allowed in app names if not project_error_regex.match(project): # If the only offending character is a dash, replace dashes with underscores and notify user if project_warning_regex.match(project): before = project project = project.replace('-', '_') print('\nWarning: Dashes in project name "{0}" have been replaced ' \ 'with underscores "{1}"'.format(before, project)) # Otherwise, throw error else: print('\nError: Invalid characters in project name "{0}". Only letters, numbers, and underscores ' \ '(no dashes) allowed after the "tethysapp-" prefix.'.format(project)) sys.exit(1) vars['project'] = project # Derive the project_url from the project name vars['project_url'] = project.replace('_', '-').lower() # Derive proper_name if not provided by user if not vars['proper_name']: vars['proper_name'] = project.replace('_', ' ').title() # Derive the proper_no_spaces variable (used for the name of the App class) vars['proper_no_spaces'] = ''.join(vars['proper_name'].split()) # Add the color variable to vars vars['color'] = random.choice(self.default_colors) return vars
def check_vars(self, vars, cmd): vars = Template.check_vars(self, vars, cmd) if not vars['project'].startswith('ckanext-'): print "\nError: Project name must start with 'ckanext-'" sys.exit(1) # The project name without the ckanext-. vars['project_shortname'] = vars['project'][len('ckanext-'):] # Make sure keywords contains "CKAN" (upper-case) once only. keywords = vars['keywords'].strip().split() keywords = [keyword for keyword in keywords if keyword not in ('ckan', 'CKAN')] keywords.insert(0, 'CKAN') vars['keywords'] = ' '.join(keywords) # For an extension named ckanext-example we want a plugin class # named ExamplePlugin. vars['plugin_class_name'] = vars['project_shortname'].title() + 'Plugin' return vars
def create_project(self, project, templates, vars=None, database=None, repository=None, return_missing=False): """ * project: path name of project * templates: templates to be applied on project creation * vars: variables for interpolation * database: type of database to use * repository: type of repository to use """ ### set variables dirname = os.path.join(self.directory, project) if os.path.isdir(dirname) and os.listdir(dirname): raise ValueError("Project directory %r already exists, " "cowardly refusing to create anything" % dirname) _vars = vars or {} vars = self.vars.copy() vars.update(_vars) vars['project'] = project permissions = dict([(key, value[:]) for key, value in self.permissions.items()]) wiki = self.wiki[:] ### munge configuration # get templates # XXX hack to get the specified DB out of pastescript templates if not database: if isinstance(templates, ProjectTemplates): pastescript_templates = templates.pastescript_templates else: pastescript_templates = ProjectTemplates( *(templates + self.site_templates)).pastescript_templates databases = set([ template.database() for template in pastescript_templates if template.db is not None ]) if databases: assert len(databases) == 1 database = databases.pop() if not database: database = SQLite() _templates = [] _templates.append(database.config()) if repository: _templates.append(repository.config()) if isinstance(templates, ProjectTemplates): if _templates: templates.append(*_templates) else: templates += _templates templates = self.project_templates(templates) # determine the vars/options optdict = templates.vars(self.options) repo_fields = {} if database: vars2dict(optdict, *database.options) if repository: vars2dict(optdict, *repository.options) repo_fields = self.repository_fields(project).get( repository.name, {}) ### interpolate configuration command = create_distro_command(interactive=self.interactive) # check for missing variables missing = templates.missing(vars) missing.update(set(optdict.keys()).difference(vars.keys())) if return_missing: return missing if missing: # use default repo fields if they are missing for field in repo_fields: if field in missing: vars[field] = repo_fields[field] missing.remove(field) # add missing variables to the optdict for missed in missing: if missed not in optdict: optdict[missed] = var(missed, '') if missing: paste_template = Template(project) paste_template._read_vars = dict2vars(optdict) # XXX bad touch paste_template.check_vars(vars, command) # run the pre method of the pastescript templates # XXX should this be done here? command.interactive = False for paste_template in templates.pastescript_templates: paste_template.pre(command, dirname, vars) ### create the database if database: database.setup(**vars) ### create the trac environment options = templates.options_tuples(vars) options.append(('project', 'name', project)) # XXX needed? if self.inherit: options.append(('inherit', 'file', self.inherit)) env = Environment(dirname, create=True, options=options) ### repository setup if repository: repository.setup(**vars) try: repos = env.get_repository() repos.sync() except TracError: pass ### read the generated configuration _conf_file = os.path.join(dirname, 'conf', 'trac.ini') fp = file(_conf_file) _conf = fp.read() fp.close() ### run pastescript templates for paste_template in templates.pastescript_templates: paste_template.write_files(command, dirname, vars) paste_template.post(command, dirname, vars) # read permissions for agent, perm in paste_template.permissions.items(): permissions.setdefault(agent, []).extend(perm) # read wiki directories wiki_dir = paste_template.wiki_dir() if wiki_dir is not None: wiki.append(wiki_dir) # write back munged configuration munger = ConfigMunger(_conf, options) fp = file(_conf_file, 'w') munger.write(fp) fp.close() # TODO: update the inherited file: # * intertrac # trac-admin upgrade the project env = Environment(dirname) if env.needs_upgrade(): env.upgrade() ### trac-admin operations admin = TracLegosAdmin(dirname) # remove the default items admin.delete_all() # load wiki pages admin.load_pages() # default wiki pages for page_dir in wiki: admin.load_pages(page_dir) # add permissions if permissions: admin.add_permissions(permissions)
def post(self, *arg, **kw): # pragma: no cover print 'Welcome to Pyramid. Sorry for the convenience.' return Template.post(self, *arg, **kw)
def pre(self, command, output_dir, vars): # pragma: no cover vars['random_string'] = os.urandom(20).encode('hex') return Template.pre(self, command, output_dir, vars)
def check_vars(self, vars, cmd): vars = Template.check_vars(self, vars, cmd) PREFIX = 'tethysapp-' PREFIX_NO_DASH = 'tethysapp' if not vars['project'].startswith(PREFIX): print('\nError: Expected the project name to start with "{0}". Please add the "{0}" ' 'as a prefix and try again'.format(PREFIX)) sys.exit(1) # Validate project name project_error_regex = re.compile(r'^[a-zA-Z0-9_]+$') project_warning_regex = re.compile(r'^[a-zA-Z0-9_-]+$') project = vars['project'][len(PREFIX):] # Only letters, numbers and underscores allowed in app names if not project_error_regex.match(project): # If the only offending character is a dash, replace dashes with underscores and notify user if project_warning_regex.match(project): before = project project = project.replace('-', '_') print('\nWarning: Dashes in project name "{0}" have been replaced ' \ 'with underscores "{1}"'.format(before, project)) # Otherwise, throw error else: print('\nError: Invalid characters in project name "{0}". Only letters, numbers, and underscores ' \ '(no dashes) allowed after the "tethysapp-" prefix.'.format(project)) sys.exit(1) vars['project'] = project # Derive the project_url from the project name vars['project_url'] = project.replace('_', '-').lower() # Derive proper_name if not provided by user if not vars['proper_name']: vars['proper_name'] = project.replace('_', ' ').title() else: # Validate and sanitize user input proper_name_error_regex = re.compile(r'^[a-zA-Z0-9\s]+$') proper_name_warn_regex = re.compile(r'^[a-zA-Z0-9-\s_\"\']+$') print vars['proper_name'] if not proper_name_error_regex.match(vars['proper_name']): # If offending characters are dashes, underscores or quotes, replace and notify user if proper_name_warn_regex.match(vars['proper_name']): before = vars['proper_name'] vars['proper_name'] = vars['proper_name'].replace('_', ' ') vars['proper_name'] = vars['proper_name'].replace('-', ' ') vars['proper_name'] = vars['proper_name'].replace('"', '') vars['proper_name'] = vars['proper_name'].replace("'", "") print('\nWarning: Illegal characters were detected in proper name "{0}". They have replaced or ' 'removed with valid characters: "{1}"'.format(before, vars['proper_name'])) # Otherwise, throw error else: print('\nError: Invalid characters in proper name "{0}". Only letters and numbers and spaces' 'allowed.'.format(vars['proper_name'])) sys.exit(1) # Derive the proper_no_spaces variable (used for the name of the App class) split_proper_name = vars['proper_name'].split() title_split_proper_name = [x.title() for x in split_proper_name] vars['proper_no_spaces'] = ''.join(title_split_proper_name) # Add the color variable to vars vars['color'] = random.choice(self.default_colors) return vars
def post(self, command, output_dir, vars): self.out('Welcome to Pyramid. Sorry for the convenience.') return Template.post(self, command, output_dir, vars)
def check_vars(self, vars, command): if not command.options.no_interactive and \ not hasattr(command, '_deleted_once'): del vars['package'] command._deleted_once = True return Template.check_vars(self, vars, command)
def write_files(self, command, output_dir, vars): """ Override so as to put the files in '.' """ Template.write_files(self, command, ".", vars)
def post(self, command, output_dir, vars): deo_trib = ("\n\nPtah has generated your application. Your application " "can be found at /. \n\nDorneles hopes you like it.\n") self.out(deo_trib) return Template.post(self, command, output_dir, vars)
def create_project(self, project, templates, vars=None, database=None, repository=None, return_missing=False): """ * project: path name of project * templates: templates to be applied on project creation * vars: variables for interpolation * database: type of database to use * repository: type of repository to use """ ### set variables dirname = os.path.join(self.directory, project) if os.path.isdir(dirname) and os.listdir(dirname): raise ValueError("Project directory %r already exists, " "cowardly refusing to create anything" % dirname) _vars = vars or {} vars = self.vars.copy() vars.update(_vars) vars['project'] = project permissions = dict([(key, value[:]) for key, value in self.permissions.items()]) wiki = self.wiki[:] ### munge configuration # get templates # XXX hack to get the specified DB out of pastescript templates if not database: if isinstance(templates, ProjectTemplates): pastescript_templates = templates.pastescript_templates else: pastescript_templates = ProjectTemplates(*(templates + self.site_templates)).pastescript_templates databases = set([ template.database() for template in pastescript_templates if template.db is not None]) if databases: assert len(databases) == 1 database = databases.pop() if not database: database = SQLite() _templates = [] _templates.append(database.config()) if repository: _templates.append(repository.config()) if isinstance(templates, ProjectTemplates): if _templates: templates.append(*_templates) else: templates += _templates templates = self.project_templates(templates) # determine the vars/options optdict = templates.vars(self.options) repo_fields = {} if database: vars2dict(optdict, *database.options) if repository: vars2dict(optdict, *repository.options) repo_fields = self.repository_fields(project).get(repository.name, {}) ### interpolate configuration command = create_distro_command(interactive=self.interactive) # check for missing variables missing = templates.missing(vars) missing.update(set(optdict.keys()).difference(vars.keys())) if return_missing: return missing if missing: # use default repo fields if they are missing for field in repo_fields: if field in missing: vars[field] = repo_fields[field] missing.remove(field) # add missing variables to the optdict for missed in missing: if missed not in optdict: optdict[missed] = var(missed, '') if missing: paste_template = Template(project) paste_template._read_vars = dict2vars(optdict) # XXX bad touch paste_template.check_vars(vars, command) # run the pre method of the pastescript templates # XXX should this be done here? command.interactive = False for paste_template in templates.pastescript_templates: paste_template.pre(command, dirname, vars) ### create the database if database: database.setup(**vars) ### create the trac environment options = templates.options_tuples(vars) options.append(('project', 'name', project)) # XXX needed? if self.inherit: options.append(('inherit', 'file', self.inherit)) env = Environment(dirname, create=True, options=options) ### repository setup if repository: repository.setup(**vars) try: repos = env.get_repository() repos.sync() except TracError: pass ### read the generated configuration _conf_file = os.path.join(dirname, 'conf', 'trac.ini') fp = file(_conf_file) _conf = fp.read() fp.close() ### run pastescript templates for paste_template in templates.pastescript_templates: paste_template.write_files(command, dirname, vars) paste_template.post(command, dirname, vars) # read permissions for agent, perm in paste_template.permissions.items(): permissions.setdefault(agent, []).extend(perm) # read wiki directories wiki_dir = paste_template.wiki_dir() if wiki_dir is not None: wiki.append(wiki_dir) # write back munged configuration munger = ConfigMunger(_conf, options) fp = file(_conf_file, 'w') munger.write(fp) fp.close() # TODO: update the inherited file: # * intertrac # trac-admin upgrade the project env = Environment(dirname) if env.needs_upgrade(): env.upgrade() ### trac-admin operations admin = TracLegosAdmin(dirname) # remove the default items admin.delete_all() # load wiki pages admin.load_pages() # default wiki pages for page_dir in wiki: admin.load_pages(page_dir) # add permissions if permissions: admin.add_permissions(permissions)