<pre style='margin:0'>
Chris Jones (cjones051073) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/88fb3ad96ce63b83e69c9118bbca0592d27cebc6">https://github.com/macports/macports-ports/commit/88fb3ad96ce63b83e69c9118bbca0592d27cebc6</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new 88fb3ad  bazel : Add support for builds on older OSX versions
</span>88fb3ad is described below

<span style='display:block; white-space:pre;color:#808000;'>commit 88fb3ad96ce63b83e69c9118bbca0592d27cebc6
</span>Author: Chris Jones <jonesc@macports.org>
AuthorDate: Sun Oct 21 12:10:46 2018 +0100

<span style='display:block; white-space:pre;color:#404040;'>    bazel : Add support for builds on older OSX versions
</span>---
 devel/bazel/Portfile                               |  72 ++++--
 .../Xcode7-Revert-xcode-locator/xcode_locator.m    | 271 +++++++++++++++++++++
 2 files changed, 321 insertions(+), 22 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/devel/bazel/Portfile b/devel/bazel/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index df9cbb7..f2ed127 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/devel/bazel/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/devel/bazel/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4,21 +4,16 @@ PortSystem                          1.0
</span> PortGroup                 github    1.0
 PortGroup                 cxx11     1.1
 PortGroup                 java      1.0
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# Might be useful to support older systems at some point.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#PortGroup                 compilers 1.0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#PortGroup                 compiler_blacklist_versions 1.0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#compiler.blacklist-append {clang < 702}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#compilers.setup           require_fortran
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#build.env-append          CC=${configure.cc}   \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#                          CXX=${configure.cxx} \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#                          FC=${configure.fc}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup                 compilers 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup                 xcodeversion 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup                 compiler_blacklist_versions 1.0
</span> 
 github.setup              bazelbuild bazel 0.18.0
<span style='display:block; white-space:pre;background:#ffe0e0;'>-revision                  1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision                  2
</span> github.tarball_from       releases
 categories                devel
 maintainers               {tfmnet.com:mohamed.issa @RootFunction} \
<span style='display:block; white-space:pre;background:#e0ffe0;'>+                          {jonesc @cjones051073} \
</span>                           openmaintainer
 description               A tool for automating builds and tests.
 long_description          ${description}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -39,15 +34,55 @@ use_configure             no
