예제 #1
0
  def execute(self):
    node_paths = self.context.products.get_data(NodePaths)
    runtime_classpath_product = self.context.products.get_data(
      'runtime_classpath', init_func=ClasspathProducts.init_func(self.get_options().pants_workdir))
    bundleable_js_product = self.context.products.get_data(
      'bundleable_js', init_func=lambda: defaultdict(MultipleRootedProducts))

    targets = self.context.targets(predicate=self.is_node_module)
    with self.invalidated(targets, invalidate_dependents=True) as invalidation_check:
      for vt in invalidation_check.all_vts:
        target = vt.target
        node_installed_path = node_paths.node_path(target)

        with pushd(node_installed_path):
          if not vt.valid:
            self._run_build_script(
              target, vt.results_dir, node_installed_path, node_paths.all_node_paths)
          if not target.payload.dev_dependency:
            output_dir = self._get_output_dir(target, node_installed_path)
            # Make sure that there is output generated.
            if not os.path.exists(output_dir):
              raise TaskError(
                'Target {} has build script {} specified, but did not generate any output '
                'at {}.\n'.format(
                  target.address.reference(), target.payload.build_script, output_dir))
            absolute_symlink(output_dir, os.path.join(vt.results_dir, target.address.target_name))
            bundleable_js_product[target].add_abs_paths(output_dir, [output_dir])
            runtime_classpath_product.add_for_target(target, [('default', vt.results_dir)])
예제 #2
0
  def execute(self):
    node_paths = self.context.products.get_data(NodePaths)
    runtime_classpath_product = self.context.products.get_data(
      'runtime_classpath', init_func=ClasspathProducts.init_func(self.get_options().pants_workdir))
    bundleable_js_product = self.context.products.get_data(
      'bundleable_js', init_func=lambda: defaultdict(MultipleRootedProducts))

    targets = self.context.targets(predicate=self.is_node_module)
    with self.invalidated(targets, invalidate_dependents=True) as invalidation_check:
      for vt in invalidation_check.all_vts:
        target = vt.target
        node_installed_path = node_paths.node_path(target)

        with pushd(node_installed_path):
          if not vt.valid:
            self._run_build_script(target, vt.results_dir, node_installed_path)

          if not target.payload.dev_dependency:
            output_dir = self._get_output_dir(target, node_installed_path)
            # Make sure that there is output generated.
            if not os.path.exists(output_dir):
              raise TaskError(
                'Target {} has build script {} specified, but did not generate any output '
                'at {}.\n'.format(
                  target.address.reference(), target.payload.build_script, output_dir))
            absolute_symlink(output_dir, os.path.join(vt.results_dir, target.address.target_name))
            bundleable_js_product[target].add_abs_paths(output_dir, [output_dir])
            runtime_classpath_product.add_for_target(target, [('default', vt.results_dir)])
예제 #3
0
async def export(
    console: Console,
    targets: Targets,
    export_subsystem: ExportSubsystem,
    workspace: Workspace,
    union_membership: UnionMembership,
    build_root: BuildRoot,
    dist_dir: DistDir,
) -> Export:
    request_types = cast("Iterable[type[ExportableDataRequest]]",
                         union_membership.get(ExportableDataRequest))
    requests = tuple(request_type(targets) for request_type in request_types)
    exportables = await MultiGet(
        Get(ExportableData, ExportableDataRequest, request)
        for request in requests)
    prefixed_digests = await MultiGet(
        Get(Digest, AddPrefix(exp.digest, exp.reldir)) for exp in exportables)
    output_dir = os.path.join(str(dist_dir.relpath), "export")
    merged_digest = await Get(Digest, MergeDigests(prefixed_digests))
    dist_digest = await Get(Digest, AddPrefix(merged_digest, output_dir))
    workspace.write_digest(dist_digest)
    for exp in exportables:
        for symlink in exp.symlinks:
            # Note that if symlink.source_path is an abspath, join returns it unchanged.
            source_abspath = os.path.join(build_root.path, symlink.source_path)
            link_abspath = os.path.abspath(
                os.path.join(output_dir, exp.reldir, symlink.link_rel_path))
            absolute_symlink(source_abspath, link_abspath)
        console.print_stdout(
            f"Wrote {exp.description} to {os.path.join(output_dir, exp.reldir)}"
        )
    return Export(exit_code=0)
예제 #4
0
 def create_symlink_to_clean_workdir():
     # Executed when no link exists. We treat this as equivalent to a request to have deleted
     # this state. Operations like `clean-all` will already have purged the destination, but in
     # cases like manual removal of the symlink, we want to treat the case as equivalent.
     safe_mkdir(workdir_dst, clean=True)
     absolute_symlink(workdir_dst, workdir_src)
     maybe_create_source_control_symlink()
