Exemplo n.º 1
0
    def test_safe_temp_edit(self):
        content = b'hello'

        with temporary_file() as temp_file:
            temp_file.write(content)
            temp_file.close()

            with open(temp_file.name, 'rb') as f:
                self.assertEqual(content, f.read())

            temp_content = b'hello world'
            with safe_temp_edit(temp_file.name) as temp_edit_file:
                with open(temp_edit_file, 'wb') as t_f:
                    t_f.write(temp_content)

                # Make sure the edit is actually happening in temp_file
                with open(temp_file.name, 'rb') as f:
                    self.assertEqual(temp_content, f.read())

            # Test that temp_file has been safely recovered.
            with open(temp_file.name, 'rb') as f:
                self.assertEqual(content, f.read())
Exemplo n.º 2
0
  def test_safe_temp_edit(self):
    content = b'hello'

    with temporary_file() as temp_file:
      temp_file.write(content)
      temp_file.close()

      with open(temp_file.name, 'rb') as f:
        self.assertEqual(content, f.read())

      temp_content = b'hello world'
      with safe_temp_edit(temp_file.name) as temp_edit_file:
        with open(temp_edit_file, 'wb') as t_f:
          t_f.write(temp_content)

        # Make sure the edit is actually happening in temp_file
        with open(temp_file.name, 'rb') as f:
          self.assertEqual(temp_content, f.read())

      # Test that temp_file has been safely recovered.
      with open(temp_file.name, 'rb') as f:
        self.assertEqual(content, f.read())
Exemplo n.º 3
0
    def resolve_target(self,
                       node_task,
                       target,
                       results_dir,
                       node_paths,
                       resolve_locally=False,
                       install_optional=None,
                       production_only=None,
                       force=None,
                       frozen_lockfile=None,
                       **kwargs):
        """Installs the node_package target in the results directory copying sources if necessary.

    :param Task node_task: The task executing this method.
    :param Target target: The target being resolve.
    :param String results_dir: The output location where this target will be resolved.
    :param NodePaths node_paths: A mapping of targets and their resolved location, if resolved.
    :param Boolean resolve_locally: If true, the sources do not have to be copied.
    :param Boolean install_optional: If true, install optional dependencies.
    :param Boolean force: If true, rebuild dependencies even if already built.
    :param Boolean frozen_lockfile: Preserve lock file and fails if a change is detected.
    """
        if self.get_options().force_option_override:
            install_optional = self.get_options().install_optional
            production_only = self.get_options().install_production
            force = self.get_options().force
            frozen_lockfile = self.get_options().frozen_lockfile
        else:
            install_optional = install_optional if install_optional is not None else self.get_options(
            ).install_optional
            production_only = production_only if production_only is not None else self.get_options(
            ).install_production
            force = force if force is not None else self.get_options().force
            frozen_lockfile = frozen_lockfile if frozen_lockfile is not None else self.get_options(
            ).frozen_lockfile

        if not resolve_locally:
            self._copy_sources(target, results_dir)
        with pushd(results_dir):
            if not os.path.exists('package.json'):
                raise TaskError(
                    'Cannot find package.json. Did you forget to put it in target sources?'
                )
            # TODO: remove/remodel the following section when node_module dependency is fleshed out.
            package_manager = node_task.get_package_manager(target=target).name
            if package_manager == PACKAGE_MANAGER_NPM:
                if resolve_locally:
                    raise TaskError(
                        'Resolving node package modules locally is not supported for NPM.'
                    )
                if os.path.exists('npm-shrinkwrap.json'):
                    node_task.context.log.info(
                        'Found npm-shrinkwrap.json, will not inject package.json'
                    )
                else:
                    node_task.context.log.warn(
                        'Cannot find npm-shrinkwrap.json. Did you forget to put it in target sources? '
                        'This package will fall back to inject package.json with pants BUILD dependencies '
                        'including node_remote_module and other node dependencies. However, this is '
                        'not fully supported.')
                    self._emit_package_descriptor(node_task, target,
                                                  results_dir, node_paths)
            elif package_manager == PACKAGE_MANAGER_YARNPKG:
                if not os.path.exists('yarn.lock') and frozen_lockfile:
                    raise TaskError(
                        'Cannot find yarn.lock. Did you forget to put it in target sources?'
                    )
            # Install all dependencies except for `file:` dependencies
            # `file:` dependencies are special dependencies that point to a local path to a pants node target
            # `file:` dependencies are already in the build graph and should be already be installed by this point

            # Copy the package.json and then remove the file: dependencies from package.json
            # Run the install and symlink the file: dependencies using their node_paths
            # Afterwards, restore the original package.json to not cause diff changes when resolve_locally=True
            # The file mutation is occuring in place and the package.json may potentially not be restored here
            # if the process is closed.
            with safe_temp_edit('package.json') as package_json:
                with open(package_json, 'r') as package_json_file:
                    json_data = json.load(package_json_file)
                    source_deps = {
                        k: v
                        for k, v in json_data.get('dependencies', {}).items()
                        if self.parse_file_path(v)
                    }
                    third_party_deps = {
                        k: v
                        for k, v in json_data.get('dependencies', {}).items()
                        if not self.parse_file_path(v)
                    }
                    json_data['dependencies'] = third_party_deps

                # TODO(6489): Currently the file: dependencies need to be duplicated in BUILD.
                # After this issue is closed, only dependencies need to be specified in package.json
                for package_name, file_path in source_deps.items():
                    if self._get_target_from_package_name(
                            target, package_name, file_path) is None:
                        raise TaskError(
                            'Local dependency in package.json not found in the build graph. '
                            'Check your BUILD file for missing dependencies. ["{}": {}]'
                            .format(package_name, file_path))
                mode = 'w' if PY3 else 'wb'
                with open(package_json, mode) as package_json_file:
                    json.dump(json_data,
                              package_json_file,
                              indent=2,
                              separators=(',', ': '))
                result, command = node_task.install_module(
                    target=target,
                    install_optional=install_optional,
                    production_only=production_only,
                    force=force,
                    frozen_lockfile=frozen_lockfile,
                    workunit_name=target.address.reference(),
                    workunit_labels=[WorkUnitLabel.COMPILER])
                if result != 0:
                    raise TaskError(
                        'Failed to resolve dependencies for {}:\n\t{} failed with exit code {}'
                        .format(target.address.reference(), command, result))
                if source_deps:
                    self._link_source_dependencies(node_task, target,
                                                   results_dir, node_paths,
                                                   source_deps)
