If you follow us on Twitter (@iachievedit) you know that we build open source Swift a lot, and for a number of different OSes and architectures. There’s no rhyme or reason as to when we decide to start building, but it’s nice to keep track of the various git
revisions of the repositories that went into a given artifact.
Since we’re excited about Swift eventually displacing other scripting languages on Linux (their names rhyme with Bython and Buby), it felt like a good time to write up a script (in Swift) that did this for us.
Some notes here:
- we’re using a
subscript
extension ofString
that will likely never be a part of the core language for reasons. exec
is our version of backticks (output = `ls`
) in other scripting languages. We want to execute a command and read its output.- there’s certainly more optimization and tightening that can be done.
With that out of the way, here is swiftrevs.swift
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
import Glibc extension String { subscript (r: CountableClosedRange<Int>) -> String { get { let startIndex = self.characters.index(self.characters.startIndex, offsetBy:r.lowerBound) let endIndex = self.characters.index(self.characters.startIndex, offsetBy:r.upperBound) return self[startIndex..<endIndex] } } } func exec(_ command:String) -> String { let BUFSIZE = 128 let pipe = popen(command, "r") var buf = [CChar](repeating:CChar(0), count:BUFSIZE) var output:String = "" while fgets(&buf, Int32(BUFSIZE), pipe) != nil { output = String(cString:buf) } return output } func gitRevision() -> String { return exec("/usr/bin/git rev-parse HEAD")[0...9] } func gitFetchURL() -> String { return exec("/usr/bin/git remote show origin -n|grep Fetch| echo -n `cut --characters=14-`") } func gitBranch() -> String { return exec("/usr/bin/git branch | echo -n `cut --characters=2-`") } let dirs = ["swift", "llvm", "clang", "lldb", "compiler-rt", "cmark", "llbuild", "swiftpm", "swift-corelibs-xctest", "swift-corelibs-foundation", "swift-integration-tests", "swift-corelibs-libdispatch"] for dir in dirs { let cwd = String(cString:getcwd(nil, 0)) let rc = chdir(dir) // pushd guard rc == 0 else { continue } let fetch = gitFetchURL() let rev = gitRevision() let branch = gitBranch() print("\(dir),\(fetch),\(branch),\(rev)") chdir(cwd) // popd } |
We use this as follows:
# swift swiftrevs.swift swift,https://github.com/apple/swift.git,master,cf3fdff04 llvm,https://github.com/apple/swift-llvm.git,stable,8d0086ac3 clang,https://github.com/apple/swift-clang.git,stable,460d629e8 lldb,https://github.com/apple/swift-lldb.git,master,da120cf91 compiler-rt,https://github.com/apple/swift-compiler-rt.git,stable,9daa1b32c cmark,https://github.com/apple/swift-cmark.git,master,5af77f3c1 llbuild,https://github.com/apple/swift-llbuild.git,master,7aadcf936 swiftpm,https://github.com/apple/swift-package-manager.git,master,423c2a1c8 swift-corelibs-xctest,https://github.com/apple/swift-corelibs-xctest.git,master,03905f564 swift-corelibs-foundation,https://github.com/apple/swift-corelibs-foundation.git,master,4c15543f8 swift-integration-tests,https://github.com/apple/swift-integration-tests.git,master,4eda8055a swift-corelibs-libdispatch,https://github.com/apple/swift-corelibs-libdispatch.git,master,e922531c2
This, of course, is run in a directory that has all of the various repositories required to build Swift cloned. If you’re interested in learning how to build Swift for X86 or certain ARM devices, check out our package-swift repository. It not only contains swiftrevs.swift
but also a handful of scripts aimed at making building Swift (along with the REPL, Foundation, and Swift Package Manager) nearly painless.