예제 #5
0
    def execute(self):
        targets = self.context.targets(predicate=self.is_node_module)
        if not targets:
            return

        node_paths = self.context.products.get_data(NodePaths)
        # This is required even if node does not need `compile_classpaths` because certain downstream
        # tasks require `runtime_classpath` to be initialized correctly with `compile_classpaths`
        compile_classpath = self.context.products.get_data(
            "compile_classpath",
            init_func=ClasspathProducts.init_func(
                self.get_options().pants_workdir),
        )
        runtime_classpath = self.context.products.get_data(
            "runtime_classpath", compile_classpath.copy)

        bundleable_js_product = self.context.products.get_data(
            "bundleable_js",
            init_func=lambda: defaultdict(MultipleRootedProducts))

        with self.invalidated(
                targets, invalidate_dependents=True) as invalidation_check:
            for vt in invalidation_check.all_vts:
                target = vt.target
                node_installed_path = node_paths.node_path(target)

                with pushd(node_installed_path):
                    if not vt.valid:
                        self._run_build_script(target, vt.results_dir,
                                               node_installed_path,
                                               node_paths.all_node_paths)
                    if not target.payload.dev_dependency:
                        output_dir = self._get_output_dir(
                            target, node_installed_path)
                        # Make sure that there is output generated.
                        if not os.path.exists(output_dir):
                            raise TaskError(
                                "Target {} has build script {} specified, but did not generate any output "
                                "at {}.\n".format(
                                    target.address.reference(),
                                    target.payload.build_script,
                                    output_dir,
                                ))
                        absolute_symlink(
                            output_dir,
                            os.path.join(vt.results_dir,
                                         target.address.target_name))
                        bundleable_js_product[target].add_abs_paths(
                            output_dir, [output_dir])

                        runtime_classpath.add_for_target(
                            target,
                            [("default",
                              self._snapshotted_classpath(vt.results_dir))])
예제 #6
0
  def publish_results(self, dist_dir, use_basename_prefix, vt, bundle_dir, archivepath, id, archive_ext):
    """Publish a copy of the bundle and archive from the results dir in dist."""
    # TODO (from mateor) move distdir management somewhere more general purpose.
    name = vt.target.basename if use_basename_prefix else id
    bundle_copy = os.path.join(dist_dir, '{}-bundle'.format(name))
    absolute_symlink(bundle_dir, bundle_copy)
    self.context.log.info(
      'created bundle copy {}'.format(os.path.relpath(bundle_copy, get_buildroot())))

    if archivepath:
      ext = archive.archive_extensions.get(archive_ext, archive_ext)
      archive_copy = os.path.join(dist_dir,'{}.{}'.format(name, ext))
      safe_mkdir_for(archive_copy)  # Ensure parent dir exists
      atomic_copy(archivepath, archive_copy)
      self.context.log.info(
        'created archive copy {}'.format(os.path.relpath(archive_copy, get_buildroot())))
예제 #7
0
    def maybe_create_source_control_symlink():
        """If the buildroot we are working in has a source control administrative directory, we need
        to add a link to it from the physical workdir we create.

        Tools which run from the physical workdir expect to be able to glean repository information
        directly. For instance node_binary targets are built using ad-hoc build scripts which can do
        this.
        """
        # Don't link anything unless this option is enabled.
        if not global_options.pants_physical_workdir_source_control:
            return
        for scm_state_dir in SOURCE_CONTROL_DIRS:
            scm_source_path = os.path.join(get_buildroot(), scm_state_dir)
            scm_target_path = os.path.join(workdir_dst, scm_state_dir)
            if os.path.exists(scm_source_path) and not symlink_is_correct(
                    scm_source_path, scm_target_path):
                absolute_symlink(scm_source_path, scm_target_path)
                break
예제 #8
0
def init_workdir(global_options):
    """Given the bootstrap options (generally immediately after bootstrap), initialize the workdir.

    If it is in use, the "physical" workdir is a directory under the `pants_physical_workdir_base`
    that is unique to each working copy (via including the entire path to the working copy in its
    name using `safe_filename_from_path`).
    """
    workdir_src = global_options.pants_workdir
    if not global_options.pants_physical_workdir_base:
        safe_mkdir(workdir_src)
        return workdir_src

    workdir_base = global_options.pants_physical_workdir_base
    workdir_dst = os.path.join(workdir_base,
                               safe_filename_from_path(workdir_src))

    def create_symlink_to_clean_workdir():
        # Executed when no link exists. We treat this as equivalent to a request to have deleted
        # this state. Operations like `clean-all` will already have purged the destination, but in
        # cases like manual removal of the symlink, we want to treat the case as equivalent.
        safe_mkdir(workdir_dst, clean=True)
        absolute_symlink(workdir_dst, workdir_src)

    if not os.path.lexists(workdir_src):
        # Does not exist.
        create_symlink_to_clean_workdir()
    elif os.path.islink(workdir_src):
        if os.readlink(workdir_src) != workdir_dst:
            # Exists but is incorrect.
            os.unlink(workdir_src)
            create_symlink_to_clean_workdir()
        else:
            # Exists and is correct: ensure that the destination exists.
            safe_mkdir(workdir_dst)
    else:
        safe_rmtree(workdir_src)
        absolute_symlink(workdir_dst, workdir_src)
    return workdir_src
예제 #9
0
 def _create_and_check_link(self, source: str, link: str) -> None:
     absolute_symlink(source, link)
     self.assertTrue(os.path.islink(link))
     self.assertEqual(source, os.readlink(link))
예제 #10
0
 def _create_and_check_link(self, source, link):
     absolute_symlink(source, link)
     self.assertTrue(os.path.islink(link))
     self.assertEquals(source, os.readlink(link))
예제 #11
0
 def _create_and_check_link(self, source, link):
   absolute_symlink(source, link)
   self.assertTrue(os.path.islink(link))
   self.assertEquals(source, os.readlink(link))
예제 #12
0
 def _create_and_check_link(self, source: str, link: str) -> None:
     absolute_symlink(source, link)
     assert os.path.islink(link)
     assert source == os.readlink(link)