github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/repository/trusty/haproxy/cm.py (about)

     1  # Copyright 2010-2013 Canonical Ltd. All rights reserved.
     2  import os
     3  import re
     4  import sys
     5  import errno
     6  import hashlib
     7  import subprocess
     8  import optparse
     9  
    10  from os import curdir
    11  from bzrlib.branch import Branch
    12  from bzrlib.plugin import load_plugins
    13  load_plugins()
    14  from bzrlib.plugins.launchpad import account as lp_account
    15  
    16  if 'GlobalConfig' in dir(lp_account):
    17      from bzrlib.config import LocationConfig as LocationConfiguration
    18      _ = LocationConfiguration
    19  else:
    20      from bzrlib.config import LocationStack as LocationConfiguration
    21      _ = LocationConfiguration
    22  
    23  
    24  def get_branch_config(config_file):
    25      """
    26      Retrieves the sourcedeps configuration for an source dir.
    27      Returns a dict of (branch, revspec) tuples, keyed by branch name.
    28      """
    29      branches = {}
    30      with open(config_file, 'r') as stream:
    31          for line in stream:
    32              line = line.split('#')[0].strip()
    33              bzr_match = re.match(r'(\S+)\s+'
    34                                   'lp:([^;]+)'
    35                                   '(?:;revno=(\d+))?', line)
    36              if bzr_match:
    37                  name, branch, revno = bzr_match.group(1, 2, 3)
    38                  if revno is None:
    39                      revspec = -1
    40                  else:
    41                      revspec = revno
    42                  branches[name] = (branch, revspec)
    43                  continue
    44              dir_match = re.match(r'(\S+)\s+'
    45                                   '\(directory\)', line)
    46              if dir_match:
    47                  name = dir_match.group(1)
    48                  branches[name] = None
    49      return branches
    50  
    51  
    52  def main(config_file, parent_dir, target_dir, verbose):
    53      """Do the deed."""
    54  
    55      try:
    56          os.makedirs(parent_dir)
    57      except OSError, e:
    58          if e.errno != errno.EEXIST:
    59              raise
    60  
    61      branches = sorted(get_branch_config(config_file).items())
    62      for branch_name, spec in branches:
    63          if spec is None:
    64              # It's a directory, just create it and move on.
    65              destination_path = os.path.join(target_dir, branch_name)
    66              if not os.path.isdir(destination_path):
    67                  os.makedirs(destination_path)
    68              continue
    69  
    70          (quoted_branch_spec, revspec) = spec
    71          revno = int(revspec)
    72  
    73          # qualify mirror branch name with hash of remote repo path to deal
    74          # with changes to the remote branch URL over time
    75          branch_spec_digest = hashlib.sha1(quoted_branch_spec).hexdigest()
    76          branch_directory = branch_spec_digest
    77  
    78          source_path = os.path.join(parent_dir, branch_directory)
    79          destination_path = os.path.join(target_dir, branch_name)
    80  
    81          # Remove leftover symlinks/stray files.
    82          try:
    83              os.remove(destination_path)
    84          except OSError, e:
    85              if e.errno != errno.EISDIR and e.errno != errno.ENOENT:
    86                  raise
    87  
    88          lp_url = "lp:" + quoted_branch_spec
    89  
    90          # Create the local mirror branch if it doesn't already exist
    91          if verbose:
    92              sys.stderr.write('%30s: ' % (branch_name,))
    93              sys.stderr.flush()
    94  
    95          fresh = False
    96          if not os.path.exists(source_path):
    97              subprocess.check_call(['bzr', 'branch', '-q', '--no-tree',
    98                                     '--', lp_url, source_path])
    99              fresh = True
   100  
   101          if not fresh:
   102              source_branch = Branch.open(source_path)
   103              if revno == -1:
   104                  orig_branch = Branch.open(lp_url)
   105                  fresh = source_branch.revno() == orig_branch.revno()
   106              else:
   107                  fresh = source_branch.revno() == revno
   108  
   109          # Freshen the source branch if required.
   110          if not fresh:
   111              subprocess.check_call(['bzr', 'pull', '-q', '--overwrite', '-r',
   112                                     str(revno), '-d', source_path,
   113                                     '--', lp_url])
   114  
   115          if os.path.exists(destination_path):
   116              # Overwrite the destination with the appropriate revision.
   117              subprocess.check_call(['bzr', 'clean-tree', '--force', '-q',
   118                                     '--ignored', '-d', destination_path])
   119              subprocess.check_call(['bzr', 'pull', '-q', '--overwrite',
   120                                     '-r', str(revno),
   121                                     '-d', destination_path, '--', source_path])
   122          else:
   123              # Create a new branch.
   124              subprocess.check_call(['bzr', 'branch', '-q', '--hardlink',
   125                                     '-r', str(revno),
   126                                     '--', source_path, destination_path])
   127  
   128          # Check the state of the destination branch.
   129          destination_branch = Branch.open(destination_path)
   130          destination_revno = destination_branch.revno()
   131  
   132          if verbose:
   133              sys.stderr.write('checked out %4s of %s\n' %
   134                               ("r" + str(destination_revno), lp_url))
   135              sys.stderr.flush()
   136  
   137          if revno != -1 and destination_revno != revno:
   138              raise RuntimeError("Expected revno %d but got revno %d" %
   139                                 (revno, destination_revno))
   140  
   141  if __name__ == '__main__':
   142      parser = optparse.OptionParser(
   143          usage="%prog [options]",
   144          description=(
   145              "Add a lightweight checkout in <target> for each "
   146              "corresponding file in <parent>."),
   147          add_help_option=False)
   148      parser.add_option(
   149          '-p', '--parent', dest='parent',
   150          default=None,
   151          help=("The directory of the parent tree."),
   152          metavar="DIR")
   153      parser.add_option(
   154          '-t', '--target', dest='target', default=curdir,
   155          help=("The directory of the target tree."),
   156          metavar="DIR")
   157      parser.add_option(
   158          '-c', '--config', dest='config', default=None,
   159          help=("The config file to be used for config-manager."),
   160          metavar="DIR")
   161      parser.add_option(
   162          '-q', '--quiet', dest='verbose', action='store_false',
   163          help="Be less verbose.")
   164      parser.add_option(
   165          '-v', '--verbose', dest='verbose', action='store_true',
   166          help="Be more verbose.")
   167      parser.add_option(
   168          '-h', '--help', action='help',
   169          help="Show this help message and exit.")
   170      parser.set_defaults(verbose=True)
   171  
   172      options, args = parser.parse_args()
   173  
   174      if options.parent is None:
   175          options.parent = os.environ.get(
   176              "SOURCEDEPS_DIR",
   177              os.path.join(curdir, ".sourcecode"))
   178  
   179      if options.target is None:
   180          parser.error(
   181              "Target directory not specified.")
   182  
   183      if options.config is None:
   184          config = [arg for arg in args
   185                    if arg != "update"]
   186          if not config or len(config) > 1:
   187              parser.error("Config not specified")
   188          options.config = config[0]
   189  
   190      sys.exit(main(config_file=options.config,
   191                    parent_dir=options.parent,
   192                    target_dir=options.target,
   193                    verbose=options.verbose))