# Path: alibuild_helpers/cmd.py
# def execute(command, printer=debug):
#   kwargs = {} if sys.version_info.major < 3 else {"encoding": "utf-8"}
#   popen = Popen(command, shell=is_string(command), stdout=PIPE,
#                 universal_newlines=True, **kwargs)
#   lines_iterator = iter(popen.stdout.readline, "")
#   for line in lines_iterator:
#     if not line: break
#     printer("%s", line.strip("\n"))
#   out = popen.communicate()[0].strip("\n")
#   if out:
#     printer(out)
#   return popen.returncode
# 
# Path: alibuild_helpers/log.py
# def dieOnError(err, msg):
#   def __init__(self, fmtstr):
#   def format(self, record):
#   def __init__(self, begin_msg=""):
#   def __call__(self, txt, *args):
#   def erase(self):
#   def end(self, msg="", error=False):
# def log_banner(self, message, *args, **kws):
# def log_success(self, message, *args, **kws):
# class LogFormatter(logging.Formatter):
# class ProgressPrint:
# 
# Path: alibuild_helpers/utilities.py
# def format(s, **kwds):
#   if sys.version_info[0] >= 3:
#     if isinstance(s, bytes):
#       try:
#         s = s.decode("utf-8")  # to get newlines as such and not as escaped \n
#       except:
#         s = s.decode("latin-1")  # Workaround issue with some special characters of latin-1 which are not understood by unicode
#     else:
#       s = str(s)
#   elif isinstance(s, str):
#     s = unicode(s, "utf-8")  # utf-8 is a safe assumption
#   elif not isinstance(s, unicode):
#     s = unicode(str(s))
#   return s % kwds
# 
# def star():
#   return re.sub("build.*$", "", basename(sys.argv[0]).lower())
# 
# def resolve_store_path(architecture, spec_hash):
#   """Return the path where a tarball with the given hash is to be stored.
# 
#   The returned path is relative to the working directory (normally sw/) or the
#   root of the remote store.
#   """
#   return "/".join(("TARS", architecture, "store", spec_hash[:2], spec_hash))
# 
# def resolve_links_path(architecture, package):
#   """Return the path where symlinks for the given package are to be stored.
# 
#   The returned path is relative to the working directory (normally sw/) or the
#   root of the remote store.
#   """
#   return "/".join(("TARS", architecture, package))


import glob
import os
import os.path
import re
import sys
import time
import requests
      import boto3
from requests.exceptions import RequestException
from alibuild_helpers.cmd import execute
from alibuild_helpers.log import debug, warning, error, dieOnError
from alibuild_helpers.utilities import format, star, resolve_store_path, resolve_links_path
    from botocore.exceptions import ClientError
    from botocore.exceptions import ClientError
  As boto3 doesn't support Python 2, this class can only be used under Python
  3. boto3 is only imported at __init__ time, so if this class is never
  instantiated, boto3 doesn't have to be installed.

  This class has the advantage over S3RemoteSync that it uses the same
  connection to S3 every time, while s3cmd must establish a new connection each
  time.
  """

  def __init__(self, remoteStore, writeStore, architecture, workdir):
    self.remoteStore = re.sub("^b3://", "", remoteStore)
    self.writeStore = re.sub("^b3://", "", writeStore)
    self.architecture = architecture
    self.workdir = workdir
    self._s3_init()

  def _s3_init(self):
    # This is a separate method so that we can patch it out for unit tests.
    # Import boto3 here, so that if we don't use this remote store, we don't
    # have to install it in the first place.
    try:
    except ImportError:
      error("boto3 must be installed to use %s", Boto3RemoteSync)
      sys.exit(1)

    try:
      self.s3 = boto3.client("s3", endpoint_url="https://s3.cern.ch",
                             aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
                             aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"])
    except KeyError:

# Path: alibuild_helpers/cmd.py
# def execute(command, printer=debug):
#   kwargs = {} if sys.version_info.major < 3 else {"encoding": "utf-8"}
#   popen = Popen(command, shell=is_string(command), stdout=PIPE,
#                 universal_newlines=True, **kwargs)
#   lines_iterator = iter(popen.stdout.readline, "")
#   for line in lines_iterator:
#     if not line: break
#     printer("%s", line.strip("\n"))
#   out = popen.communicate()[0].strip("\n")
#   if out:
#     printer(out)
#   return popen.returncode
# 
# Path: alibuild_helpers/log.py
# def dieOnError(err, msg):
#   def __init__(self, fmtstr):
#   def format(self, record):
#   def __init__(self, begin_msg=""):
#   def __call__(self, txt, *args):
#   def erase(self):
#   def end(self, msg="", error=False):
# def log_banner(self, message, *args, **kws):
# def log_success(self, message, *args, **kws):
# class LogFormatter(logging.Formatter):
# class ProgressPrint:
# 
# Path: alibuild_helpers/utilities.py
# def format(s, **kwds):
#   if sys.version_info[0] >= 3:
#     if isinstance(s, bytes):
#       try:
#         s = s.decode("utf-8")  # to get newlines as such and not as escaped \n
#       except:
#         s = s.decode("latin-1")  # Workaround issue with some special characters of latin-1 which are not understood by unicode
#     else:
#       s = str(s)
#   elif isinstance(s, str):
#     s = unicode(s, "utf-8")  # utf-8 is a safe assumption
#   elif not isinstance(s, unicode):
#     s = unicode(str(s))
#   return s % kwds
# 
# def star():
#   return re.sub("build.*$", "", basename(sys.argv[0]).lower())
# 
# def resolve_store_path(architecture, spec_hash):
#   """Return the path where a tarball with the given hash is to be stored.
# 
#   The returned path is relative to the working directory (normally sw/) or the
#   root of the remote store.
#   """
#   return "/".join(("TARS", architecture, "store", spec_hash[:2], spec_hash))
# 
# def resolve_links_path(architecture, package):
#   """Return the path where symlinks for the given package are to be stored.
# 
#   The returned path is relative to the working directory (normally sw/) or the
#   root of the remote store.
#   """
#   return "/".join(("TARS", architecture, package))


# Path: alibuild_helpers/sync.py
import glob
import os
import os.path
import re
import sys
import time
import requests
      import boto3
from requests.exceptions import RequestException
from alibuild_helpers.cmd import execute
from alibuild_helpers.log import debug, warning, error, dieOnError
from alibuild_helpers.utilities import format, star, resolve_store_path, resolve_links_path
    from botocore.exceptions import ClientError
    from botocore.exceptions import ClientError

  As boto3 doesn't support Python 2, this class can only be used under Python
  3. boto3 is only imported at __init__ time, so if this class is never
  instantiated, boto3 doesn't have to be installed.

  This class has the advantage over S3RemoteSync that it uses the same
  connection to S3 every time, while s3cmd must establish a new connection each
  time.
  """

  def __init__(self, remoteStore, writeStore, architecture, workdir):
    self.remoteStore = re.sub("^b3://", "", remoteStore)
    self.writeStore = re.sub("^b3://", "", writeStore)
    self.architecture = architecture
    self.workdir = workdir
    self._s3_init()

  def _s3_init(self):
    # This is a separate method so that we can patch it out for unit tests.
    # Import boto3 here, so that if we don't use this remote store, we don't
    # have to install it in the first place.
    try:
    except ImportError:
      error("boto3 must be installed to use %s", Boto3RemoteSync)
      sys.exit(1)

    try:
      self.s3 = boto3.client("s3", endpoint_url="https://s3.cern.ch",
                             aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
                             aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"])
    except KeyError:

      error("you must pass the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY env "