Exemplo n.º 4
0
  def resolve_target(self, node_task, target, results_dir, node_paths, resolve_locally=False,
                     install_optional=None, production_only=None, force=None, frozen_lockfile=None,
                     **kwargs):
    """Installs the node_package target in the results directory copying sources if necessary.

    :param Task node_task: The task executing this method.
    :param Target target: The target being resolve.
    :param String results_dir: The output location where this target will be resolved.
    :param NodePaths node_paths: A mapping of targets and their resolved location, if resolved.
    :param Boolean resolve_locally: If true, the sources do not have to be copied.
    :param Boolean install_optional: If true, install optional dependencies.
    :param Boolean force: If true, rebuild dependencies even if already built.
    :param Boolean frozen_lockfile: Preserve lock file and fails if a change is detected.
    """
    if self.get_options().force_option_override:
      install_optional = self.get_options().install_optional
      production_only = self.get_options().install_production
      force = self.get_options().force
      frozen_lockfile = self.get_options().frozen_lockfile
    else:
      install_optional = install_optional if install_optional is not None else self.get_options().install_optional
      production_only = production_only if production_only is not None else self.get_options().install_production
      force = force if force is not None else self.get_options().force
      frozen_lockfile = frozen_lockfile if frozen_lockfile is not None else self.get_options().frozen_lockfile

    if not resolve_locally:
      self._copy_sources(target, results_dir)
    with pushd(results_dir):
      if not os.path.exists('package.json'):
        raise TaskError(
          'Cannot find package.json. Did you forget to put it in target sources?')
      # TODO: remove/remodel the following section when node_module dependency is fleshed out.
      package_manager = node_task.get_package_manager(target=target).name
      if package_manager == PACKAGE_MANAGER_NPM:
        if resolve_locally:
          raise TaskError('Resolving node package modules locally is not supported for NPM.')
        if os.path.exists('npm-shrinkwrap.json'):
          node_task.context.log.info('Found npm-shrinkwrap.json, will not inject package.json')
        else:
          node_task.context.log.warn(
            'Cannot find npm-shrinkwrap.json. Did you forget to put it in target sources? '
            'This package will fall back to inject package.json with pants BUILD dependencies '
            'including node_remote_module and other node dependencies. However, this is '
            'not fully supported.')
          self._emit_package_descriptor(node_task, target, results_dir, node_paths)
      elif package_manager == PACKAGE_MANAGER_YARNPKG:
        if not os.path.exists('yarn.lock') and frozen_lockfile:
          raise TaskError(
            'Cannot find yarn.lock. Did you forget to put it in target sources?')
      # Install all dependencies except for `file:` dependencies
      # `file:` dependencies are special dependencies that point to a local path to a pants node target
      # `file:` dependencies are already in the build graph and should be already be installed by this point

      # Copy the package.json and then remove the file: dependencies from package.json
      # Run the install and symlink the file: dependencies using their node_paths
      # Afterwards, restore the original package.json to not cause diff changes when resolve_locally=True
      # The file mutation is occuring in place and the package.json may potentially not be restored here
      # if the process is closed.
      with safe_temp_edit('package.json') as package_json:
        with open(package_json, 'r') as package_json_file:
          json_data = json.load(package_json_file)
          source_deps = { k : v for k,v in json_data.get('dependencies', {}).items() if self.parse_file_path(v)}
          third_party_deps = { k : v for k,v in json_data.get('dependencies', {}).items() if not self.parse_file_path(v)}
          json_data['dependencies'] = third_party_deps

        # TODO(6489): Currently the file: dependencies need to be duplicated in BUILD.
        # After this issue is closed, only dependencies need to be specified in package.json
        for package_name, file_path in source_deps.items():
          if self._get_target_from_package_name(target, package_name, file_path) is None:
            raise TaskError('Local dependency in package.json not found in the build graph. '
                            'Check your BUILD file for missing dependencies. ["{}": {}]'.format(package_name, file_path))
        mode = 'w' if PY3 else 'wb'
        with open(package_json, mode) as package_json_file:
          json.dump(json_data, package_json_file, indent=2, separators=(',', ': '))
        result, command = node_task.install_module(
          target=target, install_optional=install_optional,
          production_only=production_only, force=force, frozen_lockfile=frozen_lockfile,
          workunit_name=target.address.reference(),
          workunit_labels=[WorkUnitLabel.COMPILER])
        if result != 0:
          raise TaskError('Failed to resolve dependencies for {}:\n\t{} failed with exit code {}'
                          .format(target.address.reference(), command, result))
        if source_deps:
          self._link_source_dependencies(node_task, target, results_dir, node_paths, source_deps)