</span> depends_build-append      bin:python:python27 \
                           bin:bash:bash \
                           bin:zip:zip
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#                          bin:git:git
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# https://github.com/bazelbuild/bazel/issues/6188
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-if {${os.major} <= 15} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+depends_lib-append        port:cctools
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patch.pre_args -p1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# The oldest Xcode version to use default Xcode compiler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Note setting here should be in sync with that in py-tensorflow
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set bazel_min_xcode 9.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Older OS hacks
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${os.major} < 16} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # https://github.com/bazelbuild/bazel/issues/6188
</span>     depends_build-append  port:unzip
 }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+post-patch {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[vercmp ${xcodeversion} 8.0] < 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Revert xcode-locator to an older version for Xcode 7 and older
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # https://raw.githubusercontent.com/bazelbuild/bazel/7372c04d40d7ab45fa2649c8be002ee6909668d1/tools/osx/xcode_locator.m
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        file copy -force ${filespath}/Xcode7-Revert-xcode-locator/xcode_locator.m ${worksrcpath}/tools/osx/xcode_locator.m
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compiler.blacklist-append {clang < 710}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#compilers.setup           require_fortran
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+build.env-append  CC=${configure.cc} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 CXX=${configure.cxx} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              TMPDIR=${workpath}/tmp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Disable Xcode detection on older OSes, as we want the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# MP provided commandline utilities to be used instead.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {[vercmp ${xcodeversion} ${bazel_min_xcode}] < 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    build.env-append BAZEL_USE_CPP_ONLY_TOOLCHAIN=1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
 build {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    system -W ${worksrcpath} "./compile.sh"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[vercmp ${xcodeversion} ${bazel_min_xcode}] < 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Patch build files to enforce correct compiler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach f { scripts/bootstrap/compile.sh tools/osx/crosstool/CROSSTOOL.tpl src/test/shell/bazel/testdata/bazel_toolchain_test_data/tools/arm_compiler/CROSSTOOL tools/cpp/unix_cc_configure.bzl tools/cpp/CROSSTOOL third_party/zlib/configure src/test/java/com/google/devtools/build/lib/analysis/mock/MOCK_CROSSTOOL } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            foreach cmd {ar nm strip libtool ld objdump} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                reinplace -q "s|/usr/bin/${cmd}|${prefix}/bin/${cmd}|g" ${f}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            reinplace -q "s|/usr/bin/clang|${configure.cc}|g" ${f}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            reinplace -q "s|\"clang\"|\"${configure.cc}\"|g"  ${f}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            reinplace -q "s| clang | ${configure.cc} |g"  ${f}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Build bazel
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    system -W ${worksrcpath} "VERBOSE=yes BAZEL_WRKDIR=${workpath} ./compile.sh"
</span> 
     # Put executable in main working folder
     xinstall -m 755 -W ${worksrcpath}/output ${name} ${worksrcpath}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -55,15 +90,8 @@ build {
</span>     # Get ready to build the bash completion script
     file delete -force /var/tmp/_${name}_root
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # build fails if it does not recognize this dir as a git repo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # As of 0.18.0 this no longer seems neccessary, and git dependency
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # prevents binary distribution so comment out. Eventually can be removed.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    #system -W ${worksrcpath} "git init"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    #system -W ${worksrcpath} "git add ."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    #system -W ${worksrcpath} "git commit -m GitRepo"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     # Build the bash completion script
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    system -W ${worksrcpath} "./${name} --max_idle_secs=60 --output_user_root=${workpath} build //scripts:${name}-complete.bash"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    system -W ${worksrcpath} "./${name} --max_idle_secs=60 --output_user_root=${workpath} build -s //scripts:${name}-complete.bash"
</span> }
 
 destroot {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/devel/bazel/files/Xcode7-Revert-xcode-locator/xcode_locator.m b/devel/bazel/files/Xcode7-Revert-xcode-locator/xcode_locator.m
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..1565f6f
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/devel/bazel/files/Xcode7-Revert-xcode-locator/xcode_locator.m
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,271 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Copyright 2015 Google Inc. All rights reserved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Licensed under the Apache License, Version 2.0 (the "License");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// you may not use this file except in compliance with the License.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// You may obtain a copy of the License at
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//    http://www.apache.org/licenses/LICENSE-2.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Unless required by applicable law or agreed to in writing, software
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// distributed under the License is distributed on an "AS IS" BASIS,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// See the License for the specific language governing permissions and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// limitations under the License.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Application that finds all Xcodes installed on a given Mac and will return a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// path for a given version number.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// If you have 7.0, 6.4.1 and 6.3 installed the inputs will map to:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// 7,7.0,7.0.0 = 7.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// 6,6.4,6.4.1 = 6.4.1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// 6.3,6.3.0 = 6.3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if !defined(__has_feature) || !__has_feature(objc_arc)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#error "This file requires ARC support."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#import <CoreServices/CoreServices.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#import <Foundation/Foundation.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Simple data structure for tracking a version of Xcode (i.e. 6.4) with an URL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// to the appplication.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@interface XcodeVersionEntry : NSObject
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@property(readonly) NSString *version;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@property(readonly) NSURL *url;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@end
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@implementation XcodeVersionEntry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- (id)initWithVersion:(NSString *)version url:(NSURL *)url {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if ((self = [super init])) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    _version = version;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    _url = url;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return self;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- (id)description {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return [NSString stringWithFormat:@"<%@ %p>: %@ %@",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   [self class], self, _version, _url];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@end
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Given an entry, insert it into a dictionary that is keyed by versions.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// For an entry that is 6.4.1:/Applications/Xcode.app, add it for 6.4.1 and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// optionally add it for 6.4 and 6 if it is "better" than any entry that may
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// already be there, where "better" is defined as:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// 1. Under /Applications/. (This avoids mounted xcode versions taking
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//    precedence over installed versions.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// 2. Not older (at least as high version number).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void AddEntryToDictionary(XcodeVersionEntry *entry,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                 NSMutableDictionary *dict) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  BOOL inApplications =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      [entry.url.path rangeOfString:@"/Applications/"].location != NSNotFound;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NSString *entryVersion = entry.version;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NSString *subversion = entryVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (dict[entryVersion] && !inApplications) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  dict[entryVersion] = entry;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (YES) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSRange range = [subversion rangeOfString:@"." options:NSBackwardsSearch];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (range.length == 0 || range.location == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    subversion = [subversion substringToIndex:range.location];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    XcodeVersionEntry *subversionEntry = dict[subversion];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (subversionEntry) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      BOOL atLeastAsLarge = ([subversionEntry.version compare:entry.version]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                             == NSOrderedDescending);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (inApplications && atLeastAsLarge) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        dict[subversion] = entry;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      dict[subversion] = entry;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Given a "version", expand it to at least 3 components by adding .0 as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// necessary.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static NSString *ExpandVersion(NSString *version) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NSArray *components = [version componentsSeparatedByString:@"."];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NSString *appendage = nil;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (components.count == 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    appendage = @".0";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  } else if (components.count == 1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    appendage = @".0.0";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (appendage) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    version = [version stringByAppendingString:appendage];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return version;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Searches for all available Xcodes in the system and returns a dictionary that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// maps version identifiers of any form (X, X.Y, and X.Y.Z) to the directory
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// where the Xcode bundle lives.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// If there is a problem locating the Xcodes, prints one or more error messages
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// and returns nil.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static NSMutableDictionary *FindXcodes() __attribute((ns_returns_retained)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CFStringRef bundleID = CFSTR("com.apple.dt.Xcode");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CFErrorRef cfError;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NSArray *array = CFBridgingRelease(LSCopyApplicationURLsForBundleIdentifier(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      bundleID, &cfError));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (array == nil) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSError *nsError = (__bridge NSError *)cfError;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "error: %s\n", nsError.description.UTF8String);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return nil;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  // Scan all bundles but delay returning in case of errors until we are
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  // done. This is to let us log details about all the bundles that were
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  // processed so that a faulty bundle doesn't hide useful information about
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  // other bundles that were found.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  BOOL errors = NO;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  for (NSURL *url in array) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSArray *contents = [
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      [NSFileManager defaultManager] contentsOfDirectoryAtURL:url
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   includingPropertiesForKeys:nil
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                                      options:0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                                        error:nil];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSLog(@"Found bundle %@ in %@; contents on disk: %@",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          bundleID, url, contents);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSBundle *bundle = [NSBundle bundleWithURL:url];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (bundle == nil) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      NSLog(@"ERROR: Unable to open bundle at URL: %@\n", url);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      errors = YES;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSString *versionKey = @"CFBundleShortVersionString";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSString *version = [bundle.infoDictionary objectForKey:versionKey];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (version == nil) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      NSLog(@"ERROR: Cannot find %@ in info for bundle %@; info: %@\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            versionKey, url, bundle.infoDictionary);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      errors = YES;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSString *expandedVersion = ExpandVersion(version);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSLog(@"Version strings for %@: short=%@, expanded=%@",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          url, version, expandedVersion);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSURL *developerDir =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        [url URLByAppendingPathComponent:@"Contents/Developer"];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    XcodeVersionEntry *entry =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        [[XcodeVersionEntry alloc] initWithVersion:expandedVersion
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                               url:developerDir];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    AddEntryToDictionary(entry, dict);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return errors ? nil : dict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Prints out the located Xcodes as a set of lines where each line contains the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// list of versions for a given Xcode and its location on disk.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void DumpAsVersionsOnly(FILE *output, NSMutableDictionary *dict) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NSSet *distinctValues = [[NSSet alloc] initWithArray:[dict allValues]];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NSMutableDictionary *aliasDict = [[NSMutableDictionary alloc] init];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  for (XcodeVersionEntry *value in distinctValues) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSString *versionString = value.version;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (aliasDict[versionString] == nil) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      aliasDict[versionString] = [[NSMutableSet alloc] init];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    [aliasDict[versionString]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        addObjectsFromArray:[dict allKeysForObject:value]];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  for (NSString *version in aliasDict) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    XcodeVersionEntry *entry = dict[version];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(output, "%s:%s:%s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            version.UTF8String,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            [[aliasDict[version] allObjects]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   componentsJoinedByString: @","].UTF8String,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            entry.url.fileSystemRepresentation);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Prints out the located Xcodes in JSON format.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void DumpAsJson(FILE *output, NSMutableDictionary *dict) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(output, "{\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  for (NSString *version in dict) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    XcodeVersionEntry *entry = dict[version];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(output, "\t\"%s\": \"%s\",\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            version.UTF8String, entry.url.fileSystemRepresentation);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(output, "}\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// Dumps usage information.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void usage(FILE *output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      output,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "xcode-locator [-v|<version_number>]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "\n\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "Given a version number or partial version number in x.y.z format, "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "will attempt to return the path to the appropriate developer "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "directory."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "\n\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "Omitting a version number will list all available versions in JSON "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "format, alongside their paths."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "\n\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "Passing -v will list all available fully-specified version numbers "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "along with their possible aliases and their developer directory, "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "each on a new line. For example:"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "\n\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "7.3.1:7,7.3,7.3.1:/Applications/Xcode.app/Contents/Developer"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      "\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int main(int argc, const char * argv[]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  @autoreleasepool {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSString *versionArg = nil;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    BOOL versionsOnly = NO;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (argc == 1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      versionArg = @"";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else if (argc == 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      NSString *firstArg = [NSString stringWithUTF8String:argv[1]];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if ([@"-v" isEqualToString:firstArg]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        versionsOnly = YES;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        versionArg = @"";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        versionArg = firstArg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        NSCharacterSet *versSet =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            [NSCharacterSet characterSetWithCharactersInString:@"0123456789."];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if ([versionArg rangeOfCharacterFromSet:versSet.invertedSet].length
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            != 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          versionArg = nil;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (versionArg == nil) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      usage(stderr);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NSMutableDictionary *dict = FindXcodes();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (dict == nil) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    XcodeVersionEntry *entry = [dict objectForKey:versionArg];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (entry) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("%s\n", entry.url.fileSystemRepresentation);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (versionsOnly) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      DumpAsVersionsOnly(stdout, dict);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      DumpAsJson(stdout, dict);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return ([@"" isEqualToString:versionArg] ? 0 : 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span></pre><pre style='margin:0'>

</pre>