<gh_stars>0
# coding=utf-8
# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
                        unicode_literals, with_statement)

import logging
import os
import shutil
from contextlib import closing

import six.moves.urllib.error as urllib_error
import six.moves.urllib.parse as urllib_parse
import six.moves.urllib.request as urllib_request
from pants.base.exceptions import TaskError
from pants.fs.archive import archiver_for_path
from pants.subsystem.subsystem import Subsystem
from pants.util.contextutil import temporary_dir
from pants.util.dirutil import safe_open

from pants.contrib.node.subsystems.resolvers.node_resolver_base import NodeResolverBase
from pants.contrib.node.targets.node_preinstalled_module import NodePreinstalledModule
from pants.contrib.node.tasks.node_resolve import NodeResolve


logger = logging.getLogger(__name__)


class NodePreinstalledModuleResolver(Subsystem, NodeResolverBase):
  options_scope = 'node-preinstalled-module-resolver'

  @classmethod
  def register_options(cls, register):
    super(NodePreinstalledModuleResolver, cls).register_options(register)
    NodeResolve.register_resolver_for_type(NodePreinstalledModule, cls)

  def resolve_target(self, node_task, target, results_dir, node_paths):
    self._copy_sources(target, results_dir)

    with temporary_dir() as temp_dir:
      archive_file_name = urllib_parse.urlsplit(target.dependencies_archive_url).path.split('/')[-1]
      if not archive_file_name:
        raise TaskError('Could not determine archive file name for {target} from {url}'
                        .format(target=target.address.reference(),
                                url=target.dependencies_archive_url))

      download_path = os.path.join(temp_dir, archive_file_name)

      logger.info('Downloading archive {archive_file_name} from '
                  '{dependencies_archive_url} to {path}'
                  .format(archive_file_name=archive_file_name,
                          dependencies_archive_url=target.dependencies_archive_url,
                          path=download_path))

      try:
        with closing(urllib_request.urlopen(target.dependencies_archive_url)) as opened_archive_url:
          with safe_open(download_path, 'wb') as downloaded_archive:
            downloaded_archive.write(opened_archive_url.read())
      except (IOError, urllib_error.HTTPError, urllib_error.URLError, ValueError) as error:
        raise TaskError('Failed to fetch preinstalled node_modules for {target} from '
                        '{dependencies_archive_url}: {error}'
                        .format(target=target.address.reference(),
                                url=target.dependencies_archive_url, error=error))

      logger.info('Fetched archive {archive_file_name} from {dependencies_archive_url} to {path}'
                  .format(archive_file_name=archive_file_name,
                          dependencies_archive_url=target.dependencies_archive_url,
                          path=download_path))

      archiver_for_path(archive_file_name).extract(download_path, temp_dir)

      extracted_node_modules = os.path.join(temp_dir, 'node_modules')
      if not os.path.isdir(extracted_node_modules):
        raise TaskError('Did not find an extracted node_modules directory for {target} '
                        'inside {dependencies_archive_url}'
                        .format(target=target.address.reference(),
                                dependencies_archive_url=target.dependencies_archive_url))

      shutil.move(extracted_node_modules, os.path.join(results_dir, 'node_modules'))

# coding=utf-8
# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
                        unicode_literals, with_statement)

import logging
import os
import shutil
from contextlib import closing

import six.moves.urllib.error as urllib_error
import six.moves.urllib.parse as urllib_parse
import six.moves.urllib.request as urllib_request
from pants.base.exceptions import TaskError
from pants.fs.archive import archiver_for_path
from pants.subsystem.subsystem import Subsystem
from pants.util.contextutil import temporary_dir
from pants.util.dirutil import safe_open

from pants.contrib.node.subsystems.resolvers.node_resolver_base import NodeResolverBase
from pants.contrib.node.targets.node_preinstalled_module import NodePreinstalledModule
from pants.contrib.node.tasks.node_resolve import NodeResolve


logger = logging.getLogger(__name__)


class NodePreinstalledModuleResolver(Subsystem, NodeResolverBase):
  options_scope = 'node-preinstalled-module-resolver'

  @classmethod
  def register_options(cls, register):
    super(NodePreinstalledModuleResolver, cls).register_options(register)
    NodeResolve.register_resolver_for_type(NodePreinstalledModule, cls)

  def resolve_target(self, node_task, target, results_dir, node_paths):
    self._copy_sources(target, results_dir)

    with temporary_dir() as temp_dir:
      archive_file_name = urllib_parse.urlsplit(target.dependencies_archive_url).path.split('/')[-1]
      if not archive_file_name:
        raise TaskError('Could not determine archive file name for {target} from {url}'
                        .format(target=target.address.reference(),
                                url=target.dependencies_archive_url))

      download_path = os.path.join(temp_dir, archive_file_name)

      logger.info('Downloading archive {archive_file_name} from '
                  '{dependencies_archive_url} to {path}'
                  .format(archive_file_name=archive_file_name,
                          dependencies_archive_url=target.dependencies_archive_url,
                          path=download_path))

      try:
        with closing(urllib_request.urlopen(target.dependencies_archive_url)) as opened_archive_url:
          with safe_open(download_path, 'wb') as downloaded_archive:
            downloaded_archive.write(opened_archive_url.read())
      except (IOError, urllib_error.HTTPError, urllib_error.URLError, ValueError) as error:
        raise TaskError('Failed to fetch preinstalled node_modules for {target} from '
                        '{dependencies_archive_url}: {error}'
                        .format(target=target.address.reference(),
                                url=target.dependencies_archive_url, error=error))

      logger.info('Fetched archive {archive_file_name} from {dependencies_archive_url} to {path}'
                  .format(archive_file_name=archive_file_name,
                          dependencies_archive_url=target.dependencies_archive_url,
                          path=download_path))

      archiver_for_path(archive_file_name).extract(download_path, temp_dir)

      extracted_node_modules = os.path.join(temp_dir, 'node_modules')
      if not os.path.isdir(extracted_node_modules):
        raise TaskError('Did not find an extracted node_modules directory for {target} '
                        'inside {dependencies_archive_url}'
                        .format(target=target.address.reference(),
                                dependencies_archive_url=target.dependencies_archive_url))

      shutil.move(extracted_node_modules, os.path.join(results_dir, 'node_modules'))
# coding=utf-8 # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE).