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

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

from contextlib import closing, contextmanager
import os
import subprocess

import posixpath
from twitter.common import log
from twitter.common.collections import OrderedSet
from twitter.common.contextutil import temporary_file
from twitter.common.dirutil import chmod_plus_x, safe_delete, safe_open
from twitter.common.lang import Compatibility


if Compatibility.PY3:
  import urllib.request as urllib_request
  import urllib.error as urllib_error
else:
  import urllib2 as urllib_request
  import urllib2 as urllib_error

from pants.base.config import Config
from pants.base.exceptions import TaskError


_ID_BY_OS = {
  'linux': lambda release, machine: ('linux', machine),
  'darwin': lambda release, machine: ('darwin', release.split('.')[0]),
}

_PATH_BY_ID = {
  ('linux', 'x86_64'):  ['linux', 'x86_64'],
  ('linux', 'amd64'):   ['linux', 'x86_64'],
  ('linux', 'i386'):    ['linux', 'i386'],
  ('darwin', '9'):      ['mac', '10.5'],
  ('darwin', '10'):     ['mac', '10.6'],
  ('darwin', '11'):     ['mac', '10.7'],
  ('darwin', '12'):     ['mac', '10.8'],
  ('darwin', '13'):     ['mac', '10.9'],
}


class BinaryUtil(object):
  """Wraps utility methods for finding binary executables."""

  class MissingMachineInfo(TaskError):
    """Indicates that pants was unable to map this machine's OS to a binary path prefix."""

  class BinaryNotFound(TaskError):
    def __init__(self, binary, accumulated_errors):
      super(BinaryNotFound, self).__init__(
          'Failed to fetch binary {binary} from any source: ({sources})'
          .format(binary=binary, sources=', '.join(accumulated_errors)))

  class NoBaseUrlsError(TaskError):
    """Indicates that no urls were specified in pants.ini."""

  def __init__(self, bootstrap_dir=None, baseurls=None, timeout=None, config=None,
               binary_base_path_strategy=None):
    """Creates a BinaryUtil with the given settings to define binary lookup behavior.

    Relevant settings may either be specified in the arguments, or will be loaded from the given
    config file.
    :param bootstrap_dir: Directory search for binaries in, or download binaries to if needed.
      Defaults to the value of 'pants_bootstrapdir' in config if unspecified.
    :param baseurls: List of url prefixes which represent repositories of binaries. Defaults to the<commit_msg>This is a fix for issue #367<commit_after># coding=utf-8
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

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

from contextlib import closing, contextmanager
import os
import subprocess

import posixpath
from twitter.common import log
from twitter.common.collections import OrderedSet
from twitter.common.contextutil import temporary_file
from twitter.common.dirutil import chmod_plus_x, safe_delete, safe_open
from twitter.common.lang import Compatibility


if Compatibility.PY3:
  import urllib.request as urllib_request
  import urllib.error as urllib_error
else:
  import urllib2 as urllib_request
  import urllib2 as urllib_error

from pants.base.config import Config
from pants.base.exceptions import TaskError


_ID_BY_OS = {
  'linux': lambda release, machine: ('linux', machine),
  'darwin': lambda release, machine: ('darwin', release.split('.')[0]),
}

_PATH_BY_ID = {
  ('linux', 'x86_64'):  ['linux', 'x86_64'],
  ('linux', 'amd64'):   ['linux', 'x86_64'],
  ('linux', 'i386'):    ['linux', 'i386'],
  ('darwin', '9'):      ['mac', '10.5'],
  ('darwin', '10'):     ['mac', '10.6'],
  ('darwin', '11'):     ['mac', '10.7'],
  ('darwin', '12'):     ['mac', '10.8'],
  ('darwin', '13'):     ['mac', '10.9'],
}


class BinaryUtil(object):
  """Wraps utility methods for finding binary executables."""

  class MissingMachineInfo(TaskError):
    """Indicates that pants was unable to map this machine's OS to a binary path prefix."""

  class BinaryNotFound(TaskError):
    def __init__(self, binary, accumulated_errors):
      super(BinaryUtil.BinaryNotFound, self).__init__(
          'Failed to fetch binary {binary} from any source: ({sources})'
          .format(binary=binary, sources=', '.join(accumulated_errors)))

  class NoBaseUrlsError(TaskError):
    """Indicates that no urls were specified in pants.ini."""

  def __init__(self, bootstrap_dir=None, baseurls=None, timeout=None, config=None,
               binary_base_path_strategy=None):
    """Creates a BinaryUtil with the given settings to define binary lookup behavior.

    Relevant settings may either be specified in the arguments, or will be loaded from the given
    config file.
    :param bootstrap_dir: Directory search for binaries in, or download binaries to if needed.
      Defaults to the value of 'pants_bootstrapdir' in config if unspecified.
    :param baseurls: List of url prefixes which represent repositories of binaries. Defaults to the
{'fraction_non_alphanumeric': 0.1176027139087825, 'fraction_numerical': 0.021296645307199397, 'mean_word_length': 4.317635270541082, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2246514', 'n_tokens_mistral': 1661, 'n_tokens_neox': 1542, 'n_words': 533}