def delete(self, prop, value_regex=None, section=None, all=None): if self.scm == 'git': if all: args = ['--unset-all', prop] if value_regex: args.append(value_regex) elif section: args = ['--remove-section', prop] else: args = ['--unset', prop] if value_regex: args.append(value_regex) run_command(['git', 'config'] + args) self._config_cache.clear()
def set(self, prop, value): if self.scm == 'git': _, error = run_command(['git', 'config', prop, value], retcode=True) if error: raise IOError("Couldn't set: git config %s %s" % (prop, value)) self._config_cache[prop] = value
def root(self): if not self._root: if self.scm == 'git': self._root = abspath( run_command(['git', 'rev-parse', '--show-cdup']).strip() ) return self._root
def init_build_recipes(): if RECIPES_INITIALISED: return # Try getting a lock to avoid concurrent builds. lock(BUILD_LOCK) mkdir(RECEIPTS) for recipe in BUILD_RECIPES: execfile(recipe, BUILTINS) for package in list(RECIPES): recipes = RECIPES[package] versions = [] data = {} for recipe in recipes: recipe_type = recipe.get('type') if recipe_type == 'git': path = join(ROOT, recipe['path']) version = run_command( ['git', 'rev-parse', 'HEAD'], cwd=path, exit_on_error=True ).strip() elif 'depends' in recipe: contents = {} latest = 0 for pattern in recipe['depends']: for file in glob(pattern): dep_file = open(file, 'rb') contents[file] = dep_file.read() dep_file.close() dep_mtime = stat(file)[ST_MTIME] if dep_mtime > latest: latest = dep_mtime generate = 0 for pattern in recipe['outputs']: files = glob(pattern) if not files: generate = 1 break for file in files: if not isfile(file): generate = 1 break if stat(file)[ST_MTIME] <= latest: generate = 1 break if generate: break if generate: for file in listdir(RECEIPTS): if file.startswith(package + '-'): remove(join(RECEIPTS, file)) version = sha1(''.join([ '%s\x00%s' % (f, contents[f]) for f in sorted(contents) ])).hexdigest() else: version = recipe['version'] versions.append(version) data[version] = recipe RECIPES[package] = data PACKAGES[package] = versions RECIPES_INITIALISED.append(1)
def get_git_info(filename): """Extract info from the Git repository.""" environ['TZ'] = 'UTC' git_info = run_command(['git', 'log', '--pretty=raw', '--', filename]) info = {'__git__': False} if (not git_info) or git_info.startswith('fatal:'): info['__updated__'] = datetime.utcfromtimestamp( stat(filename).st_mtime ) return info info['__git__'] = True for line in git_info.splitlines(): if line.startswith('author'): email, timestamp, tz = line.split()[-3:] email = email.lstrip('<').rstrip('>') if '(' in email: email = email.split('(')[0].strip() info['__by__'] = email info['__updated__'] = datetime.utcfromtimestamp(float(timestamp)) break return info
def set(self, prop, value): if self.scm == 'git': _, error = run_command( ['git', 'config', prop, value], retcode=True ) if error: raise IOError("Couldn't set: git config %s %s" % (prop, value)) self._config_cache[prop] = value
def do(*cmd, **kwargs): if 'redirect_stdout' not in kwargs: kwargs['redirect_stdout'] = False if 'redirect_stderr' not in kwargs: kwargs['redirect_stderr'] = False if 'exit_on_error' not in kwargs: kwargs['exit_on_error'] = True return run_command(cmd, **kwargs)
def do(args, **kwargs): kwargs["exit_on_error"] = 0 kwargs["retcode"] = 1 kwargs['redirect_stdout'] = 1 kwargs['redirect_stderr'] = 0 ret, retcode = run_command(args, **kwargs) if retcode: raise AppExit() return ret
def is_mercurial(): """Return whether the current directory is inside a Mercurial repo.""" try: _, error = run_command(["hg", "root"], retcode=True) except CommandNotFound: return if not error: return True
def get(self, prop, default=None): if prop in self._config_cache: return self._config_cache[prop] if self.scm == 'git': value, error = run_command(['git', 'config', prop], retcode=True) if error: value = default else: value = value.strip() return self._config_cache.setdefault(prop, value)
def is_git(): """Return whether the current directory is inside a Git repo.""" try: _, error = run_command(["git", "rev-parse", "--is-inside-work-tree"], retcode=True) except CommandNotFound: return if not error: return True
def do_with_stderr(args, **kwargs): kwargs["exit_on_error"] = 0 kwargs["retcode"] = 1 kwargs["reterror"] = 1 kwargs['redirect_stdout'] = 1 kwargs['redirect_stderr'] = 1 ret, err, retcode = run_command(args, **kwargs) if retcode: if err.strip(): print err.strip() raise AppExit() return ret
def is_git(): """Return whether the current directory is inside a Git repo.""" try: _, error = run_command( ["git", "rev-parse", "--is-inside-work-tree"], retcode=True ) except CommandNotFound: return if not error: return True
def do(args, **kwargs): kwargs["exit_on_error"] = 0 kwargs["retcode"] = 1 kwargs["reterror"] = 1 kwargs['redirect_stdout'] = 1 kwargs['redirect_stderr'] = 1 ret, reterr, retcode = run_command(args, **kwargs) if retcode: cmd = ' '.join(args) if reterr: reterr = '\n\t'.join(reterr.strip().split('\n')) exit("Error running: %s\n\n\t%s\n" % (cmd, reterr)) raise AppExit("Error running: %s" % cmd) return ret
def main(argv=None): argv = argv or sys.argv[1:] op = OptionParser(usage=( "Usage: assetgen [<path/to/assetgen.yaml> ...] [options]\n\n" "Note:\n" " If you don't specify assetgen.yaml file paths, then `git\n" " ls-files *assetgen.yaml` will be used to detect all config\n" " files in the current repository. So you need to be inside\n" " a git repository's working tree." )) op.add_option( '-v', '--version', action='store_true', help="show program's version number and exit" ) op.add_option( '--clean', action='store_true', help="remove all generated files" ) op.add_option( '--debug', action='store_true', help="set debug mode" ) op.add_option( '--extension', action='append', dest='path', help="specify a python extension file (may be repeated)" ) op.add_option( '--force', action='store_true', help="force rebuild of all files" ) op.add_option( '--profile', dest='name', default='default', help="specify a profile to use" ) op.add_option( '--watch', action='store_true', help="keep running assetgen on a loop" ) autocomplete(op) options, files = op.parse_args(argv) if options.version: print 'assetgen 0.1' sys.exit() if options.debug: global DEBUG DEBUG = True clean = options.clean extensions = options.path force = options.force profile = options.name watch = options.watch if extensions: scope = globals() for ext in extensions: execfile(ext, scope, {}) if files: for file in files: if not isfile(file): exit("Could not find %s" % file) if not files: if not is_git(): op.print_help() sys.exit() root = SCMConfig().root files = run_command( ['git', 'ls-files', '*assetgen.yaml'], cwd=root ).strip().splitlines() if not files: op.print_help() sys.exit() files = [join(root, file) for file in files] files = [realpath(file) for file in files] if watch: mtime_cache = {} for file in files: mtime_cache[file] = stat(file)[ST_MTIME] generators = [AssetGenRunner(file, profile, force) for file in files] if clean: for assetgen in generators: assetgen.clean() sys.exit() if watch: while 1: try: for assetgen in generators: assetgen.run() for idx, file in enumerate(files): mtime = stat(file)[ST_MTIME] if mtime > mtime_cache[file]: mtime_cache[file] = mtime generators[idx] = AssetGenRunner(file, profile, force) sleep(1) except AppExit: sleep(3) except KeyboardInterrupt: break else: try: for assetgen in generators: assetgen.run() except AppExit: sys.exit(1)
def stderr(*args, **kwargs): kwargs['reterror'] = 1 return run_command(args, **kwargs)[1]
def do(args, **kwargs): kwargs['exit_on_error'] = 1 kwargs['retcode'] = 0 kwargs['redirect_stdout'] = 1 kwargs['redirect_stderr'] = 0 return run_command(args, **kwargs)
def main(argv=None): argv = argv or sys.argv[1:] op = OptionParser(usage=( "Usage: assetgen [<path/to/assetgen.yaml> ...] [options]\n\n" "Note:\n" " If you don't specify assetgen.yaml file paths, then `git\n" " ls-files *assetgen.yaml` will be used to detect all config\n" " files in the current repository. So you need to be inside\n" " a git repository's working tree.\n\n" " And if you specify a URL as a `source`, then it will be\n" " downloaded to ~/.assetgen -- you can override this by\n" " setting the env variable $ASSETGEN_DOWNLOADS" )) op.add_option( '-v', '--version', action='store_true', help="show program's version number and exit" ) op.add_option( '--clean', action='store_true', help="remove all generated files" ) op.add_option( '--debug', action='store_true', help="set debug mode" ) op.add_option( '--extension', action='append', dest='path', help="specify a python extension file (may be repeated)" ) op.add_option( '--force', action='store_true', help="force rebuild of all files" ) op.add_option( '--nuke', action='store_true', help="remove all generated and downloaded files" ) op.add_option( '--profile', dest='name', default='default', help="specify a profile to use" ) op.add_option( '--watch', action='store_true', help="keep running assetgen on a loop" ) autocomplete(op) options, files = op.parse_args(argv) if options.version: print 'assetgen %s' % __release__ sys.exit() if options.debug: global DEBUG DEBUG = True clean = options.clean extensions = options.path force = options.force nuke = options.nuke profile = options.name watch = options.watch if extensions: scope = globals() for ext in extensions: execfile(ext, scope, {}) if files: for file in files: if not isfile(file): exit("Could not find %s" % file) if not files: if not is_git(): op.print_help() sys.exit() root = SCMConfig().root files = run_command( ['git', 'ls-files', '*assetgen.yaml'], cwd=root ).strip().splitlines() if not files: op.print_help() sys.exit() files = [join(root, file) for file in files] files = [realpath(file) for file in files] if watch: change_checker = FileChangeDetector() for file in files: change_checker.mark_clean(file) generators = [AssetGenRunner(file, profile, force, nuke) for file in files] if nuke: if isdir(DOWNLOADS_PATH): log.info("Removing: %s" % DOWNLOADS_PATH) rmtree(DOWNLOADS_PATH) clean = 1 if clean: for assetgen in generators: assetgen.clean() sys.exit() if watch: while 1: try: for assetgen in generators: assetgen.run() for idx, file in enumerate(files): if change_checker.is_changed(file): generators[idx] = AssetGenRunner(file, profile, force) change_checker.mark_clean(file) sleep(1) except AppExit: sleep(3) except KeyboardInterrupt: break else: try: for assetgen in generators: assetgen.run() except AppExit: sys.exit(1)
def main(argv=None): argv = argv or sys.argv[1:] op = OptionParser(usage=( "Usage: assetgen [<path/to/assetgen.yaml> ...] [options]\n\n" "Note:\n" " If you don't specify assetgen.yaml file paths, then `git\n" " ls-files *assetgen.yaml` will be used to detect all config\n" " files in the current repository. So you need to be inside\n" " a git repository's working tree.\n\n" " And if you specify a URL as a `source`, then it will be\n" " downloaded to ~/.assetgen -- you can override this by\n" " setting the env variable $ASSETGEN_DOWNLOADS_DIRECTORY")) op.add_option('-v', '--version', action='store_true', help="show program's version number and exit") op.add_option('--clean', action='store_true', help="remove all generated files") op.add_option('--debug', action='store_true', help="set debug mode") op.add_option('--extension', action='append', dest='path', help="specify a python extension file (may be repeated)") op.add_option('--force', action='store_true', help="force rebuild of all files") op.add_option('--nuke', action='store_true', help="remove all generated and downloaded files") op.add_option('--profile', dest='name', default='default', help="specify a profile to use") op.add_option('--watch', action='store_true', help="keep running assetgen on a loop") autocomplete(op) options, files = op.parse_args(argv) if options.version: print 'assetgen 0.2.2' sys.exit() if options.debug: global DEBUG DEBUG = True clean = options.clean extensions = options.path force = options.force nuke = options.nuke profile = options.name watch = options.watch if extensions: scope = globals() for ext in extensions: execfile(ext, scope, {}) if files: for file in files: if not isfile(file): exit("Could not find %s" % file) if not files: if not is_git(): op.print_help() sys.exit() root = SCMConfig().root files = run_command(['git', 'ls-files', '*assetgen.yaml'], cwd=root).strip().splitlines() if not files: op.print_help() sys.exit() files = [join(root, file) for file in files] files = [realpath(file) for file in files] if watch: mtime_cache = {} for file in files: mtime_cache[file] = stat(file)[ST_MTIME] generators = [AssetGenRunner(file, profile, force) for file in files] if nuke: if isdir(DOWNLOADS_PATH): print "=> Removing:", DOWNLOADS_PATH rmtree(DOWNLOADS_PATH) clean = 1 if clean: for assetgen in generators: assetgen.clean() sys.exit() if watch: while 1: try: for assetgen in generators: assetgen.run() for idx, file in enumerate(files): mtime = stat(file)[ST_MTIME] if mtime > mtime_cache[file]: mtime_cache[file] = mtime generators[idx] = AssetGenRunner(file, profile, force) sleep(1) except AppExit: sleep(3) except KeyboardInterrupt: break else: try: for assetgen in generators: assetgen.run() except AppExit: sys.exit(1)
def main(argv=None, show_help=False): argv = argv or sys.argv[1:] # Set the script name to ``redpill`` so that OptionParser error messages # don't display a potentially confusing ``redpill.py`` to end users. sys.argv[0] = 'redpill' major_listing = '\n'.join( " %-10s %s" % (cmd, MAJOR_COMMANDS[cmd].__doc__) for cmd in sorted(MAJOR_COMMANDS) ) mini_listing = '\n'.join( " %-10s %s" % (cmd, MINI_COMMANDS[cmd].__doc__) for cmd in sorted(MINI_COMMANDS) ) usage = ("""%s\nUsage: redpill <command> [options] \nCommands: \n%s\n\n%s \nSee `redpill help <command>` for more info on a specific command.""" % (__doc__, major_listing, mini_listing)) autocomplete( OptionParser(add_help_option=False), ListCompleter(AUTOCOMPLETE_COMMANDS.keys()), subcommands=AUTOCOMPLETE_COMMANDS ) if not argv: show_help = True else: command = argv[0] argv = argv[1:] if command in ['help', '-h', '--help']: if argv: command = argv[0] argv = ['--help'] if command in MINI_COMMANDS: help = MINI_COMMANDS[command].__doc__ print "Usage: redpill %s\n\n %s\n" % (command, help) sys.exit() else: show_help = True elif command in ['-v', '--version']: version() sys.exit() elif command in MINI_COMMANDS: MINI_COMMANDS[command]() sys.exit() if show_help: print usage sys.exit() if command in MAJOR_COMMANDS: return MAJOR_COMMANDS[command](argv) # We support git-command like behaviour. That is, if there's an external # binary named ``redpill-foo`` available on the ``$PATH``, then running ``redpill # foo`` will automatically delegate to it. try: output, retcode = run_command( ['redpill-%s' % command] + argv, retcode=True, redirect_stdout=False, redirect_stderr=False ) except CommandNotFound: exit("ERROR: Unknown command %r" % command) if retcode: sys.exit(retcode)
def main(argv=None): argv = argv or sys.argv[1:] op = OptionParser( usage="Usage: %prog [options] [path/to/source/directory]" ) op.add_option('-d', dest='data_file', default='.articlestore', help="Set the path for a data file (default: .articlestore)") op.add_option('-o', dest='output_directory', default='website', help="Set the output directory for files (default: website)") op.add_option('-p', dest='package', default='', help="Generate documentation for a Python package (optional)") op.add_option('--clean', dest='clean', default=False, action='store_true', help="Flag to remove all generated output files") op.add_option('--force', dest='force', default=False, action='store_true', help="Flag to force regeneration of all files") op.add_option('--quiet', dest='quiet', default=False, action='store_true', help="Flag to suppress output") try: options, args = op.parse_args(argv) except SystemExit: return # Normalise various options and load from the config file. if args: source_directory = args[0] source_directory_specified = True else: source_directory = getcwd() source_directory_specified = False source_directory = abspath(source_directory) chdir(source_directory) if not isdir(source_directory): raise IOError("%r is not a directory!" % source_directory) config_file = join_path(source_directory, 'yatiblog.conf') if isfile(config_file): config_file_obj = open(config_file, 'rb') config_data = config_file_obj.read() config_file_obj.close() config = load_yaml(config_data) elif not source_directory_specified: raise IOError("Couldn't find: %s" % config_file) else: config = {} index_pages = config.pop('index_pages', []) if not isinstance(index_pages, list): raise ValueError("The 'index_pages' config value is not a list!") index_pages = dict( (index_page.keys()[0], index_page.values()[0]) for index_page in index_pages ) output_directory = join_path(source_directory, options.output_directory.rstrip('/')) if not isdir(output_directory): if not exists(output_directory): mkdir(output_directory) else: raise IOError("%r is not a directory!" % output_directory) code_pages = config.pop('code_pages', {}) if code_pages: code_layout = code_pages['layout'] code_paths = code_pages['paths'] code_files = {} git_root = realpath(SCMConfig().root) for output_filename, input_pattern in code_paths.items(): ignore_pattern = None if isinstance(input_pattern, dict): definition = input_pattern input_pattern = definition['pattern'] if 'ignore' in definition: ignore_pattern = definition['ignore'] files = run_command(['git', 'ls-files', input_pattern], cwd=git_root) files = filter(None, files.splitlines()) if ignore_pattern is not None: ignore_files = run_command( ['git', 'ls-files', ignore_pattern], cwd=git_root ) for file in ignore_files.splitlines(): if file in files: files.remove(file) if '%' in output_filename: output_pattern = True else: output_pattern = False for file in files: directory = basename(dirname(file)) filename, ext = splitext(basename(file)) if output_pattern: dest = output_filename % { 'dir':directory, 'filename':filename, 'ext':ext } else: dest = output_filename code_files[ join_path(output_directory, dest + '.html') ] = [file, join_path(git_root, file)] else: code_files = {} code_layout = None verbose = not options.quiet # See if there's a persistent data file to read from. data_file = join_path(source_directory, options.data_file) if isfile(data_file): data_file_obj = open(data_file, 'rb') data_dict = load_pickle(data_file_obj) data_file_obj.close() else: data_dict = {} # Persist the data file to disk. def persist_data_file(): if data_file: data_file_obj = open(data_file, 'wb') dump_pickle(data_dict, data_file_obj) data_file_obj.close() atexit.register(persist_data_file) # Figure out what the generated files would be. source_files = [ file for file in listfiles(source_directory) if file.endswith('.txt') ] generated_files = [ join_path(output_directory, splitext(file)[0] + '.html') for file in source_files ] index_files = [join_path(output_directory, index) for index in index_pages] # Handle --clean support. if options.clean: for file in generated_files + index_files + [data_file] + code_files.keys(): if isfile(file): if verbose: print "Removing: %s" % file rm(file) data_dict.clear() sys.exit() # Figure out layout dependencies for the source .txt files. layouts = {} sources = {} def init_rst_source(source_file, destname=None): source_path = join_path(source_directory, source_file) source_file_obj = open(source_path, 'rb') content = source_file_obj.read() source_file_obj.close() if not content.startswith('---'): return filebase, filetype = splitext(source_file) filebase = filebase.lower() env = load_yaml(match_yaml_frontmatter(content).group(1)) layout = env.pop('layout') if layout not in layouts: load_layout(layout, source_directory, layouts) content = replace_yaml_frontmatter('', content) if MORE_LINE in content: lead = content.split(MORE_LINE)[0] content = content.replace(MORE_LINE, '') else: lead = content if destname: destname = join_path(output_directory, destname) else: destname = join_path(output_directory, filebase + '.html') sources[source_file] = { '__content__': content, '__deps__': find_include_refs(content), '__env__': env, '__genfile__': destname, '__id__': source_file, '__layout__': layout, '__lead__': lead, '__mtime__': stat(source_path).st_mtime, '__name__': basename(destname), # filebase, '__outdir__': output_directory, '__path__': source_path, '__rst__': True, '__type__': 'text', '__filetype__': filetype } for source_file in source_files: init_rst_source(source_file) # And likewise for any source code files. def init_rst_source_code(relative_source_path, source_path, destname): source_file_obj = open(source_path, 'rb') content = source_file_obj.read() source_file_obj.close() filebase, filetype = splitext(basename(source_path)) filebase = filebase.lower() if not filetype: if content.startswith('#!'): content = content.split('\n', 1) if len(content) == 2: shebang, content = content else: shebang = content[0] content = '' for interp, ext in SHEBANGS: if interp in shebang: filetype = ext break if not filetype: raise ValueError("Unknown file type: %s" % source_path) sources[source_path] = { '__content__': content, '__deps__': [], '__env__': {'title': filebase}, '__genfile__': destname, '__gitpath__': relative_source_path, '__id__': source_path, '__layout__': code_layout, '__lead__': '', '__mtime__': stat(source_path).st_mtime, '__name__': basename(destname), # filebase, '__outdir__': output_directory, '__path__': source_path, '__rst__': True, '__type__': 'code', '__filetype__': filetype } if code_layout and code_layout not in layouts: load_layout(code_layout, source_directory, layouts) for destname, (relative_source_path, source_path) in code_files.items(): init_rst_source_code(relative_source_path, source_path, destname) # And likewise for the ``index_pages``. render_last = set() for index_page, index_source in index_pages.items(): layout, filetype = splitext(index_source) if filetype == '.genshi': if layout not in layouts: load_layout(layout, source_directory, layouts) source_path = join_path(source_directory, '_layouts', index_source) sources[index_source] = { '__content__': '', '__deps__': [], '__env__': {}, '__genfile__': join_path(output_directory, index_page), '__id__': index_source, '__layout__': layout, '__lead__': '', '__mtime__': stat(source_path).st_mtime, '__name__': basename(index_page), '__outdir__': output_directory, '__path__': source_path, '__rst__': False, '__type__': 'index', '__filetype__': 'genshi' } else: init_rst_source(index_source, index_page) render_last.add(index_source) # Update the envs for all the source files. for source in sources: info = sources[source] layout = info['__layout__'] layout_info = layouts[layout] if layout_info['__deps__']: for dep_layout in reversed(layout_info['__deps__']): info.update(layouts[dep_layout]['__env__']) info.update(layouts[layout]['__env__']) info.update(get_git_info(info['__path__'])) info.update(info.pop('__env__')) # Figure out which files to regenerate. if not options.force: no_regen = set() for source in sources: info = sources[source] try: gen_mtime = stat(info['__genfile__']).st_mtime except: continue dirty = False if gen_mtime < info['__mtime__']: dirty = True layout = info['__layout__'] layout_info = layouts[layout] if layout_info['__deps__']: layout_chain = [layout] + layout_info['__deps__'] else: layout_chain = [layout] for layout in layout_chain: if gen_mtime < layouts[layout]['__mtime__']: dirty = True break for dep in info['__deps__']: dep_mtime = stat(join_path(source_directory, dep)).st_mtime if gen_mtime < dep_mtime: dirty = True break if not dirty: no_regen.add(source) for source in no_regen: if source in render_last: continue del sources[source] remaining = set(sources.keys()) if remaining == render_last: for source in remaining.intersection(no_regen): del sources[source] BLANK_CODE_LINE = '<div class="syntax"><pre><div class="syntax"><pre></pre></div>' # Regenerate! items = sorted(sources.items(), key=lambda x: x[1]['__rst__'] == False) for source, source_info in items: info = config.copy() info.update(source_info) if verbose: print print LINE print 'Converting: [%s] %s' % (info['__type__'], info['__path__']) print LINE print if info['__type__'] == 'code': content = info['__content__'] conf = PROGLANGS[info['__filetype__']] if conf[2]: content = conf[2](content) comment_matcher = conf[3] lines = content.split('\n') include_section = None if lines and lines[0].startswith('#!'): lines.pop(0) sections = []; new_section = sections.append docs_text = []; docs_out = docs_text.append code_text = []; code_out = code_text.append for line in lines: if comment_matcher.match(line): line = comment_matcher.sub('', line) if line == '<yatiblog.comment>': include_section = 1 else: docs_out(line) else: if not line.strip(): if docs_text and not include_section: last_line = docs_text[-1].strip() if last_line: last_line_char = last_line[0] for char in last_line: if char != last_line_char: break else: include_section = 1 else: if docs_text: include_section = 1 if docs_text: if include_section: new_section({ 'docs_text': '\n'.join(docs_text) + '\n', 'code_text': '\n'.join(code_text) }) docs_text[:] = [] code_text[:] = [] include_section = None else: docs_text[:] = [] code_out(line) else: code_out(line) new_section({'docs_text': '', 'code_text': '\n'.join(code_text)}) docs = conf[6].join(part['docs_text'] for part in sections) code = conf[4].join(part['code_text'] for part in sections) docs_html, props = render_rst(docs, with_props=1) if ('title' in props) and props['title']: info['title'] = props['title'] code = code.replace('\t', ' ') code_html = highlight(code, get_lexer_by_name(conf[0]), SYNTAX_FORMATTER) docs_split = conf[7].split(docs_html) code_split = conf[5].split(code_html) output = info['__output__'] = [] out = output.append if docs_split and docs_split[0]: diff = 0 docs_split.insert(0, u'') else: diff = 1 last = len(docs_split) - 2 for i in range(last + 1): code = code_split[i+diff].split(u'<br/>') while (code and code[0] == ''): code.pop(0) while (code and code[-1] == ''): code.pop() code = u'<br />'.join(code) if code: if i == last: code = u'<div class="syntax"><pre>' + code else: code = u'<div class="syntax"><pre>' + code + "</pre></div>" out((docs_split[i], code)) while output and output[0][1] == BLANK_CODE_LINE: if not output[0][0]: output.pop(0) elif info['__rst__']: with_props = info.get('with_props', False) if with_props: output, props = render_rst(info['__content__'], with_props=1) if ('title' in props) and props['title']: info['title'] = props['title'] info['__output__'] = output else: output = info['__output__'] = render_rst(info['__content__']) if info['__lead__'] == info['__content__']: info['__lead_output__'] = info['__output__'] else: info['__lead_output__'] = render_rst(info['__lead__']) else: output = '' layout = info['__layout__'] layout_info = layouts[layout] if layout_info['__deps__']: layout_chain = [layout] + layout_info['__deps__'] else: layout_chain = [layout] for layout in layout_chain: template = layouts[layout]['__template__'] output = template.generate( content=output, yatidb=data_dict, **info ).render('xhtml', encoding=None) if isinstance(output, unicode): output = output.encode('utf-8') data_dict[info['__name__']] = info output_file = open(info['__genfile__'], 'wb') output_file.write(output) output_file.close() if verbose: print 'Done!' sys.exit()
def root(self): if not self._root: if self.scm == 'git': self._root = abspath( run_command(['git', 'rev-parse', '--show-cdup']).strip()) return self._root