<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Just out of curiosity: what's your definition of "<tt>real world</tt>"?<br>
    Pavel<br>
    <br>
    <div class="moz-cite-prefix">On 3/13/18 03:49, CCTBX commit wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:20180313105128.25F551019EB@g18-sc-serv-04.diamond.ac.uk"><tt>Repository
        : <a class="moz-txt-link-freetext" href="ssh://g18-sc-serv-04.diamond.ac.uk/cctbx">ssh://g18-sc-serv-04.diamond.ac.uk/cctbx</a><br>
        On branch  : master<br>
        <br>
        <hr><br>
        <br>
        commit 914c74bf195b5e5d4fa2c4145da3e5f89c7e5872<br>
        Author: Markus Gerstel <a class="moz-txt-link-rfc2396E" href="mailto:markus.gerstel@diamond.ac.uk">&lt;markus.gerstel@diamond.ac.uk&gt;</a><br>
        Date:   Tue Mar 13 10:43:22 2018 +0000<br>
        <br>
            New command: libtbx.install<br>
            <br>
            This downloads and configures from a select list of
        cctbx/libtbxish<br>
            modules in a similar manner to pip in the real world. This
        will not<br>
            update or install any libraries in the base build, but
        assuming<br>
            those libraries are present libtbx.install should work.<br>
        <br>
        <br>
        <hr><br>
        <br>
        914c74bf195b5e5d4fa2c4145da3e5f89c7e5872<br>
        libtbx/command_line/install.py | 118
        +++++++++++++++++++++++++++++++++++++++++<br>
        1 file changed, 118 insertions(+)<br>
        <br>
        diff --git a/libtbx/command_line/install.py
        b/libtbx/command_line/install.py<br>
        new file mode 100644<br>
        index 000000000..47ad94eb5<br>
        <tt style="color:#800">--- /dev/null</tt><br>
        <tt style="color:#008">+++ b/libtbx/command_line/install.py</tt><br>
        @@ -0,0 +1,118 @@<br>
        <tt style="color:#008">+from __future__ import absolute_import,
          division, print_function</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+import collections</tt><br>
        <tt style="color:#008">+import os</tt><br>
        <tt style="color:#008">+import sys</tt><br>
        <tt style="color:#008">+from optparse import SUPPRESS_HELP,
          OptionParser</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+import procrunner</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+import libtbx.load_env</tt><br>
        <tt style="color:#008">+from libtbx.auto_build.bootstrap import
          Toolbox</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+# Basically 'pip' for selected
          libtbx/cctbx modules.</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+def is_source_repository(path):</tt><br>
        <tt style="color:#008">+  return (path / '.git').isdir() or
          (path / '.svn').isdir()</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+def run(args):</tt><br>
        <tt style="color:#008">+  parser =
          OptionParser(usage="libtbx.install [package]",</tt><br>
        <tt style="color:#008">+                        description="Installs
          an additional cctbx package")</tt><br>
        <tt style="color:#008">+  parser.add_option("-?", action="help",
          help=SUPPRESS_HELP)</tt><br>
        <tt style="color:#008">+  options, args =
          parser.parse_args(args)</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+  modules_directory = list(filter(lambda
          dir: not is_source_repository(dir),
          libtbx.env.repository_paths))</tt><br>
        <tt style="color:#008">+  if not modules_directory:</tt><br>
        <tt style="color:#008">+    sys.exit("No repository path
          candidate found. Can't install modules without an installation
          root.")</tt><br>
        <tt style="color:#008">+  if len(modules_directory) &gt; 1:</tt><br>
        <tt style="color:#008">+    print("More than one repository path
          candidate found.")</tt><br>
        <tt style="color:#008">+  installation_root =
          modules_directory[0]</tt><br>
        <tt style="color:#008">+  print("Using %s as installation root"
          % abs(installation_root))</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+  packages_to_configure = set()</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+  errors = False</tt><br>
        <tt style="color:#008">+  for package in args:</tt><br>
        <tt style="color:#008">+    if (installation_root /
          package).isdir():</tt><br>
        <tt style="color:#008">+      print("Skipping package %s:
          Directory already exists in installation root" % package)</tt><br>
        <tt style="color:#008">+      errors = True</tt><br>
        <tt style="color:#008">+      continue</tt><br>
        <tt style="color:#008">+    if package not in warehouse:</tt><br>
        <tt style="color:#008">+      print("Skipping package %s: Never
          heard of this before" % package)</tt><br>
        <tt style="color:#008">+      errors = True</tt><br>
        <tt style="color:#008">+      continue</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+    downloaded = False</tt><br>
        <tt style="color:#008">+    for mech, call in
          mechanisms.items():</tt><br>
        <tt style="color:#008">+      if mech in warehouse[package]:</tt><br>
        <tt style="color:#008">+        print("Attempting to obtain %s
          using %s..." % (package, mech), end='')</tt><br>
        <tt style="color:#008">+        sys.stdout.flush()</tt><br>
        <tt style="color:#008">+        if call(abs(installation_root /
          package), warehouse[package][mech]):</tt><br>
        <tt style="color:#008">+          assert (installation_root /
          package).isdir(), "Installation failed"</tt><br>
        <tt style="color:#008">+          downloaded = True</tt><br>
        <tt style="color:#008">+          print("success")</tt><br>
        <tt style="color:#008">+          break</tt><br>
        <tt style="color:#008">+        else:</tt><br>
        <tt style="color:#008">+          assert not (installation_root
          / package).isdir(), "Install mechanism %s did not fail
          cleanly" % mech</tt><br>
        <tt style="color:#008">+          print("failed")</tt><br>
        <tt style="color:#008">+    if not downloaded:</tt><br>
        <tt style="color:#008">+      print("Skipping package %s: Could
          not install" % package)</tt><br>
        <tt style="color:#008">+      errors = True</tt><br>
        <tt style="color:#008">+      continue</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+    packages_to_configure.add(package)</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+  if packages_to_configure:</tt><br>
        <tt style="color:#008">+    packages_to_configure =
          sorted(packages_to_configure)</tt><br>
        <tt style="color:#008">+    print("Configuring packages %s" % ",
          ".join(packages_to_configure))</tt><br>
        <tt style="color:#008">+    os.chdir(abs(libtbx.env.build_path))</tt><br>
        <tt style="color:#008">+    result =
          procrunner.run_process(['libtbx.configure'] +
          packages_to_configure)</tt><br>
        <tt style="color:#008">+    if result['exitcode']: errors = True</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+  if errors:</tt><br>
        <tt style="color:#008">+    sys.exit(1)</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+def install_git(location, source):</tt><br>
        <tt style="color:#008">+  try:</tt><br>
        <tt style="color:#008">+    result =
          procrunner.run_process(['git', 'clone', '--recursive', source,
          location], print_stdout=False, print_stderr=False)</tt><br>
        <tt style="color:#008">+    if result['exitcode']:</tt><br>
        <tt style="color:#008">+      return False</tt><br>
        <tt style="color:#008">+    Toolbox.set_git_repository_config_to_rebase(os.path.join(location,
          '.git', 'config'))</tt><br>
        <tt style="color:#008">+    return True</tt><br>
        <tt style="color:#008">+  except OSError:</tt><br>
        <tt style="color:#008">+    return False # git may not be
          installed</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+def install_zip(location, source):</tt><br>
        <tt style="color:#008">+  os.mkdir(location)</tt><br>
        <tt style="color:#008">+  tempfile = os.path.join(location,
          '.tmp.zip')</tt><br>
        <tt style="color:#008">+  etagfile = os.path.join(location,
          '..tmp.zip.etag')</tt><br>
        <tt style="color:#008">+  def cleanup():</tt><br>
        <tt style="color:#008">+    try: os.remove(tempfile)</tt><br>
        <tt style="color:#008">+    except OSError: pass</tt><br>
        <tt style="color:#008">+    try: os.remove(etagfile)</tt><br>
        <tt style="color:#008">+    except OSError: pass</tt><br>
        <tt style="color:#008">+  if
          Toolbox.download_to_file(source['url'], tempfile) &lt;= 0:</tt><br>
        <tt style="color:#008">+    cleanup()</tt><br>
        <tt style="color:#008">+    os.rmdir(location)</tt><br>
        <tt style="color:#008">+    return False</tt><br>
        <tt style="color:#008">+  Toolbox.unzip(tempfile, location,
          trim_directory=source.get('trim', 0))</tt><br>
        <tt style="color:#008">+  cleanup()</tt><br>
        <tt style="color:#008">+  return True</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+mechanisms = collections.OrderedDict((</tt><br>
        <tt style="color:#008">+  ('git-auth', install_git),</tt><br>
        <tt style="color:#008">+  ('git-anon', install_git),</tt><br>
        <tt style="color:#008">+  ('http-zip', install_zip),</tt><br>
        <tt style="color:#008">+))</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+warehouse = {</tt><br>
        <tt style="color:#008">+  'i19': {</tt><br>
        <tt style="color:#008">+    'git-auth':
          '<a class="moz-txt-link-abbreviated" href="mailto:git@github.com:/xia2/i19">git@github.com:/xia2/i19</a>',</tt><br>
        <tt style="color:#008">+    'git-anon':
          '<a class="moz-txt-link-freetext" href="https://github.com/xia2/i19.git">https://github.com/xia2/i19.git</a>',</tt><br>
        <tt style="color:#008">+    'http-zip': { 'url':
          '<a class="moz-txt-link-freetext" href="https://github.com/xia2/i19/archive/master.zip">https://github.com/xia2/i19/archive/master.zip</a>', 'trim': 1 },</tt><br>
        <tt style="color:#008">+  },</tt><br>
        <tt style="color:#008">+}</tt><br>
        <tt style="color:#008">+</tt><br>
        <tt style="color:#008">+if __name__ == '__main__':</tt><br>
        <tt style="color:#008">+  run(sys.argv[1:])</tt><br>
      </tt>
    </blockquote>
    <br>
  </body>
</html>