Beispiel #1
0
def _calculate_deps(js_entrypoint_file_path):
    js_sources = set()
    source_files = set()
    logging.info("Scanning paths for Javascript files...")
    for js_path in loader.locate("*.js"):
        if not js_path.startswith(coverage.INSTRUMENTED_CODE_PATH):
            source_files.add(js_path)

    for js_path in source_files:
        js_sources.add(closurebuilder._PathSource(js_path))

    logging.info("Done")
    logging.info("Building dependency tree..")
    tree = depstree.DepsTree(js_sources)

    # find the namespace of entrypoint
    entrypoint_source = closurebuilder._PathSource(js_entrypoint_file_path)
    if entrypoint_source.provides:
        namespace = entrypoint_source.provides
    else:
        namespace = entrypoint_source.requires

    # namespace = [closurebuilder._PathSource(js_entrypoint_file_path).provides.pop()]
    # The Closure Library base file must go first.
    base = closurebuilder._GetClosureBaseFile(js_sources)
    deps = [base] + tree.GetDependencies(namespace)
    logging.info("Done")
    return deps
    def __init__(self, buildout, name, options):
        self.buildout = buildout
        self.name = name
        self.options = options

        self.dependency = options["dependency"]
        self.compiler_jar = options.get("jar", DEFAULT_COMPILER_JAR)
        self.compiler_flags = [
            flag for flag in options.get("flags", "").split() if flag
            ]

        self.extra_js = [
            js
            for js in self.options.get("extra_js", "").split()
            if js]

        self.outputdir = self.options["output"]

        path_to_source = self.buildout[self.dependency].recipe.path_to_source
        sources = path_to_source.values()
        tree = DepsTree(sources)

        base = closurebuilder._GetClosureBaseFile(sources)

        start_wd = os.getcwd()

        input_namespaces = set()
        for input_path in self.options.get("inputs", "").split():
            if not input_path:
                continue

            js_input = [
                source
                for source in sources
                if source.GetPath() == os.path.join(start_wd, input_path)
                ]
            if len(js_input) != 1:
                # logging.error('No source matched input %s', input_path)
                raise Exception("No source matched input %s" % input_path)

            input_namespaces.update(js_input[0].provides)

        input_namespaces.update(
            [namespace
             for namespace in self.options.get("namespaces", "").split()
             if namespace]
            )

        if not input_namespaces:
            raise Exception(
                "No namespaces found. At least one namespace must be "
                "specified with the --namespace or --input flags.")

        deps = [base] + tree.GetDependencies(input_namespaces)
        deps_sources = self.extra_js + \
                       [js_source.GetSourcePath()[1] for js_source in deps]

        self.compiled_code = jscompiler.Compile(
            self.compiler_jar, deps_sources, self.compiler_flags)

        md5name = hashlib.md5()
        md5name.update(self.compiled_code)
        self.options["filename"] = self.filename = md5name.hexdigest() + ".js"
Beispiel #3
0
    def build_minified(self):
        from distutils import log
        import closurebuilder
        import treescan
        import depstree
        log.info('Building minified script "%s", mode: %s',
                 self.minified, self.output_mode)
        log.info('Scanning paths...')
        sources = set(
            (closurebuilder._PathSource(js_path)
             for path in (self.root, self.project,)
             for js_path in treescan.ScanTreeForJsFiles(path)
            ))

        log.info('%s sources scanned.', len(sources))
        log.info('Building dependency tree..')
        tree = depstree.DepsTree(sources)

        input_namespaces = set(self.namespaces)

        for input_path in self.inputs:
            js_input = closurebuilder._GetInputByPath(input_path, sources)
            if not js_input:
                msg = 'No source matched input %s' % input_path
                log.error(msg)
                raise DistutilsError, msg

            input_namespaces.update(js_input.provides)

        if not input_namespaces:
            msg = ('No namespaces found. At least one namespace must be '
                   'specified with the --namespaces or --inputs flags.')
            log.error(msg)
            raise DistutilsError, msg

        base = closurebuilder._GetClosureBaseFile(sources)
        deps = [base] + tree.GetDependencies(input_namespaces)

        if self.output_mode == 'list':
            log.info('Listing files:')
            log.info('\n'.join([js_source.GetPath() for js_source in deps]))
            log.info('Build successful!')
            return

        out = open(self.minified, 'w')

        if self.output_mode == 'script':
            out.writelines([js_source.GetSource() for js_source in deps])
            out.close()
            log.info('Build successful!')
            return

        import jscompiler
        compiled_source = jscompiler.Compile(
            self.compiler_jar,
            [js_source.GetPath() for js_source in deps],
            self.compiler_flags)

        if compiled_source is None:
            msg = 'JavaScript compilation failed.'
            log.error(msg)
            raise DistutilsError, msg
        else:
            log.info('JavaScript compilation succeeded.')
            out.write(compiled_source)
            log.info('Build successful!')

        out.close()
Beispiel #4
0
def _generateModules(sources, modules, keepBaseSeparate=True):
  tree = depstree.DepsTree(sources)


  # list of tuples, (module_name, file_deps, module_deps_names)
  # + we force all modules to be dependent on the base goog module (could inject as a file deps also but this should work and is easier)
  baseDep = []
  if keepBaseSeparate:
    baseDep = ['goog']
  depLst = [ (mod[0], tree.GetDependencies(mod[1]), list(baseDep)) for mod in modules ]

  # subtract basedeps from "upper" deps
  # todo: what to do if a module becomes empty? (i.e a duplicate)
  for i in range(len(depLst)):
    for j in range(i+1, len(depLst)):
      bd = depLst[i]
      dp = depLst[j][1]
      for d in bd[1]:
        try:
          dp.remove(d)
        except:
          pass

  # create union of all provides/requires in the deps files per module
  global moduleProvides # modulename->set of all provides in module
  moduleProvides = {}
  global moduleRequires
  moduleRequires = {} # modulename->set of all requires in module

  for name, deps, moddeps in depLst:
    if len(deps) == 0:
      out.writelines('Warning - empty module: "' + name + '". Probably due to incorrect module ordering')
    moduleProvides[name] = set()
    moduleRequires[name] = set()
    for src in deps:
      for prov in src.provides:
        moduleProvides[name].add(prov)
      for req in src.requires:
        moduleRequires[name].add(req)

  # figure out module-module deps
  # todo: could/should also verify that all dependecies go "down" (the tree should have fixed this though)
  moduleModuleDeps = {} # moduleName->list of module deps
  for i in range(len(depLst)-1, -1, -1): # reverse
    td = depLst[i]
    for j in range(i-1, -1, -1):
      bd = depLst[j]
      if moduleRequires[td[0]] & moduleProvides[bd[0]]: # intersects? (todo: is there no isintersecting test? (more efficient since we don't actually need the complete intersection set)
        td[2].append(bd[0])
        # print 'module:', td[0], 'depends on module:', bd[0]

  # force goog.base to be present in compilation (note that it will Not become part of any of the modules, only a dummy goog.js will be output)
  # (?! this wasn't necessary previously?)
  gbase = closurebuilder._GetClosureBaseFile(sources) # _must_ be present!
  if keepBaseSeparate:
    depLst.insert(0, ('goog', [gbase], [])) # could rename it to make it clearer it is a dummy/helper? ('__goog'?)
    moduleProvides['goog'] = set()
    moduleRequires['goog'] = set()
  else:
    depLst[0][1].insert(0, gbase) # inject goog into base module

  return depLst