def process_svg_image( ctx, source_image, dst_filename, width=None, height=None, mode=None, ): if width is None and height is None: raise ValueError("Must specify at least one of width or height.") # Because Lektor doesn't have a generic find program (only imagemagick), # only *nix is supported for simplicity. Imagemagick will be used as the # fallback on Windows, but it won't work well... if os.name == 'nt': return process_image(ctx, source_image, dst_filename, width, height, mode, 85) inkscape = locate_executable('inkscape') cmdline = [inkscape, source_image] if width is not None: cmdline += ["-w", str(width)] if height is not None: cmdline += ["-h", str(height)] # FIXME: This will only work with inkscape 1.0+ cmdline += ["--export-filename", dst_filename] reporter.report_debug_info("inkscape cmd line", cmdline) portable_popen(cmdline).wait()
def process_image(ctx, source_image, dst_filename, width=None, height=None, mode=ThumbnailMode.DEFAULT, quality=None, offset=None, zoom=None): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ if width is None and height is None: raise ValueError("Must specify at least one of width or height.") im = find_imagemagick(ctx.build_state.config["IMAGEMAGICK_EXECUTABLE"]) if quality is None: quality = get_quality(source_image) resize_key = '' offset_key = '' gravity = 'Center' zoom_key = '100%' if width is not None: resize_key += str(width) if height is not None: resize_key += 'x' + str(height) if offset is not None and len(offset) == 2: offset_key = '%+d%+d' % ((offset[0] - width / 2), (offset[1] - height / 2)) gravity = 'NorthWest' if zoom is not None: zoom_key = '%d' % zoom + '%' print(gravity, offset_key, zoom_key, dst_filename) if mode == ThumbnailMode.STRETCH: resize_key += "!" cmdline = [im, source_image, "-auto-orient"] if mode == ThumbnailMode.CROP: cmdline += [ '-resize', zoom_key, '-gravity', gravity, '-extent', resize_key + offset_key, ] else: cmdline += ["-resize", resize_key] cmdline += ["-strip", "-colorspace", "sRGB"] cmdline += ["-quality", str(quality), dst_filename] reporter.report_debug_info("imagemagick cmd line", cmdline) portable_popen(cmdline).wait()
def parse_templates(self, to_filename): pybabel=locate_executable('pybabel') if pybabel is None: pybabel="/usr/bin/pybabel" cmdline=[pybabel, 'extract', '-F', 'babel.cfg', "-o", to_filename, "./"] reporter.report_debug_info('pybabel cmd line', cmdline) portable_popen(cmdline).wait()
def process_image(ctx, source_image, dst_filename, width, height=None, crop=False): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ im = find_imagemagick( ctx.build_state.config['IMAGEMAGICK_EXECUTABLE']) quality = get_quality(source_image) resize_key = str(width) if height is not None: resize_key += 'x' + str(height) cmdline = [im, source_image] if crop: cmdline += ['-resize', resize_key + '^', '-gravity', 'Center', '-extent', resize_key] else: cmdline += ['-resize', resize_key] cmdline += ['-auto-orient', '-quality', str(quality), dst_filename] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def process_image(ctx, source_image, dst_filename, width, height=None, crop=False): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ im = find_imagemagick(ctx.build_state.config['IMAGEMAGICK_EXECUTABLE']) quality = get_quality(source_image) resize_key = str(width) if height is not None: resize_key += 'x' + str(height) cmdline = [im, source_image] if crop: cmdline += [ '-resize', resize_key + '^', '-gravity', 'Center', '-extent', resize_key ] else: cmdline += ['-resize', resize_key] cmdline += ['-auto-orient', '-quality', str(quality), dst_filename] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def merge_pot(self, from_filenames, to_filename): msgcat=locate_executable('msgcat') cmdline=[msgcat, "--use-first"] cmdline.extend(from_filenames) cmdline.extend(("-o", to_filename)) reporter.report_debug_info('msgcat cmd line', cmdline) portable_popen(cmdline).wait()
def merge_pot(self, from_filenames, to_filename): msgcat = locate_executable('msgcat') cmdline = [msgcat, "--use-first"] cmdline.extend(from_filenames) cmdline.extend(("-o", to_filename)) reporter.report_debug_info('msgcat cmd line', cmdline) portable_popen(cmdline).wait()
def _msg_init(self): """Generates the first <language>.po file""" msginit = locate_executable('msginit') cmdline = [ msginit, "-i", "contents.pot", "-l", self.language, "-o", self.FILENAME_PATTERN % self.language, "--no-translator" ] reporter.report_debug_info('msginit cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def _msg_merge(self): """Merges an existing <language>.po file with .pot file""" msgmerge = locate_executable('msgmerge') cmdline = [ msgmerge, self.FILENAME_PATTERN % self.language, "contents.pot", "-U", "-N", "--backup=simple" ] reporter.report_debug_info('msgmerge cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def _msg_fmt(self, locale_dirname): """Compile an existing <language>.po file into a .mo file""" msgfmt = locate_executable('msgfmt') cmdline = [ msgfmt, self.FILENAME_PATTERN % self.language, "-o", join(locale_dirname, "contents.mo") ] reporter.report_debug_info('msgfmt cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def start(self): if self.watcher is not None: return from lektor import admin admin = os.path.dirname(admin.__file__) portable_popen(['npm', 'install', '.'], cwd=admin).wait() self.watcher = portable_popen( ['../node_modules/.bin/webpack', '--watch'], cwd=os.path.join(admin, 'static'))
def start(self): if self.watcher is not None: return from lektor import admin admin = os.path.dirname(admin.__file__) portable_popen(['npm', 'install', '.'], cwd=admin).wait() self.watcher = portable_popen(['../node_modules/.bin/webpack', '--watch'], cwd=os.path.join(admin, 'static'))
def parse_templates(self, to_filename): pybabel = locate_executable('pybabel') cmdline = [ pybabel, 'extract', '-F', 'babel.cfg', "-o", to_filename, "./" ] reporter.report_debug_info('pybabel cmd line', cmdline) try: portable_popen(cmdline).wait() except TypeError as err: traceback.print_exc(file=sys.stderr) print(err)
def build_thumbnail_artifact(artifact): resize_key = str(width) if height is not None: resize_key += 'x' + str(height) artifact.ensure_dir() cmdline = [im, source_image, '-resize', resize_key, '-auto-orient', '-quality', str(quality), artifact.dst_filename] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def install_node_dependencies(self): webpack_root = os.path.join(self.env.root_path, 'webpack') # Use yarn over npm if it's availabe and there is a yarn lockfile has_yarn_lockfile = os.path.exists( os.path.join(webpack_root, 'yarn.lock')) pkg_manager = 'npm' if locate_executable('yarn') is not None and has_yarn_lockfile: pkg_manager = 'yarn' reporter.report_generic('Running {} install'.format(pkg_manager)) portable_popen([pkg_manager, 'install'], cwd=webpack_root).wait()
def start(self): if self.watcher is not None: return from lektor import admin admin = os.path.dirname(admin.__file__) portable_popen(["npm", "install", "."], cwd=admin).wait() self.watcher = portable_popen( [os.path.join(admin, "node_modules/.bin/webpack"), "--watch"], cwd=os.path.join(admin, "static"), )
def run_uncss(self, sources, output): npm_root = os.path.join(self.env.root_path, ".") args = [os.path.join(npm_root, "node_modules", ".bin", "uncss")] args.extend(sources) args.append("-n") args.append("-o") args.append(output) ignore = self.options.get("uncss.ignore", "") if len(ignore) > 0: args.append("-i") args.append(ignore) portable_popen(args, cwd=npm_root).wait()
def on_setup_env(self, **extra): # add all functions which should be visible from the jinja2 templates self.env.jinja_env.globals.update( get_year=get_year, generate_download_section=generate_download_section, generate_maintainer_overview=generate_maintainer_overview, generate_news_section=news.generate_news_section, # for the slug generation slugify=slugify) # craft temporary POT file with languages now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M') now += '+%s' % (time.tzname[0]) pot = [ re.sub( '\n\\s+', '\n', """msgid ""\nmsgstr ""\n "Project-Id-Version: 0.0.0\\n" "Report-Msgid-Bugs-To: [email protected]\\n" "POT-Creation-Date: {}s\\n"\n "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" "Language-Team: FreeDict <*****@*****.**>\\n" "Language: LANGUAGE\\n" "MIME-Version: 1.0\\n"\n"Content-Type: text/plain; charset=UTF-8\\n" "Content-Transfer-Encoding: 8bit\\n"\n""".format(now)) ] for lang in sorted(self.get_used_languages()): pot.append('\n#: iso-639-3.tab (no:lineno)\n') pot.append('msgid "{}"\nmsgstr ""\n'.format(lang)) if not os.path.exists("i18n"): os.mkdir("i18n") lang_pot = tempfile.NamedTemporaryFile(suffix='pot') lang_pot.write(''.join(pot).encode('UTF-8')) lang_pot.flush() plugin_pot = tempfile.NamedTemporaryFile(suffix='pot') # retrieve relative path from lektor project root directory = os.path.dirname(os.path.abspath(__file__)) directory = directory.replace(os.getcwd() + os.sep, '') pyfiles = [ os.path.join(directory, f) for f in os.listdir(directory) if f.endswith('.py') ] xgettext = portable_popen([ 'xgettext', '-L', 'Python', '--from-code=UTF-8', '-o', plugin_pot.name ] + pyfiles) ret = xgettext.wait() if ret: raise OSError('xgettext exited with %d' % ret) with open(os.path.join('i18n', 'plugins.pot'), 'wb') as f: portable_popen([ 'msgcat', "--use-first", lang_pot.name, '-t', 'UTF-8', plugin_pot.name ], stdout=f).wait()
def start(self): if self.watcher is not None: return self.signal_state = self.env.plugin_controller.emit('devtools_start') from lektor import admin admin = os.path.dirname(admin.__file__) portable_popen(['npm', 'install', '.'], cwd=admin).wait() self.watcher = portable_popen([os.path.join( admin, 'node_modules/.bin/webpack'), '--watch'], cwd=os.path.join(admin, 'static'))
def build_thumbnail_artifact(artifact): resize_key = str(width) if height is not None: resize_key += 'x' + str(height) artifact.ensure_dir() cmdline = [ im, source_image, '-resize', resize_key, '-quality', str(quality), artifact.dst_filename ] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def install_local_package(package_root, path): """This installs a local dependency of a package.""" # XXX: windows env = dict(os.environ) env["PYTHONPATH"] = package_root # Step 1: generate egg info and link us into the target folder. rv = portable_popen( [ sys.executable, "-m", "pip", "install", "--editable", path, "--install-option=--install-dir=%s" % package_root, "--no-deps", ], env=env, ).wait() if rv != 0: raise RuntimeError("Failed to install local package") # Step 2: generate the egg info into a temp folder to find the # requirements. tmp = tempfile.mkdtemp() try: rv = portable_popen( [ sys.executable, "setup.py", "--quiet", "egg_info", "--quiet", "--egg-base", tmp, ], cwd=path, ).wait() dirs = os.listdir(tmp) if rv != 0 or len(dirs) != 1: raise RuntimeError("Failed to create egg info for local package.") requires = os.path.join(tmp, dirs[0], "requires.txt") # We have dependencies, install them! if os.path.isfile(requires): download_and_install_package(package_root, requirements_file=requires) finally: shutil.rmtree(tmp)
def process_image( ctx, source_image, dst_filename, width=None, height=None, mode=ThumbnailMode.DEFAULT, quality=None, ): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ if width is None and height is None: raise ValueError("Must specify at least one of width or height.") im = find_imagemagick(ctx.build_state.config["IMAGEMAGICK_EXECUTABLE"]) if quality is None: quality = get_quality(source_image) resize_key = "" if width is not None: resize_key += str(width) if height is not None: resize_key += "x" + str(height) if mode == ThumbnailMode.STRETCH: resize_key += "!" cmdline = [im, source_image, "-auto-orient"] if mode == ThumbnailMode.CROP: cmdline += [ "-resize", resize_key + "^", "-gravity", "Center", "-extent", resize_key, ] else: cmdline += ["-resize", resize_key] cmdline += ["-strip", "-colorspace", "sRGB"] cmdline += ["-quality", str(quality), dst_filename] reporter.report_debug_info("imagemagick cmd line", cmdline) portable_popen(cmdline).wait()
def requirements_from_unfinished_editable_install_at_path(path): # Step 2: generate the egg info into a temp folder to find the # requirements. tmp = tempfile.mkdtemp() try: rv = portable_popen( [ sys.executable, "setup.py", "--quiet", "egg_info", "--quiet", "--egg-base", tmp, ], cwd=path, ).wait() dirs = os.listdir(tmp) if rv != 0 or len(dirs) != 1: raise RuntimeError("Failed to create egg info for local package.") requires_path = os.path.join(tmp, dirs[0], "requires.txt") if os.path.isfile(requires_path): # We have dependencies, install them! return requirements_from_requires_file(requires_path) finally: shutil.rmtree(tmp) # no dependencies to install return None
def build_artifact(self, artifact): ctx = get_ctx() source_out = self.build_state.make_named_temporary('less') map_out = self.build_state.make_named_temporary('less-sourcemap') here = os.path.dirname(self.source.source_filename) exe = self.build_state.config['LESSC_EXECUTABLE'] if exe is None: exe = 'lessc' cmdline = [exe, '--no-js', '--include-path=%s' % here, '--source-map=%s' % map_out, self.source.source_filename, source_out] reporter.report_debug_info('lessc cmd line', cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError('lessc failed') with open(map_out) as f: for dep in json.load(f).get('sources') or (): ctx.record_dependency(os.path.join(here, dep)) artifact.replace_with_file(source_out) @ctx.sub_artifact(artifact_name=artifact.artifact_name + '.map', sources=[self.source.source_filename]) def build_less_sourcemap_artifact(artifact): artifact.replace_with_file(map_out)
def build_artifact(self, artifact): ctx = get_ctx() source_out = self.build_state.make_named_temporary('less') map_out = self.build_state.make_named_temporary('less-sourcemap') here = os.path.dirname(self.source.source_filename) exe = self.build_state.config['LESSC_EXECUTABLE'] if exe is None: exe = 'lessc' cmdline = [ exe, '--no-js', '--include-path=%s' % here, '--source-map=%s' % map_out, self.source.source_filename, source_out ] reporter.report_debug_info('lessc cmd line', cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError('lessc failed') with open(map_out) as f: for dep in json.load(f).get('sources') or (): ctx.record_dependency(os.path.join(here, dep)) artifact.replace_with_file(source_out) @ctx.sub_artifact(artifact_name=artifact.artifact_name + '.map', sources=[self.source.source_filename]) def build_less_sourcemap_artifact(artifact): artifact.replace_with_file(map_out)
def build_thumbnail_artifact(artifact): artifact.ensure_dir() vfilter = 'thumbnail,scale={rw}:{rh},crop={tw}:{th}'.format( rw=resize_dim.width, rh=resize_dim.height, tw=crop_dim.width, th=crop_dim.height, ) cmdline = [ ffmpeg, '-loglevel', '-8', '-ss', get_timecode(seek), # Input seeking since it's faster '-i', source_video, '-vf', vfilter, '-frames:v', '1', '-qscale:v', str(get_ffmpeg_quality(quality)), artifact.dst_filename, ] reporter.report_debug_info('ffmpeg cmd line', cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError( 'ffmpeg exited with code {}'.format(proc.returncode)) if not os.path.exists(artifact.dst_filename): msg = ('Unable to create video thumbnail for {!r}. Maybe the seek ' 'is outside of the video duration?') raise RuntimeError(msg.format(source_video))
def build_artifact(self, artifact): ctx = get_ctx() source_out = self.build_state.make_named_temporary("less") map_out = self.build_state.make_named_temporary("less-sourcemap") here = os.path.dirname(self.source.source_filename) cmdline = [ "lessc", "--no-js", "--include-path=%s" % here, "--source-map=%s" % map_out, self.source.source_filename, source_out, ] reporter.report_debug_info("lessc cmd line", cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError("lessc failed") with open(map_out) as f: dep_base = os.path.dirname(map_out) for dep in json.load(f).get("sources") or (): ctx.record_dependency(os.path.join(dep_base, dep)) artifact.replace_with_file(source_out)
def get_package_info(path): """Returns the name of a package at a path.""" rv = (portable_popen( [ sys.executable, "setup.py", "--quiet", "--name", "--author", "--author-email", "--license", "--url", ], cwd=path, stdout=PIPE, ).communicate()[0].splitlines()) def _process(value): value = value.strip() if value == "UNKNOWN": return None return value.decode("utf-8", "replace") return { "name": _process(rv[0]), "author": _process(rv[1]), "author_email": _process(rv[2]), "license": _process(rv[3]), "url": _process(rv[4]), "path": path, }
def download_and_install_package(package_root, package=None, version=None, requirements_file=None): """This downloads and installs a specific version of a package.""" # XXX: windows env = dict(os.environ) args = [ sys.executable, "-m", "pip", "install", "--target", package_root, ] if package is not None: args.append("%s%s%s" % (package, version and "==" or "", version or "")) if requirements_file is not None: args.extend(("-r", requirements_file)) rv = portable_popen(args, env=env).wait() if rv != 0: raise RuntimeError("Failed to install dependency package.")
def __init__(self, argline, cwd=None, env=None, capture=True, silent=False): environ = dict(os.environ) if env: environ.update(env) kwargs = {"cwd": cwd, "env": environ} if silent: kwargs["stdout"] = subprocess.DEVNULL kwargs["stderr"] = subprocess.DEVNULL capture = False if capture: kwargs["stdout"] = subprocess.PIPE kwargs["stderr"] = subprocess.STDOUT if sys.version_info >= (3, 7): # Python >= 3.7 has sane encoding defaults in the case that the system is # (likely mis-)configured to use ASCII as the default encoding (PEP538). # It also provides a way for the user to force the use of UTF-8 (PEP540). kwargs["text"] = True else: kwargs["encoding"] = "utf-8" kwargs["errors"] = "replace" self.capture = capture self._cmd = portable_popen(argline, **kwargs)
def run_brunch(self, build_flags, watch=False): brunch_root = os.path.join(self.env.root_path, 'brunch') args = [os.path.join(brunch_root, 'node_modules', '.bin', 'brunch')] if watch: args.append('watch') else: args.append('build') if self.is_production(build_flags): args.append('--production') return portable_popen(args, cwd=brunch_root)
def __init__(self, argline, cwd=None, env=None, capture=True): environ = dict(os.environ) if env: environ.update(env) kwargs = {'cwd': cwd, 'env': env} if capture: kwargs['stdout'] = subprocess.PIPE kwargs['stderr'] = subprocess.PIPE self.capture = capture self._cmd = portable_popen(argline, **kwargs)
def process_image(ctx, source_image, dst_filename, width=None, height=None, mode=ThumbnailMode.DEFAULT, quality=None): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ if width is None and height is None: raise ValueError("Must specify at least one of width or height.") im = find_imagemagick(ctx.build_state.config['IMAGEMAGICK_EXECUTABLE']) if quality is None: quality = get_quality(source_image) resize_key = '' if width is not None: resize_key += str(width) if height is not None: resize_key += 'x' + str(height) if mode == ThumbnailMode.STRETCH: resize_key += '!' cmdline = [im, source_image, '-auto-orient'] if mode == ThumbnailMode.CROP: cmdline += [ '-resize', resize_key + '^', '-gravity', 'Center', '-extent', resize_key ] else: cmdline += ['-resize', resize_key] cmdline += ['-quality', str(quality), dst_filename] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def publish(self, target_url): argline = self.get_command_line(target_url) cmd = portable_popen(argline, stdout=subprocess.PIPE) try: while 1: line = cmd.stdout.readline() if not line: break yield line.rstrip().decode('utf-8', 'replace') finally: cmd.wait()
def run_package_manager(self, *args): # Use yarn over npm if it's availabe and there is a yarn lockfile has_yarn_lockfile = os.path.exists( self.get_webpack_folder('yarn.lock')) pkg_manager = 'npm' if locate_executable('yarn') is not None and has_yarn_lockfile: pkg_manager = 'yarn' reporter.report_generic('Running {} {}'.format(pkg_manager, " ".join(args))) return portable_popen([pkg_manager] + list(args), cwd=self.get_webpack_folder())
def get_video_info(filename): """Read video information using ffprobe if available. Returns a dict with: width, height and duration. """ ffprobe = locate_executable("ffprobe") if ffprobe is None: raise RuntimeError("Failed to locate ffprobe") proc = portable_popen( [ ffprobe, "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", filename, ], stdout=subprocess.PIPE, ) stdout, _ = proc.communicate() if proc.returncode != 0: raise RuntimeError("ffprobe exited with code %d" % proc.returncode) ffprobe_data = json.loads(stdout.decode("utf8")) info = { "width": None, "height": None, "duration": None, } # Try to extract total video duration try: info["duration"] = timedelta( seconds=float(ffprobe_data["format"]["duration"])) except (KeyError, TypeError, ValueError): pass # Try to extract width and height from the first found video stream for stream in ffprobe_data["streams"]: if stream["codec_type"] != "video": continue info["width"] = int(stream["width"]) info["height"] = int(stream["height"]) # We currently don't bother with multiple video streams break return info
def process_image( ctx, source_image, dst_filename, width=None, height=None, mode=None, quality=None, extra_params=None, ): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ if width is None and height is None: raise ValueError("Must specify at least one of width or height.") im = find_imagemagick(ctx.build_state.config["IMAGEMAGICK_EXECUTABLE"]) if quality is None: quality = get_quality(source_image) resize_key = "" if width is not None: resize_key += str(width) if height is not None: resize_key += "x" + str(height) cmdline = [im, source_image, "-auto-orient"] cmdline += ["-resize", resize_key] if extra_params: cmdline.extend(extra_params) cmdline += ["-quality", str(quality), dst_filename] reporter.report_debug_info("imagemagick cmd line", cmdline) portable_popen(cmdline).wait()
def __init__(self, argline, cwd=None, env=None, capture=True, silent=False): environ = dict(os.environ) if env: environ.update(env) kwargs = {"cwd": cwd, "env": environ} if silent: kwargs["stdout"] = devnull kwargs["stderr"] = devnull capture = False if capture: kwargs["stdout"] = subprocess.PIPE kwargs["stderr"] = subprocess.PIPE self.capture = capture self._cmd = portable_popen(argline, **kwargs)
def install_local_package(package_root, path): """This installs a local dependency of a package.""" # XXX: windows env = dict(os.environ) env['PYTHONPATH'] = package_root # Step 1: generate egg info and link us into the target folder. rv = portable_popen([ sys.executable, '-m', 'pip', 'install', '--editable', path, '--install-option=--install-dir=%s' % package_root, '--no-deps' ], env=env).wait() if rv != 0: raise RuntimeError('Failed to install local package') # Step 2: generate the egg info into a temp folder to find the # requirements. tmp = tempfile.mkdtemp() try: rv = portable_popen([ sys.executable, 'setup.py', '--quiet', 'egg_info', '--quiet', '--egg-base', tmp ], cwd=path).wait() dirs = os.listdir(tmp) if rv != 0 or len(dirs) != 1: raise RuntimeError('Failed to create egg info for local package.') requires = os.path.join(tmp, dirs[0], 'requires.txt') # We have dependencies, install them! if os.path.isfile(requires): download_and_install_package(package_root, requirements_file=requires) finally: shutil.rmtree(tmp)
def __init__(self, argline, cwd=None, env=None, capture=True, silent=False): environ = dict(os.environ) if env: environ.update(env) kwargs = {'cwd': cwd, 'env': environ} if silent: self.devnull = open(os.devnull, 'rb+') kwargs['stdout'] = self.devnull kwargs['stderr'] = self.devnull capture = False if capture: kwargs['stdout'] = subprocess.PIPE kwargs['stderr'] = subprocess.PIPE self.capture = capture self._cmd = portable_popen(argline, **kwargs)
def download_and_install_package(package_root, package=None, version=None, requirements_file=None): """This downloads and installs a specific version of a package.""" # XXX: windows env = dict(os.environ) args = [ sys.executable, '-m', 'pip', 'install', '--target', package_root, ] if package is not None: args.append('%s%s%s' % (package, version and '==' or '', version or '')) if requirements_file is not None: args.extend(('-r', requirements_file)) rv = portable_popen(args, env=env).wait() if rv != 0: raise RuntimeError('Failed to install dependency package.')
def get_package_info(path): """Returns the name of a package at a path.""" rv = portable_popen([ sys.executable, 'setup.py', '--quiet', '--name', '--author', '--author-email', '--license', '--url', ], cwd=path, stdout=PIPE).communicate()[0].splitlines() def _process(value): value = value.strip() if value == 'UNKNOWN': return None return value.decode('utf-8', 'replace') return { 'name': _process(rv[0]), 'author': _process(rv[1]), 'author_email': _process(rv[2]), 'license': _process(rv[3]), 'url': _process(rv[4]), 'path': path, }
def parse_templates(self, to_filename): pybabel=locate_executable('pybabel') cmdline=[pybabel, 'extract', '-F', 'babel.cfg', "-o", to_filename, "./"] reporter.report_debug_info('pybabel cmd line', cmdline) portable_popen(cmdline).wait()
def _msg_init(self): """Generates the first <language>.po file""" msginit=locate_executable('msginit') cmdline=[msginit, "-i", "contents.pot", "-l", self.language, "-o", self.FILENAME_PATTERN%self.language, "--no-translator"] reporter.report_debug_info('msginit cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def _msg_merge(self): """Merges an existing <language>.po file with .pot file""" msgmerge=locate_executable('msgmerge') cmdline=[msgmerge, self.FILENAME_PATTERN%self.language, "contents.pot", "-U", "-N", "--backup=simple"] reporter.report_debug_info('msgmerge cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def _msg_fmt(self, locale_dirname): """Compile an existing <language>.po file into a .mo file""" msgfmt=locate_executable('msgfmt') cmdline=[msgfmt, self.FILENAME_PATTERN%self.language, "-o", join(locale_dirname,"contents.mo")] reporter.report_debug_info('msgfmt cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def publish_package(path): """Registers the plugin at the given path.""" portable_popen([ sys.executable, 'setup.py', 'sdist', 'bdist_wheel', 'upload' ], cwd=path).wait()
def register_package(path): """Registers the plugin at the given path.""" portable_popen([ sys.executable, 'setup.py', 'register' ], cwd=path).wait()
def run_webpack(self, watch=False): webpack_root = os.path.join(self.env.root_path, 'webpack') args = [os.path.join(webpack_root, 'node_modules', '.bin', 'webpack')] if watch: args.append('--watch') return portable_popen(args, cwd=webpack_root)
def npm_install(self): reporter.report_generic('Running npm install') webpack_root = os.path.join(self.env.root_path, 'webpack') portable_popen(['npm', 'install'], cwd=webpack_root).wait()