blob: 62467bc6abeacbb065418c5621d37cdbc53d331a [file] [log] [blame]
// Copyright 2016 The Tulsi Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import Foundation
// Represents a label in a build file - http://bazel.build/docs/build-ref.html#labels
public class BuildLabel: Comparable, Equatable, Hashable, CustomStringConvertible {
public let value: String
public lazy var targetName: String? = { [unowned self] in
let components = self.value.components(separatedBy: ":")
if components.count > 1 {
return components.last
}
let lastPackageComponent = self.value.components(separatedBy: "/").last!
if lastPackageComponent.isEmpty {
return nil
}
return lastPackageComponent
}()
public lazy var packageName: String? = { [unowned self] in
guard var package = self.value.components(separatedBy: ":").first else {
return nil
}
if package.hasPrefix("//") {
package.removeSubrange(package.startIndex ..< package.index(package.startIndex, offsetBy: 2))
}
if package.isEmpty || package.hasSuffix("/") {
return ""
}
return package
}()
public lazy var asFileName: String? = { [unowned self] in
guard var package = self.packageName, let target = self.targetName else {
return nil
}
// Fix for external and local_repository, which may be referenced by Bazel via
// @repository//subpath while we internally refer to them via external/repository/subpath.
if package.starts(with: "@") {
package = "external/" + package.suffix(from: package.index(package.startIndex, offsetBy: 1))
}
return "\(package)/\(target)"
}()
public lazy var asFullPBXTargetName: String? = { [unowned self] in
guard let package = self.packageName, let target = self.targetName else {
return nil
}
// Note: The replacement must be done with a value that is not supported in Bazel packages in
// order to prevent collisions, but is still supported by Xcode (for scheme filenames, etc...).
return "\(package)/\(target)".replacingOccurrences(of: "/", with: "-")
}()
public lazy var hashValue: Int = { [unowned self] in
return self.value.hashValue
}()
public init(_ label: String, normalize: Bool = false) {
var value = label
if normalize && !value.hasPrefix("//") {
value = "//\(value)"
}
self.value = value
}
// MARK: - CustomStringConvertible
public var description: String {
return self.value
}
}
// MARK: - Comparable
public func <(lhs: BuildLabel, rhs: BuildLabel) -> Bool {
return lhs.value < rhs.value
}
// MARK: - Equatable
public func ==(lhs: BuildLabel, rhs: BuildLabel) -> Bool {
return lhs.value == rhs.value
}