├── .github └── workflows │ └── swift.yml ├── .gitignore ├── .swiftformat ├── LICENSE ├── Makefile ├── Package.resolved ├── Package.swift ├── README.md ├── Sources ├── Bazelize │ ├── Command.swift │ └── Entry.swift ├── BazelizeKit │ ├── Bazel │ │ ├── BazelFile.swift │ │ ├── CodeBuilder.swift │ │ ├── ConfigBazelRC.swift │ │ ├── Module.swift │ │ ├── RootBUILD.swift │ │ ├── TargetBUILD.swift │ │ ├── Version.swift │ │ ├── WORKSPACE+Builder.swift │ │ └── WORKSPACE.swift │ ├── Codegen │ │ ├── Codegen+Application.swift │ │ ├── Codegen+Framework.swift │ │ ├── Codegen+Plist.swift │ │ ├── Codegen+StaticFramework.swift │ │ ├── Codegen+StaticLibrary.swift │ │ ├── Codegen+Target.swift │ │ ├── Codegen+UITest.swift │ │ ├── Codegen+UnitTest.swift │ │ ├── Language │ │ │ ├── Codegen+Library.swift │ │ │ ├── Codegen+ObjcLibrary.swift │ │ │ └── Codegen+SwiftLibrary.swift │ │ └── Resource │ │ │ ├── Codegen+Asset.swift │ │ │ └── Codegen+Strings.swift │ ├── Kit.swift │ ├── Plugin │ │ ├── Plugin+Apple.swift │ │ ├── Plugin+Archive.swift │ │ ├── Plugin+Imported.swift │ │ ├── Plugin+Linker.swift │ │ ├── Plugin+PlistFragment.swift │ │ ├── Plugin+SPM2.swift │ │ ├── Plugin+Swift.swift │ │ ├── Plugin+XCodeProj.swift │ │ └── PluginBuiltin.swift │ ├── Repo │ │ ├── Repo+Apple.swift │ │ ├── Repo+Hammer.swift │ │ ├── Repo+Pod.swift │ │ ├── Repo+SPM.swift │ │ ├── Repo+Swift.swift │ │ ├── Repo+XCodeProj.swift │ │ └── Repo.swift │ └── Rule │ │ ├── LoadableRule.swift │ │ ├── RulesApple.swift │ │ ├── RulesConfig.swift │ │ ├── RulesObjc.swift │ │ ├── RulesPlist.swift │ │ └── RulesSwift.swift ├── Cocoapod │ ├── CodeGen │ │ └── NewPod.swift │ ├── Model │ │ ├── PodSpec.swift │ │ ├── Podfile.swift │ │ └── PodfileLock.swift │ ├── Pod.swift │ ├── PodError.swift │ └── Util.swift ├── PluginInterface │ ├── Plugin.swift │ ├── XCodeBuildSetting.swift │ ├── XCodeProject.swift │ ├── XCodeSPM.swift │ └── XCodeTarget.swift ├── PluginLoader │ ├── Core.swift │ ├── PluginBuilder.swift │ ├── PluginInfo.swift │ └── PluginLoader.swift ├── RuleBuilder │ ├── Builder │ │ ├── PropertyBuilder.swift │ │ └── StarlarkBuilder.swift │ ├── Starlark │ │ ├── Starlark+Select.swift │ │ ├── StarlarkProperty+Operator.swift │ │ ├── StarlarkProperty+String.swift │ │ ├── StarlarkProperty+Visibility.swift │ │ ├── StarlarkProperty.swift │ │ ├── StarlarkRule.swift │ │ └── Startlark.swift │ └── Text.swift ├── Util │ ├── Array+Extension.swift │ ├── AsyncSequence+all.swift │ ├── Env.swift │ ├── Logger.swift │ ├── Parsable.swift │ ├── Process.swift │ ├── String+Extension.swift │ └── String+Indent.swift └── XCode │ ├── Model │ ├── BuildSetting+PList.swift │ ├── BuildSetting.swift │ ├── ConfigList.swift │ ├── SPMParser.swift │ ├── XCode+File.swift │ ├── XCode+Preffer.swift │ ├── XCode+Project.swift │ ├── XCode+RemoteSPMPackage.swift │ ├── XCode+SPM.swift │ ├── XCode+Select.swift │ └── XCode+Target.swift │ └── Setting │ ├── DeviceFamily.swift │ ├── ExplicitFileType.swift │ └── LastKnownFileType.swift ├── Tests ├── CocoapodTests │ ├── Resource │ │ ├── Podfile │ │ └── Podfile.lock │ └── SPMTests.swift ├── RuleBuilderTests │ ├── BuilderTests.swift │ ├── PropertyTests.swift │ └── Starlark │ │ └── StarlarkTests.swift ├── UtilTests │ └── UtilTests.swift └── XCodeTests │ └── PropertyTests.swift ├── docs ├── Dependecy_ZH.md ├── Design.md ├── Design_ZH.md ├── Podfile+PodToBUILD.md ├── Podfile.lock.md ├── Podfile.md ├── Rules.md ├── RxSwift+PodToBUILD.md └── SPM.md ├── fixture └── iOS │ ├── .bazelrc │ ├── .bazelversion │ ├── .gitignore │ ├── BUILD │ ├── Example.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Example.xcscheme │ ├── Example │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ └── bazel.png │ │ ├── Contents.json │ │ └── bazel.imageset │ │ │ ├── Contents.json │ │ │ └── bazel.png │ ├── BUILD │ ├── ContentView.swift │ ├── ExampleApp.swift │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── Test.swift │ ├── en.lproj │ │ └── Localizable.strings │ └── zh-Hant.lproj │ │ └── Localizable.strings │ ├── ExampleTests │ ├── BUILD │ └── ExampleTests.swift │ ├── ExampleUITests │ ├── BUILD │ ├── ExampleUITests.swift │ └── ExampleUITestsLaunchTests.swift │ ├── Framework1 │ ├── BUILD │ ├── Framework1.h │ └── Test.swift │ ├── Framework1Tests │ ├── BUILD │ └── Framework1Tests.swift │ ├── Framework2 │ ├── BUILD │ ├── Framework2.h │ └── Test.swift │ ├── Framework2Tests │ ├── BUILD │ └── Framework2Tests.swift │ ├── Framework3 │ ├── BUILD │ ├── Framework.h │ ├── Framework.m │ └── Framework3.h │ ├── Framework3Tests │ ├── BUILD │ └── Framework3Tests.m │ ├── Local1 │ ├── .gitignore │ ├── Package.swift │ ├── README.md │ ├── Sources │ │ ├── LocalTarget1 │ │ │ └── LocalTarget1.swift │ │ ├── LocalTarget2 │ │ │ └── LocalTarget2.swift │ │ └── LocalTarget3 │ │ │ ├── include │ │ │ └── LocalTarget3.h │ │ │ └── src │ │ │ └── LocalTarget3.m │ └── Tests │ │ └── Local1Tests │ │ └── Local1Tests.swift │ ├── Local2 │ ├── .gitignore │ ├── Package.swift │ ├── README.md │ ├── Sources │ │ └── Local2 │ │ │ └── Local2.swift │ └── Tests │ │ └── Local2Tests │ │ └── Local2Tests.swift │ ├── MODULE.bazel │ ├── Makefile │ ├── Package.resolved │ ├── Package.swift │ ├── SVProgressHUD.xcframework │ ├── Info.plist │ ├── ios-arm64_armv7 │ │ └── SVProgressHUDShare.framework │ │ │ ├── Headers │ │ │ └── SVProgressHUD.h │ │ │ ├── Info.plist │ │ │ ├── Modules │ │ │ └── module.modulemap │ │ │ ├── SVProgressHUD.bundle │ │ │ ├── angle-mask.png │ │ │ ├── angle-mask@2x.png │ │ │ ├── angle-mask@3x.png │ │ │ ├── error.png │ │ │ ├── error@2x.png │ │ │ ├── error@3x.png │ │ │ ├── info.png │ │ │ ├── info@2x.png │ │ │ ├── info@3x.png │ │ │ ├── success.png │ │ │ ├── success@2x.png │ │ │ └── success@3x.png │ │ │ └── SVProgressHUDShare │ └── ios-arm64_x86_64-simulator │ │ └── SVProgressHUDShare.framework │ │ ├── Headers │ │ └── SVProgressHUD.h │ │ ├── Info.plist │ │ ├── Modules │ │ └── module.modulemap │ │ ├── SVProgressHUD.bundle │ │ ├── angle-mask.png │ │ ├── angle-mask@2x.png │ │ ├── angle-mask@3x.png │ │ ├── error.png │ │ ├── error@2x.png │ │ ├── error@3x.png │ │ ├── info.png │ │ ├── info@2x.png │ │ ├── info@3x.png │ │ ├── success.png │ │ ├── success@2x.png │ │ └── success@3x.png │ │ ├── SVProgressHUDShare │ │ └── _CodeSignature │ │ └── CodeResources │ ├── Static │ ├── BUILD │ └── Static.swift │ ├── Static2 │ ├── BUILD │ ├── Static2.h │ └── Static2.m │ ├── WORKSPACE │ ├── config.bazelrc │ ├── swift_deps.bzl │ └── swift_deps_index.json └── git_release.py /.swiftformat: -------------------------------------------------------------------------------- 1 | # From: https://github.com/airbnb/swift/blob/master/Sources/AirbnbSwiftFormatTool/airbnb.swiftformat 2 | # Modified for simplicity 3 | 4 | --swiftversion 5.6 5 | --self remove # redundantSelf 6 | --importgrouping testable-bottom # sortedImports 7 | --commas always # trailingCommas 8 | --trimwhitespace always # trailingSpace 9 | --indent 4 #indent 10 | --ifdef no-indent #indent 11 | # --indentstrings true #indent 12 | --wraparguments before-first # wrapArguments 13 | --wrapparameters before-first # wrapArguments 14 | --wrapcollections before-first # wrapArguments 15 | --wrapconditions before-first # wrapArguments 16 | --wrapreturntype if-multiline #wrapArguments 17 | --closingparen same-line # wrapArguments 18 | --wraptypealiases before-first # wrapArguments 19 | --funcattributes prev-line # wrapAttributes 20 | --typeattributes prev-line # wrapAttributes 21 | --wrapternary before-operators # wrap 22 | # --structthreshold 20 # organizeDeclarations 23 | # --enumthreshold 20 # organizeDeclarations 24 | # --organizetypes class,struct,enum,extension,actor # organizeDeclarations 25 | --extensionacl on-declarations # extensionAccessControl 26 | --patternlet inline # hoistPatternLet 27 | --redundanttype inferred # redundantType 28 | --emptybraces spaced # emptyBraces 29 | 30 | # We recommend a max width of 100 but _strictly enforce_ a max width of 130 31 | --maxwidth 130 # wrap 32 | 33 | # rules 34 | --rules anyObjectProtocol 35 | --rules blankLinesBetweenScopes 36 | --rules consecutiveSpaces 37 | --rules duplicateImports 38 | --rules extensionAccessControl 39 | --rules hoistPatternLet 40 | --rules indent 41 | --rules markTypes 42 | # --rules organizeDeclarations 43 | --rules redundantParens 44 | --rules redundantReturn 45 | --rules redundantSelf 46 | --rules redundantType 47 | --rules redundantPattern 48 | --rules redundantGet 49 | --rules redundantFileprivate 50 | --rules redundantRawValues 51 | --rules sortedImports 52 | --rules sortDeclarations 53 | --rules strongifiedSelf 54 | --rules trailingCommas 55 | --rules trailingSpace 56 | --rules typeSugar 57 | --rules wrap 58 | --rules wrapMultilineStatementBraces 59 | --rules wrapArguments 60 | --rules wrapAttributes 61 | --rules braces 62 | --rules redundantClosure 63 | --rules redundantInit 64 | --rules redundantVoidReturnType 65 | --rules unusedArguments 66 | --rules spaceInsideBrackets 67 | --rules spaceInsideBraces 68 | --rules spaceAroundBraces 69 | --rules spaceInsideParens 70 | --rules spaceAroundParens 71 | --rules enumNamespaces 72 | --rules blockComments 73 | --rules spaceAroundComments 74 | --rules spaceInsideComments 75 | --rules blankLinesAtStartOfScope 76 | --rules blankLinesAtEndOfScope 77 | --rules emptyBraces 78 | --rules andOperator 79 | 80 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Yume 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION := 0.0.4 2 | 3 | .PHONY: install 4 | install: release 5 | @cp .build/release/bazelize /usr/local/bin 6 | 7 | .PHONY: syncVersion 8 | syncVersion: 9 | @sed -i '' 's|\(version = "\)\(.*\)\("\)|\1$(VERSION)\3|' Sources/BazelizeKit/Bazel/Version.swift 10 | 11 | .PHONY: release 12 | release: syncVersion 13 | swift build -c release 14 | 15 | .PHONY: coherent 16 | coherent: 17 | coherent-swift report 18 | 19 | .PHONY: lint 20 | lint: 21 | swiftformat --lint . --verbose 22 | 23 | .PHONY: format 24 | format: 25 | swiftformat . 26 | 27 | .PHONY: build 28 | build: format 29 | swift build 30 | 31 | .PHONY: test 32 | test: 33 | swift test -v --skip CocoapodTests 2>&1 | xcpretty 34 | # COCOAPOD=$(shell which pod) swift test -v 2>&1 | xcbeautify 35 | 36 | 37 | Apple := bazelbuild/rules_apple 38 | Swift := bazelbuild/rules_swift 39 | Pod := pinterest/PodToBUILD 40 | Hammer := pinterest/xchammer 41 | XCodeProj := buildbuddy-io/rules_xcodeproj 42 | SPM := cgrindel/rules_spm 43 | SPM2 := cgrindel/swift_bazel 44 | 45 | REPOS := Apple Swift Pod Hammer XCodeProj 46 | REPO_SPM := SPM 47 | 48 | 49 | # user/repo rule_name output_file_path 50 | # python3 git_release.py bazelbuild/rules_apple Apple Sources/BazelizeKit/Rule/Rule+Apple.swift 51 | $(REPOS): 52 | python3 git_release.py $($@) $@ Sources/BazelizeKit/Repo/Repo+$@.swift 5 normal 53 | 54 | $(REPO_SPM): 55 | python3 git_release.py $($@) $@ Sources/BazelizeKit/Repo/Repo+$@.swift 5 archive 56 | 57 | rules: $(REPOS) 58 | 59 | spm: $(REPO_SPM) 60 | 61 | .PHONY: bazelize 62 | bazelize: install 63 | cd fixture/iOS && make bazelize 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bazelize 2 | 3 | A cli tool turn your xcode project to bazel. 4 | 5 | --- 6 | 7 | ## Install 8 | 9 | ```sh 10 | mint install XCodeBazelize/Bazelize 11 | ``` 12 | 13 | ## Usage 14 | 15 | ```sh 16 | bazelize --project YOUR.xcodeproj 17 | ``` 18 | 19 | --- 20 | 21 | ## Bazel 22 | 23 | ### Project Hierarchy 24 | 25 | ```bash 26 | ├── xxx.xcodeproj 27 | ├── xxx.xcworkspace 28 | ├── config.bazelrc # generated file 29 | ├── BUILD # generated file 30 | ├── WORKSPACE # generated file 31 | ├── Podfile 32 | ├── Podfile.lock 33 | ├── Target1 34 | │ ├── BUILD # generated file 35 | │ └── xxx.swift 36 | ├── Target2 37 | │ ├── BUILD # generated file 38 | │ └── xxx.m 39 | ├── TestTarget1 40 | │ ├── BUILD # generated file 41 | │ └── xxx.swift 42 | ├── TestTarget2 43 | │ ├── BUILD # generated file 44 | │ └── xxx.swift 45 | └ ... 46 | ``` 47 | 48 | ### Config 49 | 50 | All `XCode configs` is stored in `BUILD` file. 51 | 52 | You can build debug version with following code. 53 | 54 | > bazel build --//:mode=Debug [Package] 55 | 56 | ```bazel 57 | load("@bazel_skylib//rules:common_settings.bzl", "string_flag") 58 | string_flag( 59 | name = "mode", 60 | build_setting_default = "normal", 61 | ) 62 | 63 | config_setting( 64 | name = "Debug", 65 | flag_values = { 66 | ":mode": "Debug" 67 | }, 68 | ) 69 | 70 | config_setting( 71 | name = "Release", 72 | flag_values = { 73 | ":mode": "Release" 74 | }, 75 | ) 76 | ``` 77 | 78 | Or you can fill in the following code into `.bazelrc`. 79 | 80 | ```python 81 | import %workspace%/config.bazelrc 82 | ``` 83 | 84 | > bazel build --config=Debug [Package] 85 | -------------------------------------------------------------------------------- /Sources/Bazelize/Command.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Command.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/28. 6 | // 7 | 8 | import ArgumentParser 9 | import BazelizeKit 10 | import Foundation 11 | import PathKit 12 | 13 | struct Command: AsyncParsableCommand { 14 | static var configuration = CommandConfiguration( 15 | commandName: "bazelize", 16 | abstract: "A cli tool turn your xcode project to bazel.", 17 | version: version) 18 | 19 | @Option(name: [.customLong("project", withSingleDash: false)], help: "PATH/TO/YOUR.xcodeproj") 20 | var project: String 21 | 22 | @Option(name: [.short], help: "Debug/Release") 23 | var config = "Release" 24 | 25 | @Option(name: [.long], help: "plugin list") 26 | var manifest = ".bazelize.yml" 27 | 28 | @Flag 29 | var dump = false 30 | 31 | @Flag 32 | var clear = false 33 | 34 | func run() async throws { 35 | let path = Path.current + project 36 | let kit = try await Kit(path, config) 37 | 38 | guard !clear else { 39 | kit.clear() 40 | return 41 | } 42 | 43 | if dump { 44 | try kit.dump() 45 | } else { 46 | try await kit.run(Path(manifest)) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/Bazelize/Entry.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | @main 4 | enum Main { 5 | static func main() async throws { 6 | await Command.main() 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Bazel/BazelFile.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BazelFile.swift 3 | // 4 | // 5 | // Created by Yume on 2022/12/8. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | 11 | // MARK: - BazelFile 12 | 13 | protocol BazelFile { 14 | var path: Path { get } 15 | var code: String { get } 16 | } 17 | 18 | extension BazelFile { 19 | func clear() throws { 20 | try path.delete() 21 | } 22 | 23 | func write() throws { 24 | try path.write(generationHeader + "\n\n" + code) 25 | } 26 | } 27 | 28 | private let generationMarker = "Generated using Bazelize" 29 | private let url = "https://github.com/XCodeBazelize/Bazelize" 30 | private let generationHeader = "# \(generationMarker) \(version) - \(url)" 31 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Bazel/ConfigBazelRC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BazelRC.swift 3 | // 4 | // 5 | // Created by Yume on 2022/12/8. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import PluginInterface 11 | 12 | /// [config](https://bazel.build/docs/configurable-attributes) 13 | /// [.bazelrc](https://bazel.build/run/bazelrc) 14 | /// 15 | /// 16 | /// TODO: 17 | /// TIP: `import %workspace%/config.bazelrc` in `.bazelrc` 18 | /// 19 | /// /config.bazelrc 20 | struct BazelRC: BazelFile { 21 | let path: Path 22 | private(set) var code = "" 23 | 24 | init(_ root: Path) { 25 | path = root + "config.bazelrc" 26 | } 27 | 28 | /// build:debug --//:mode=debug 29 | /// bazel build --config=debug [PACKAGE:RULE] 30 | mutating 31 | func setup(config: [String : XCodeBuildSetting]?) { 32 | let configs = config?.keys.map { $0 } ?? [] 33 | code = configs.map { config in 34 | """ 35 | build:\(config) --//:mode=\(config) 36 | """ 37 | }.sorted().withNewLine 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Bazel/Module.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Module.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/30. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import RuleBuilder 11 | 12 | /// https://github.com/bazelbuild/bazel-central-registry 13 | struct Module: BazelFile { 14 | let path: Path 15 | public let builder = CodeBuilder() 16 | 17 | init(_ root: Path) { 18 | path = root + "MODULE.bazel" 19 | 20 | setup() 21 | } 22 | 23 | var code: String { 24 | builder.build() 25 | } 26 | 27 | private func setup() { 28 | builder.add("module") { 29 | "name" => "example" 30 | "version" => "0.0.1" 31 | } 32 | builder.moduleDep(name: "bazel_skylib", version: "version") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Bazel/RootBUILD.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Build.swift 3 | // 4 | // 5 | // Created by Yume on 2022/12/8. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import PluginInterface 11 | import RuleBuilder 12 | 13 | /// /BUILD 14 | struct Build: BazelFile { 15 | let path: Path 16 | public let builder = CodeBuilder() 17 | 18 | init(_ root: Path) { 19 | path = root + "BUILD" 20 | } 21 | 22 | var code: String { 23 | builder.build() 24 | } 25 | 26 | /// configs: 27 | /// debug/release/... 28 | /// 29 | /// ```bazel 30 | /// select({ 31 | /// "//:deubg": "label1", 32 | /// "//:release": "label2", 33 | /// "//conditions:default": "label3", 34 | /// }) 35 | /// ``` 36 | /// 37 | /// ```shell 38 | /// bazel build target --//:mode=debug 39 | /// ``` 40 | func setup(config: [String : XCodeBuildSetting]?) { 41 | guard let config = config else { return } 42 | let configs = config.keys.map { $0 } 43 | 44 | builder.load(.string_flag) 45 | builder.add(.string_flag) { 46 | "name" => "mode" 47 | "build_setting_default" => "Debug" 48 | } 49 | 50 | for config in configs.sorted() { 51 | builder.add("config_setting") { 52 | "name" => "\(config)" 53 | "flag_values" => [":mode": "\(config)"] 54 | } 55 | } 56 | } 57 | 58 | /// export files not in [Bazel Package](https://bazel.build/concepts/build-ref) 59 | func exportUncategorizedFiles(_ kit: Kit) { 60 | let all = kit.project.all 61 | .filter(\.isFile) 62 | .compactMap(\.label) 63 | .filter { label in 64 | label.hasPrefix("//:") 65 | } 66 | .map { label in 67 | // TODO: remove //: 68 | """ 69 | "\(label.delete(prefix: "//:"))" 70 | """ 71 | } 72 | 73 | guard all.count != 0 else { return } 74 | 75 | builder.custom("") 76 | builder.custom(""" 77 | # export files not in [Bazel Package](https://bazel.build/concepts/build-ref) 78 | exports_files([ 79 | \(all.map(\.withComma).withNewLine.indent(1)) 80 | ]) 81 | """) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Bazel/TargetBUILD.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TargetBUILD.swift 3 | // 4 | // 5 | // Created by Yume on 2022/12/8. 6 | // 7 | 8 | 9 | import Foundation 10 | import PathKit 11 | import PluginInterface 12 | import RuleBuilder 13 | import Util 14 | import XCode 15 | 16 | /// /{TARGET}/BUILD 17 | struct TargetBuild: BazelFile { 18 | // MARK: Lifecycle 19 | 20 | init(_ root: Path, _ target: XCode.Target) { 21 | self.target = target 22 | targetPath = root + target.name 23 | path = targetPath + "BUILD" 24 | } 25 | 26 | // MARK: Internal 27 | 28 | let target: XCode.Target 29 | 30 | let path: Path 31 | let targetPath: Path 32 | private(set) var code = "" 33 | 34 | 35 | mutating 36 | func setup(_ kit: Kit) { 37 | code = target.generateCode(kit) 38 | } 39 | 40 | func mkpath() throws { 41 | do { 42 | try targetPath.mkpath() 43 | } catch { 44 | Log.codeGenerate.error("Fail to create dir \(targetPath.string)") 45 | throw error 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Bazel/Version.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Version.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/13. 6 | // 7 | 8 | public let version = "0.0.4" 9 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Bazel/WORKSPACE+Builder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Workspace.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/25. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Workspace { 11 | public struct Builder { 12 | // MARK: Public 13 | 14 | // mutating 15 | // public func `default`() { 16 | // http_archive() 17 | // rulesApple(repo: .v2_0_0) 18 | // rulesSwift(repo: .v1_5_1) 19 | // rulesPod(repo: .v4_1_0_412495) 20 | // rulesSPM(repo: .v0_11_2) 21 | // rulesSPM2() 22 | // rulesXCodeProj(repo: .v0_11_0) 23 | // rulesHammer(repo: .v3_4_3_3) 24 | // } 25 | 26 | mutating 27 | public func rulesPod(repo: Repo.Pod) { 28 | _code = """ 29 | # rules_pods 30 | http_archive( 31 | name = "rules_pods", 32 | urls = ["https://github.com/pinterest/PodToBUILD/releases/download/\(repo.rawValue)/PodToBUILD.zip"], 33 | # sha256 = "\(repo.sha256)", 34 | ) 35 | 36 | load("@rules_pods//BazelExtensions:workspace.bzl", "new_pod_repository") 37 | """ 38 | } 39 | 40 | mutating 41 | public func rulesSPM(repo: Repo.SPM) { 42 | _code = """ 43 | # rules_spm 44 | http_archive( 45 | name = "cgrindel_rules_spm", 46 | # sha256 = "\(repo.sha256)", 47 | strip_prefix = "rules_spm-\(repo.version)", 48 | urls = [ 49 | "http://github.com/cgrindel/rules_spm/archive/\(repo.rawValue).tar.gz", 50 | ], 51 | ) 52 | 53 | load( 54 | "@cgrindel_rules_spm//spm:deps.bzl", 55 | "spm_rules_dependencies", 56 | ) 57 | 58 | spm_rules_dependencies() 59 | """ 60 | } 61 | 62 | mutating 63 | public func rulesHammer(repo: Repo.Hammer) { 64 | _code = """ 65 | # rules_hammer 66 | http_archive( 67 | name = "xchammer", 68 | urls = [ "https://github.com/pinterest/xchammer/releases/download/\(repo.rawValue)/xchammer.zip" ], 69 | ) 70 | """ 71 | } 72 | 73 | mutating 74 | public func custom(code: String) { 75 | _code = code 76 | } 77 | 78 | // MARK: Internal 79 | 80 | internal func build() -> String { 81 | codes.joined(separator: "\n\n") 82 | } 83 | 84 | // MARK: Private 85 | 86 | private var codes: [String] = [] 87 | 88 | 89 | private var _code: String { 90 | get { "" } 91 | set { codes.append(newValue) } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Bazel/WORKSPACE.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WORKSPACE.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/27. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import Util 11 | 12 | /// /WORKSPACE 13 | struct Workspace: BazelFile { 14 | let path: Path 15 | public let builder = CodeBuilder() 16 | 17 | init(_ root: Path) { 18 | path = root + "WORKSPACE" 19 | } 20 | 21 | var code: String { 22 | builder.build() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Codegen+Framework.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Codegen+Framework.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/29. 6 | // 7 | 8 | import Foundation 9 | import RuleBuilder 10 | import XCode 11 | 12 | // TODO: https://github.com/XCodeBazelize/Bazelize/issues/8 framework(static/dynamic) 13 | 14 | extension Target { 15 | /// ios_framework(name, additional_linker_inputs, bundle_id, bundle_name, bundle_only, codesign_inputs, codesignopts, deps, executable_name, exported_symbols_lists, extension_safe, families, frameworks, hdrs, infoplists, ipa_post_processor, linkopts, minimum_deployment_os_version, minimum_os_version, platform_type, provisioning_profile, resources, stamp, strings, version) 16 | /// Builds and bundles an iOS Dynamic Framework. 17 | /// 18 | /// To use this framework for your app and extensions, list it in the frameworks attributes of those ios_application and/or ios_extension rules. 19 | func generateFrameworkCode(_ builder: CodeBuilder, _: Kit) { 20 | builder.load(.ios_framework) 21 | builder.add(.ios_framework) { 22 | "name" => name 23 | "bundle_id" => prefer(\.bundleID) 24 | "families" => prefer(\.deviceFamily) 25 | "minimum_os_version" => prefer(\.iOS) 26 | "infoplists" => { 27 | plist_file 28 | plist_auto 29 | // plist_default 30 | } 31 | "deps" => { 32 | ":\(name)_library" 33 | frameworks 34 | } 35 | StarlarkProperty.Visibility.public 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Codegen+StaticFramework.swift: -------------------------------------------------------------------------------- 1 | //// 2 | //// StaticFramework.swift 3 | //// 4 | //// 5 | //// Created by Yume on 2022/5/4. 6 | //// 7 | // 8 | // import Foundation 9 | // import XcodeProj 10 | // 11 | ////XcodeProj.PBXProductType.static 12 | // extension PBXNativeTarget { 13 | // func generateStaitcFrameworkCode(_ kit: Kit) -> String { 14 | //// let bundle_id = buildSettings.bundleID ?? "" 15 | // let bundle_id = "" 16 | // let podDeps: String = kit.pod?[name] ?? "" 17 | // let xcodeDeps = "" 18 | // let xcodeSPMDeps = spm_deps.joined(separator: "\n") 19 | // 20 | // let code = """ 21 | // load("@build_bazel_rules_apple//apple:ios.bzl", "ios_static_framework") 22 | // load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 23 | // 24 | // swift_library( 25 | // name = "_\(name)", 26 | // module_name = "\(name)", 27 | // srcs = [ 28 | // \(srcs) 29 | // ], 30 | // deps = [ 31 | // # Cocoapod Deps 32 | // \(podDeps.indent(2)) 33 | // 34 | // # XCode SPM Deps 35 | // \(xcodeSPMDeps.indent(2)) 36 | // ], 37 | // ) 38 | // 39 | // ios_static_framework( 40 | // name = "\(name)", 41 | // bundle_id = "\(bundle_id)", 42 | // families = [ 43 | // "iphone", 44 | // "ipad", 45 | // ], 46 | // minimum_os_version = "13.0", 47 | // infoplists = [":Info.plist"], 48 | // deps = [":_\(name)"], 49 | // frameworks = [ 50 | // # XCode Target Deps 51 | // \(xcodeDeps) 52 | // ], 53 | // ) 54 | // """ 55 | // 56 | // return code 57 | // } 58 | // } 59 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Codegen+StaticLibrary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StaticLibrary.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/10. 6 | // 7 | 8 | import Foundation 9 | import RuleBuilder 10 | import XCode 11 | 12 | extension Target { 13 | func generateStaticLibrary(_ builder: CodeBuilder, _: Kit) { 14 | builder.add("alias") { 15 | "name" => "\(name)" 16 | "actual" => "\(name)_library" 17 | StarlarkProperty.Visibility.public 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Codegen+Target.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Target+Codegen.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/29. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import Util 11 | import XCode 12 | 13 | extension Target { 14 | var isTest: Bool { 15 | switch native.productType { 16 | case .unitTestBundle: fallthrough 17 | case .ocUnitTestBundle: fallthrough 18 | case .uiTestBundle: 19 | return true 20 | default: return false 21 | } 22 | } 23 | 24 | func generateCode(_ kit: Kit) -> String { 25 | let builder = CodeBuilder() 26 | generateLibrary(builder, kit) 27 | 28 | generateLoadPlistFragment(builder) 29 | generatePlistFile(builder, kit) 30 | generatePlistAuto(builder) 31 | generatePlistDefault(builder) 32 | 33 | let name = name 34 | let native = native 35 | 36 | switch native.productType { 37 | case .application: 38 | generateStrings(builder, kit) 39 | generateApplicationCode(builder, kit) 40 | case .commandLineTool: 41 | generateCommandLineApplicationCode(builder, kit) 42 | case .framework: 43 | generateFrameworkCode(builder, kit) 44 | // case .staticFramework: break 45 | case .staticLibrary: 46 | generateStaticLibrary(builder, kit) 47 | // case .appExtension: break 48 | case .unitTestBundle: 49 | generateUnitTest(builder, kit) 50 | case .uiTestBundle: 51 | generateUITest(builder, kit) 52 | default: 53 | Log.codeGenerate.warning(""" 54 | Name: \(name, privacy: .public) 55 | Type: \(native.productType?.rawValue ?? "") not gen 56 | """) 57 | } 58 | return builder.build() 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Codegen+UITest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITest.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/7. 6 | // 7 | 8 | import Foundation 9 | import RuleBuilder 10 | import XCode 11 | 12 | extension Target { 13 | // MARK: Internal 14 | 15 | func generateUITest(_ builder: CodeBuilder, _ kit: Kit) { 16 | switch prefer(\.sdk) { 17 | case .iOS: generateIOSUITest(builder, kit) 18 | case .macOS: generateMacUITest(builder, kit) 19 | case .tvOS: generateTVUITest(builder, kit) 20 | case .watchOS: generateWatchUITest(builder, kit) 21 | default: break 22 | } 23 | } 24 | 25 | // MARK: Private 26 | 27 | /// https://github.com/bazelbuild/rules_swift/blob/master/doc/rules.md#swift_test 28 | /// ios_unit_test(name, data, deps, env, platform_type, runner, test_filter, test_host) 29 | private func generateIOSUITest(_ builder: CodeBuilder, _: Kit) { 30 | builder.load(.ios_ui_test) 31 | builder.add(.ios_ui_test) { 32 | "name" => "\(name)" 33 | "test_host" => prefer(\.testTargetName).map { target in 34 | "//\(target):\(target)" 35 | } 36 | "minimum_os_version" => prefer(\.iOS) 37 | "deps" => { 38 | ":\(name)_library" 39 | } 40 | StarlarkProperty.Visibility.public 41 | } 42 | } 43 | 44 | /// https://github.com/bazelbuild/rules_apple/blob/2.0.0/doc/rules-macos.md#macos_ui_test 45 | /// macos_ui_test(name, data, deps, env, platform_type, runner, test_filter, test_host) 46 | private func generateMacUITest(_ builder: CodeBuilder, _: Kit) { 47 | builder.load(.macos_ui_test) 48 | builder.add(.macos_ui_test) { 49 | "name" => "\(name)" 50 | "test_host" => prefer(\.testTargetName).map { target in 51 | "//\(target):\(target)" 52 | } 53 | "minimum_os_version" => prefer(\.macOS) 54 | "deps" => { 55 | ":\(name)_library" 56 | } 57 | StarlarkProperty.Visibility.public 58 | } 59 | } 60 | 61 | /// https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-tvos.md#tvos_ui_test 62 | /// tvos_ui_test(name, data, deps, env, platform_type, runner, test_filter, test_host) 63 | private func generateTVUITest(_ builder: CodeBuilder, _: Kit) { 64 | builder.load(.tvos_ui_test) 65 | builder.add(.tvos_ui_test) { 66 | "name" => "\(name)" 67 | "test_host" => prefer(\.testTargetName).map { target in 68 | "//\(target):\(target)" 69 | } 70 | "minimum_os_version" => prefer(\.tvOS) 71 | "deps" => { 72 | ":\(name)_library" 73 | } 74 | StarlarkProperty.Visibility.public 75 | } 76 | } 77 | 78 | /// https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-watchos.md#watchos_ui_test 79 | /// watchos_ui_test(name, data, deps, env, platform_type, runner, test_filter, test_host) 80 | private func generateWatchUITest(_ builder: CodeBuilder, _: Kit) { 81 | builder.load(.watchos_ui_test) 82 | builder.add(.watchos_ui_test) { 83 | "name" => "\(name)" 84 | "test_host" => prefer(\.testTargetName).map { target in 85 | "//\(target):\(target)" 86 | } 87 | "minimum_os_version" => prefer(\.watchOS) 88 | "deps" => { 89 | ":\(name)_library" 90 | } 91 | StarlarkProperty.Visibility.public 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Codegen+UnitTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnitTest.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/29. 6 | // 7 | 8 | import Foundation 9 | import RuleBuilder 10 | import XCode 11 | 12 | extension Target { 13 | // MARK: Internal 14 | 15 | func generateUnitTest(_ builder: CodeBuilder, _ kit: Kit) { 16 | switch prefer(\.sdk) { 17 | case .iOS: generateIOSUnitTest(builder, kit) 18 | case .macOS: generateMacUnitTest(builder, kit) 19 | case .tvOS: generateTVUnitTest(builder, kit) 20 | case .watchOS: generateWatchUnitTest(builder, kit) 21 | default: break 22 | } 23 | } 24 | 25 | // MARK: Private 26 | 27 | /// https://github.com/bazelbuild/rules_swift/blob/master/doc/rules.md#swift_test 28 | /// ios_unit_test(name, data, deps, env, platform_type, runner, test_filter, test_host) 29 | private func generateIOSUnitTest(_ builder: CodeBuilder, _: Kit) { 30 | builder.load(.ios_unit_test) 31 | builder.add(.ios_unit_test) { 32 | "name" => "\(name)" 33 | "minimum_os_version" => prefer(\.iOS) 34 | "deps" => { 35 | ":\(name)_library" 36 | } 37 | StarlarkProperty.Visibility.public 38 | } 39 | } 40 | 41 | /// https://github.com/bazelbuild/rules_apple/blob/2.0.0/doc/rules-macos.md#macos_unit_test 42 | /// macos_unit_test(name, data, deps, env, platform_type, runner, test_filter, test_host) 43 | private func generateMacUnitTest(_ builder: CodeBuilder, _: Kit) { 44 | builder.load(.macos_unit_test) 45 | builder.add(.macos_unit_test) { 46 | "name" => "\(name)" 47 | "minimum_os_version" => prefer(\.macOS) 48 | "deps" => { 49 | ":\(name)_library" 50 | } 51 | StarlarkProperty.Visibility.public 52 | } 53 | } 54 | 55 | /// https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-tvos.md#tvos_unit_test 56 | /// tvos_unit_test(name, data, deps, env, platform_type, runner, test_filter, test_host) 57 | private func generateTVUnitTest(_ builder: CodeBuilder, _: Kit) { 58 | builder.load(.tvos_unit_test) 59 | builder.add(.tvos_unit_test) { 60 | "name" => "\(name)" 61 | "minimum_os_version" => prefer(\.tvOS) 62 | "deps" => { 63 | ":\(name)_library" 64 | } 65 | StarlarkProperty.Visibility.public 66 | } 67 | } 68 | 69 | /// https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-watchos.md#watchos_unit_test 70 | /// watchos_unit_test(name, data, deps, env, platform_type, runner, test_filter, test_host) 71 | private func generateWatchUnitTest(_ builder: CodeBuilder, _: Kit) { 72 | builder.load(.watchos_unit_test) 73 | builder.add(.watchos_unit_test) { 74 | "name" => "\(name)" 75 | "minimum_os_version" => prefer(\.watchOS) 76 | "deps" => { 77 | ":\(name)_library" 78 | } 79 | StarlarkProperty.Visibility.public 80 | } 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Language/Codegen+Library.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Codegen+Library.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/23. 6 | // 7 | 8 | import Foundation 9 | import Util 10 | import XCode 11 | 12 | extension Target { 13 | func generateLibrary(_ builder: CodeBuilder, _ kit: Kit) { 14 | let name = name 15 | let cFamily = srcs_c + srcs_cpp + srcs_objc + srcs_objcpp 16 | 17 | generateAssets(builder, kit) 18 | 19 | switch (cFamily.isEmpty, srcs_swift.isEmpty) { 20 | case (true, false): 21 | generateSwiftLibrary(builder, kit) 22 | case (false, true): 23 | generateObjcLibrary(builder, kit) 24 | case (false, false): 25 | /// TODO: mix objc & swift 26 | Log.codeGenerate.warning("TODO: mix objc & swift") 27 | case (true, true): 28 | Log.codeGenerate.warning("Target(\(name, privacy: .public)) can't happen") 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Language/Codegen+ObjcLibrary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Codegen+ObjcLibrary.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/8. 6 | // 7 | 8 | import Foundation 9 | import RuleBuilder 10 | import XCode 11 | 12 | // TODO: https://github.com/XCodeBazelize/Bazelize/issues/7 13 | 14 | extension Target { 15 | /// https://bazel.build/reference/be/objective-c 16 | /// 17 | /// objc_library(name, deps, srcs, data, hdrs, alwayslink, compatible_with, copts, defines, deprecation, distribs, enable_modules, exec_compatible_with, exec_properties, features, includes, licenses, linkopts, module_map, module_name, non_arc_srcs, pch, restricted_to, runtime_deps, sdk_dylibs, sdk_frameworks, sdk_includes, tags, target_compatible_with, testonly, textual_hdrs, toolchains, visibility, weak_sdk_frameworks) 18 | func generateObjcLibrary(_ builder: CodeBuilder, _: Kit) { 19 | builder.load(.objc_library) 20 | builder.add(.objc_library) { 21 | "name" => "\(name)_objc" 22 | "module_name" => name 23 | "srcs" => { 24 | srcs_c 25 | srcs_cpp 26 | srcs_objc 27 | srcs_objcpp 28 | } 29 | "hdrs" => { 30 | headers // TODO: pch 31 | hpps 32 | } 33 | "enable_modules" => select(\.enableModules).starlark 34 | "pch" => { } 35 | "copts" => { 36 | "-fblocks" 37 | "-fobjc-arc" 38 | "-fPIC" 39 | "-fmodule-name=\(name)" 40 | } 41 | "testonly" => isTest 42 | "defines" => { } 43 | "linkopts" => { } 44 | "includes" => { 45 | /// public header "." 46 | /// https://github.com/bazelbuild/bazel/issues/92 47 | "." 48 | } 49 | "deps" => { 50 | frameworksLibrary 51 | } 52 | StarlarkProperty.Visibility.private 53 | } 54 | 55 | builder.add("alias") { 56 | "name" => "\(name)_library" 57 | "actual" => "\(name)_objc" 58 | StarlarkProperty.Visibility.public 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Language/Codegen+SwiftLibrary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Codegen+SwiftLibrary.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/4. 6 | // 7 | 8 | import Foundation 9 | import RuleBuilder 10 | import XCode 11 | 12 | extension Target { 13 | // MARK: Internal 14 | 15 | /// https://github.com/bazelbuild/rules_swift/blob/master/doc/rules.md#swift_library 16 | /// swift_library(name, alwayslink, copts, data, defines, deps, generated_header_name, generates_header, linkopts, linkstatic, module_name, private_deps, srcs, swiftc_inputs) 17 | func generateSwiftLibrary(_ builder: CodeBuilder, _ kit: Kit) { 18 | let plugin = kit.plugins.compactMap { 19 | $0[name] 20 | }.flatMap(\.deps) 21 | 22 | let builtins: [String] = kit.builtinPlugins 23 | .compactMap(\.target) 24 | .reduce([]) { origin, next in 25 | let data = next[name] ?? [] 26 | return origin + data 27 | } 28 | 29 | builder.load(.swift_library) 30 | builder.add(.swift_library) { 31 | "name" => "\(name)_swift" 32 | "module_name" => name 33 | "srcs" => { 34 | srcs_swift 35 | } 36 | "testonly" => isTest 37 | "deps" => { 38 | frameworksLibrary 39 | applicationHost 40 | plugin 41 | builtins 42 | } 43 | "data" => { 44 | if !assets.isEmpty { 45 | ":Assets" 46 | } 47 | xibs 48 | storyboards 49 | } 50 | "defines" => defines 51 | StarlarkProperty.Visibility.private 52 | } 53 | 54 | builder.add("alias") { 55 | "name" => "\(name)_library" 56 | "actual" => "\(name)_swift" 57 | StarlarkProperty.Visibility.public 58 | } 59 | } 60 | 61 | // MARK: Private 62 | 63 | private var defines: Starlark { 64 | select(\.swiftDefine).map { text -> [String] in 65 | let flags: [String] = (text ?? "").split(separator: " ").map(String.init) 66 | 67 | var isPreviousDefine = false 68 | var result: [String] = [] 69 | for flag in flags { 70 | if flag == "-D" { 71 | isPreviousDefine = true 72 | } else if isPreviousDefine { 73 | /// -D ABC 74 | result.append(flag) 75 | isPreviousDefine = false 76 | } else if flag.hasPrefix("-D") { 77 | /// -DABC 78 | result.append(flag.delete(prefix: "-D")) 79 | } 80 | } 81 | 82 | return result 83 | }.starlark 84 | } 85 | 86 | /// Unittest's dependency from application 87 | /// 88 | /// BUNDLE_LOADER 89 | /// $(TEST_HOST) 90 | /// TEST_HOST 91 | /// $(BUILT_PRODUCTS_DIR)/Example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Example 92 | /// build/Debug-iphoneos/Example.app//Example 93 | private var applicationHost: String? { 94 | guard let host = prefer(\.testHost) else { return nil } 95 | guard let _ = prefer(\.bundleLoader) else { return nil } 96 | guard let targetName = host.components(separatedBy: "/").last else { return nil } 97 | return "//\(targetName):\(targetName)_library" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Resource/Codegen+Asset.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Asset.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/9. 6 | // 7 | 8 | import Foundation 9 | import RuleBuilder 10 | import XCode 11 | 12 | extension Target { 13 | /// https://thanhvu.dev/en/2021/07/16/migrating-ios-project-to-bazel-part-2-2/ 14 | /// filegroup( 15 | /// name = "Assets", 16 | /// srcs = glob(["Assets.xcassets/**"]), 17 | /// visibility = ["//visibility:public"], 18 | /// ) 19 | /// 20 | /// data = [ 21 | /// "//Assets:Assets", 22 | /// "Base.lproj/Main.storyboard", 23 | /// "Base.lproj/LaunchScreen.storyboard", 24 | /// ], 25 | func generateAssets(_ builder: CodeBuilder, _: Kit) { 26 | /// //Example:Assets.xcassets 27 | /// to 28 | /// Assets.xcassets/** 29 | let files = assets 30 | .map { label in 31 | "\(label.delete(prefix: "//\(name):"))/**" 32 | } 33 | .map { (label: String) in 34 | // if label.hasPrefix("//:") { 35 | // return label.replacingOccurrences(of: "//:", with: "") 36 | // } 37 | // TODO: glob can't use `../` 38 | label 39 | } 40 | 41 | guard !files.isEmpty else { return } 42 | 43 | builder.add("filegroup") { 44 | "name" => "Assets" 45 | "srcs" => Starlark.glob(files) 46 | StarlarkProperty.Visibility.private 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Codegen/Resource/Codegen+Strings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/9. 6 | // 7 | 8 | import Foundation 9 | import RuleBuilder 10 | import XCode 11 | 12 | extension Target { 13 | func generateStrings(_ builder: CodeBuilder, _: Kit) { 14 | let files = allStrings 15 | 16 | guard !files.isEmpty else { return } 17 | 18 | builder.add("filegroup") { 19 | "name" => "Strings" 20 | "srcs" => files 21 | StarlarkProperty.Visibility.private 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Plugin/Plugin+Apple.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginApple.swift 3 | // 4 | // 5 | // Created by Yume on 2023/2/3. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - PluginApple 11 | 12 | /// https://github.com/bazelbuild/rules_apple 13 | final class PluginApple: PluginBuiltin { 14 | let repo: Repo.Apple = .v2_0_0 15 | 16 | override func module(_ builder: CodeBuilder) { 17 | builder.moduleDep( 18 | name: "rules_apple", 19 | version: repo.rawValue, 20 | repo_name: "build_bazel_rules_apple") 21 | } 22 | 23 | override func workspace(_ builder: CodeBuilder) { 24 | let version = repo.version 25 | builder.custom(""" 26 | # rules_apple 27 | http_archive( 28 | name = "build_bazel_rules_apple", 29 | sha256 = "\(repo.sha256)", 30 | url = "https://github.com/bazelbuild/rules_apple/releases/download/\(version)/rules_apple.\(version).tar.gz", 31 | ) 32 | 33 | load( 34 | "@build_bazel_rules_apple//apple:repositories.bzl", 35 | "apple_rules_dependencies", 36 | ) 37 | 38 | apple_rules_dependencies() 39 | 40 | load( 41 | "@build_bazel_apple_support//lib:repositories.bzl", 42 | "apple_support_dependencies", 43 | ) 44 | 45 | apple_support_dependencies() 46 | """) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Plugin/Plugin+Archive.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginArchive.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/31. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - PluginArchive 11 | 12 | final class PluginArchive: PluginBuiltin { 13 | override var name: String { "Bazel HTTP Archive" } 14 | override func workspace(_ builder: CodeBuilder) { 15 | builder.custom(""" 16 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 17 | """) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Plugin/Plugin+Imported.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Plugin+Imported.swift 3 | // 4 | // 5 | // Created by Yume on 2023/2/7. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import RuleBuilder 11 | import XCode 12 | 13 | // TODO: check static imported (xc)framework 14 | final class PluginImported: PluginBuiltin { 15 | private lazy var _target: [String : [String]]? = kit.project.targets 16 | .map { target in 17 | (target.name, target) 18 | } 19 | .toDictionary() 20 | .mapValues { target in 21 | target.importFrameworks.map { relativePath in 22 | let name = Path(relativePath).lastComponentWithoutExtension 23 | let label = "//:\(name)" 24 | return label 25 | } 26 | } 27 | 28 | override var target: [String : [String]]? { 29 | _target 30 | } 31 | 32 | override func build(_ builder: CodeBuilder) { 33 | let imported = kit.project.frameworks.filter { file in 34 | file.relativePath != nil 35 | } 36 | 37 | let frameworks = imported.filter { file in 38 | file.lastKnownFileType == .framework 39 | } 40 | 41 | let xcframeworks = imported.filter { file in 42 | file.lastKnownFileType == .xcframework 43 | } 44 | framework(builder, frameworks) 45 | xcframework(builder, xcframeworks) 46 | } 47 | 48 | private func xcframework(_ builder: CodeBuilder, _ files: [File]) { 49 | guard !files.isEmpty else { return } 50 | builder.load(.apple_dynamic_xcframework_import) 51 | 52 | for file in files { 53 | guard let relativePath = file.relativePath else { continue } 54 | let name = Path(relativePath).lastComponentWithoutExtension 55 | builder.add(.apple_dynamic_xcframework_import) { 56 | "name" => name 57 | "xcframework_imports" => Starlark.glob([ 58 | "\(relativePath)/**", 59 | ]) 60 | StarlarkProperty.Visibility.public 61 | } 62 | } 63 | } 64 | 65 | private func framework(_ builder: CodeBuilder, _ files: [File]) { 66 | guard !files.isEmpty else { return } 67 | builder.load(.apple_dynamic_framework_import) 68 | 69 | for file in files { 70 | guard let relativePath = file.relativePath else { continue } 71 | let name = Path(relativePath).lastComponentWithoutExtension 72 | builder.add(.apple_dynamic_framework_import) { 73 | "name" => name 74 | "framework_imports" => Starlark.glob([ 75 | "\(relativePath)/**", 76 | ]) 77 | StarlarkProperty.Visibility.public 78 | } 79 | } 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Plugin/Plugin+Linker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginLinker.swift 3 | // 4 | // 5 | // Created by Yume on 2023/2/3. 6 | // 7 | 8 | import Foundation 9 | 10 | /// deps 11 | /// "@rules_apple_linker//:zld" 12 | /// "@rules_apple_linker//:lld" 13 | 14 | /// https://github.com/keith/rules_apple_linker 15 | class PluginLinker: PluginBuiltin { 16 | override func module(_ builder: CodeBuilder) { 17 | builder.custom( 18 | """ 19 | bazel_dep(name = "rules_apple_linker", version = "0.3.0") 20 | """) 21 | } 22 | 23 | override func workspace(_ builder: CodeBuilder) { 24 | builder.custom(""" 25 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 26 | 27 | http_archive( 28 | name = "rules_apple_linker", 29 | sha256 = "a8aecd86d9c63677a8f1a3849c52c05d4aed1d1d9c209db2904f53f8973731d4", 30 | strip_prefix = "rules_apple_linker-0.3.0", 31 | url = "https://github.com/keith/rules_apple_linker/archive/refs/tags/0.3.0.tar.gz", 32 | ) 33 | 34 | load("@rules_apple_linker//:deps.bzl", "rules_apple_linker_deps") 35 | 36 | rules_apple_linker_deps() 37 | """) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Plugin/Plugin+PlistFragment.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginPlistFragment.swift 3 | // 4 | // 5 | // Created by Yume on 2023/2/3. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - PluginPlistFragment 11 | 12 | /// https://github.com/imWildCat/MinimalBazelFrameworkDemo 13 | final class PluginPlistFragment: PluginBuiltin { 14 | override func workspace(_ builder: CodeBuilder) { 15 | builder.custom(""" 16 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 17 | git_repository( 18 | name = "Plist", 19 | commit = "259ca0a5d77833728c18fa6365285559ce8cc0bf", 20 | remote = "https://github.com/imWildCat/MinimalBazelFrameworkDemo", 21 | ) 22 | """) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Plugin/Plugin+Swift.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginSwift.swift 3 | // 4 | // 5 | // Created by Yume on 2023/2/3. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - PluginSwift 11 | 12 | /// https://github.com/bazelbuild/rules_swift 13 | final class PluginSwift: PluginBuiltin { 14 | let repo: Repo.Swift = .v1_5_0 15 | 16 | override func module(_ builder: CodeBuilder) { 17 | builder.custom(""" 18 | bazel_dep(name = "rules_swift", version = "\(repo.rawValue)", repo_name = "build_bazel_rules_swift") 19 | """) 20 | } 21 | 22 | override func workspace(_ builder: CodeBuilder) { 23 | builder.custom(""" 24 | # rules_swift 25 | http_archive( 26 | name = "build_bazel_rules_swift", 27 | sha256 = "\(repo.sha256)", 28 | url = "https://github.com/bazelbuild/rules_swift/releases/download/\(repo.rawValue)/rules_swift.\( 29 | repo 30 | .rawValue).tar.gz", 31 | ) 32 | 33 | load( 34 | "@build_bazel_rules_swift//swift:repositories.bzl", 35 | "swift_rules_dependencies", 36 | ) 37 | 38 | swift_rules_dependencies() 39 | 40 | load( 41 | "@build_bazel_rules_swift//swift:extras.bzl", 42 | "swift_rules_extra_dependencies", 43 | ) 44 | 45 | swift_rules_extra_dependencies() 46 | """) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Plugin/Plugin+XCodeProj.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginXCodeProj.swift 3 | // 4 | // 5 | // Created by Yume on 2023/2/3. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - PluginXCodeProj 11 | 12 | /// https://github.com/buildbuddy-io/rules_xcodeproj 13 | final class PluginXCodeProj: PluginBuiltin { 14 | let repo: Repo.XCodeProj = .v0_12_3 15 | override func module(_ builder: CodeBuilder) { 16 | builder.custom(""" 17 | bazel_dep(name = "rules_xcodeproj", version = "\(repo.rawValue)") 18 | """) 19 | } 20 | 21 | override func workspace(_ builder: CodeBuilder) { 22 | builder.custom(""" 23 | # rules_xcodeproj 24 | http_archive( 25 | name = "com_github_buildbuddy_io_rules_xcodeproj", 26 | sha256 = "\(repo.sha256)", 27 | url = "https://github.com/buildbuddy-io/rules_xcodeproj/releases/download/\(repo.rawValue)/release.tar.gz", 28 | ) 29 | 30 | load( 31 | "@com_github_buildbuddy_io_rules_xcodeproj//xcodeproj:repositories.bzl", 32 | "xcodeproj_rules_dependencies", 33 | ) 34 | 35 | xcodeproj_rules_dependencies() 36 | """) 37 | } 38 | 39 | // TODO: 40 | /// top target 41 | /// custom project_name 42 | /// not support swift_library -> static library 43 | /// target_environments `device` need provision_profile 44 | override func build(_ builder: CodeBuilder) { 45 | let targets = kit.project.targets 46 | let other = targets 47 | .map(\.name) 48 | .sorted() 49 | .map { name in 50 | """ 51 | "//\(name):\(name)", 52 | """ 53 | }.withNewLine.indent(2) 54 | 55 | builder.load(""" 56 | load( 57 | "@com_github_buildbuddy_io_rules_xcodeproj//xcodeproj:defs.bzl", 58 | "top_level_target", 59 | "xcodeproj", 60 | ) 61 | """) 62 | 63 | builder.custom(""" 64 | # Xcode 65 | xcodeproj( 66 | name = "xcodeproj", 67 | # Custom Project Name 68 | project_name = "App", 69 | tags = ["manual"], 70 | top_level_targets = [ 71 | # main target, maybe some `ios_application` 72 | top_level_target(":App", target_environments = ["device", "simulator"]), 73 | # all other target 74 | \(other) 75 | ], 76 | ) 77 | """) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Plugin/PluginBuiltin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginBuiltin.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/31. 6 | // 7 | 8 | // MARK: - PluginBuiltin 9 | 10 | class PluginBuiltin { 11 | unowned let kit: Kit 12 | init(_ kit: Kit) { 13 | self.kit = kit 14 | } 15 | 16 | var name: String { "Builtin Plugin" } 17 | var description: String { "" } 18 | var version: String { "0.0.1" } 19 | var url: String { "Builtin" } 20 | 21 | func module(_: CodeBuilder) { } 22 | func workspace(_: CodeBuilder) { } 23 | func build(_: CodeBuilder) { } 24 | 25 | var target: [String: [String]]? { nil } 26 | var custom: [Custom]? { nil } 27 | 28 | var tip: String? { nil } 29 | 30 | struct Custom { 31 | let path: String 32 | let content: String 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Repo/Repo+Apple.swift: -------------------------------------------------------------------------------- 1 | 2 | extension Repo { 3 | /// https://github.com/bazelbuild/rules_apple 4 | enum Apple: String { 5 | case v2_0_0 = "2.0.0" 6 | case v2_0_0_rc2 = "2.0.0-rc2" 7 | case v2_0_0_rc1 = "2.0.0-rc1" 8 | case v1_1_3 = "1.1.3" 9 | case v1_1_2 = "1.1.2" 10 | // MARK: Internal 11 | 12 | var version: String { 13 | if rawValue.first == "v" { 14 | return String(rawValue.dropFirst()) 15 | } 16 | return rawValue 17 | } 18 | 19 | var sha256: String { 20 | switch self { 21 | case .v2_0_0: return "43737f28a578d8d8d7ab7df2fb80225a6b23b9af9655fcdc66ae38eb2abcf2ed" 22 | case .v2_0_0_rc2: return "44c803313904f94ea14f55269c9ffabd355f66c9dca98768b907aff61c97abc3" 23 | case .v2_0_0_rc1: return "bf48acc73e536d36b4942857647ac219512d4984aca6ae083a11fd3fd540faa0" 24 | case .v1_1_3: return "f94e6dddf74739ef5cb30f000e13a2a613f6ebfa5e63588305a71fce8a8a9911" 25 | case .v1_1_2: return "90e3b5e8ff942be134e64a83499974203ea64797fd620eddeb71b3a8e1bff681" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/BazelizeKit/Repo/Repo+Hammer.swift: -------------------------------------------------------------------------------- 1 | 2 | extension Repo { 3 | /// https://github.com/pinterest/xchammer 4 | enum Hammer: String { 5 | case v3_4_3_3 = "v3.4.3.3" 6 | case v3_4_3_2 = "v3.4.3.2" 7 | case v3_4_3_1 = "v3.4.3.1" 8 | case v3_4_2_2 = "v3.4.2.2" 9 | // MARK: Internal 10 | 11 | var version: String { 12 | if rawValue.first == "v" { 13 | return String(rawValue.dropFirst()) 14 | } 15 | return rawValue 16 | } 17 | 18 | var sha256: String { 19 | switch self { 20 | case .v3_4_3_3: return "1fe8c3a283f3cfc3c7a3765e185103949bfa889c0e806897ac7ac247582d9a80" 21 | case .v3_4_3_2: return "cddf5fd1d0b6015a03a0b6eacd675093c9e0175c25357ab35de2e9a928d60fa5" 22 | case .v3_4_3_1: return "725d55d3f62e82c14544d479877862a4c2b1d4d7e903b38feb239c5a65aaa4c9" 23 | case .v3_4_2_2: return "20892993972a0a1b8dae305eb4f822d6374848a5e5631a811b88d73a0faa038a" 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Sources/BazelizeKit/Repo/Repo+Pod.swift: -------------------------------------------------------------------------------- 1 | 2 | extension Repo { 3 | /// https://github.com/pinterest/PodToBUILD 4 | enum Pod: String { 5 | case v4_1_0_412495 = "4.1.0-412495" 6 | case v4_0_0_5787125 = "4.0.0-5787125" 7 | case v4_0_0_2096f5c = "4.0.0-2096f5c" 8 | case v4_0_0_7673f06 = "4.0.0-7673f06" 9 | case v4_0_0_f96b657 = "4.0.0-f96b657" 10 | // MARK: Internal 11 | 12 | var version: String { 13 | if rawValue.first == "v" { 14 | return String(rawValue.dropFirst()) 15 | } 16 | return rawValue 17 | } 18 | 19 | var sha256: String { 20 | switch self { 21 | case .v4_1_0_412495: return "c96bbfb6364a76e09d8239914990328e66074096038728f1a1b26c62d9081af6" 22 | case .v4_0_0_5787125: return "d697642a6ca9d4d0441a5a6132e9f2bf70e8e9ee0080c3c780fe57e698e79d82" 23 | case .v4_0_0_2096f5c: return "27e168882f74adc33c901d4c930bddbdc38282185bedb8737290022891737f02" 24 | case .v4_0_0_7673f06: return "92eccc22950dcc86e86f4cbc3fb538b4b927da2cd765627ba099f30aa7dbf73b" 25 | case .v4_0_0_f96b657: return "1faf148ba6f0e494d5ccd730ae26130a5966161be034e775f76317897cf68aad" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/BazelizeKit/Repo/Repo+SPM.swift: -------------------------------------------------------------------------------- 1 | 2 | extension Repo { 3 | /// https://github.com/cgrindel/rules_spm 4 | enum SPM: String { 5 | case v0_11_2 = "v0.11.2" 6 | case v0_11_1 = "v0.11.1" 7 | case v0_11_0 = "v0.11.0" 8 | case v0_10_0 = "v0.10.0" 9 | case v0_9_0 = "v0.9.0" 10 | // MARK: Internal 11 | 12 | var version: String { 13 | if rawValue.first == "v" { 14 | return String(rawValue.dropFirst()) 15 | } 16 | return rawValue 17 | } 18 | 19 | var sha256: String { 20 | switch self { 21 | case .v0_11_2: return "777e687245faa7340488e61f5abb23b95b4c0e27e05f7cea7318c03e4cc38289" 22 | case .v0_11_1: return "d36697e83720e4dc29a97c7a8f1a02858b3c6ce51fa645be3faa03f51dbc1151" 23 | case .v0_11_0: return "03718eb865a100ba4449ebcbca6d97bf6ea78fa17346ce6d55532312e8bf9aa8" 24 | case .v0_10_0: return "ba4310ba33cd1864a95e41d1ceceaa057e56ebbe311f74105774d526d68e2a0d" 25 | case .v0_9_0: return "b85d8d089c5f707b451f142718b32c647b22d0a72a5b7c1832af0f3e4d25be4f" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/BazelizeKit/Repo/Repo+Swift.swift: -------------------------------------------------------------------------------- 1 | 2 | extension Repo { 3 | /// https://github.com/bazelbuild/rules_swift 4 | enum Swift: String { 5 | case v1_5_1 = "1.5.1" 6 | case v1_5_0 = "1.5.0" 7 | case v1_4_0 = "1.4.0" 8 | case v1_3_0 = "1.3.0" 9 | case v1_2_0 = "1.2.0" 10 | // MARK: Internal 11 | 12 | var version: String { 13 | if rawValue.first == "v" { 14 | return String(rawValue.dropFirst()) 15 | } 16 | return rawValue 17 | } 18 | 19 | var sha256: String { 20 | switch self { 21 | case .v1_5_1: return "84e2cc1c9e3593ae2c0aa4c773bceeb63c2d04c02a74a6e30c1961684d235593" 22 | case .v1_5_0: return "32f95dbe6a88eb298aaa790f05065434f32a662c65ec0a6aabdaf6881e4f169f" 23 | case .v1_4_0: return "c244e9f804a48c27fe490150c762d8b0c868b23ef93dc4e3f93d8117ca216d92" 24 | case .v1_3_0: return "2ce874c8c34a03a0a33bfb0c8100f0be32279e0a40f5b794fd943f15441e034a" 25 | case .v1_2_0: return "51efdaf85e04e51174de76ef563f255451d5a5cd24c61ad902feeadafc7046d9" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/BazelizeKit/Repo/Repo+XCodeProj.swift: -------------------------------------------------------------------------------- 1 | 2 | extension Repo { 3 | /// https://github.com/buildbuddy-io/rules_xcodeproj 4 | enum XCodeProj: String { 5 | case v1_0_0rc1 = "1.0.0rc1" 6 | case v0_12_3 = "0.12.3" 7 | case v0_12_2 = "0.12.2" 8 | case v0_12_0 = "0.12.0" 9 | case v0_11_0 = "0.11.0" 10 | // MARK: Internal 11 | 12 | var version: String { 13 | if rawValue.first == "v" { 14 | return String(rawValue.dropFirst()) 15 | } 16 | return rawValue 17 | } 18 | 19 | var sha256: String { 20 | switch self { 21 | case .v1_0_0rc1: return "0164d576945121361b28706a5bbe2ea6f834f93ae65062e5592544b728577d30" 22 | case .v0_12_3: return "f3f9b6db442892af4d16c2819d921ef8607ef86276ca8c762b82800f5d6755ad" 23 | case .v0_12_2: return "9c86784491854f205b075e5c4d8a838612d433d9454a226d270ad1a17ad8d634" 24 | case .v0_12_0: return "630e3434b49e80783430ef470c0e9a7f1c8b4e648f789b9fe324fcd37ade8a19" 25 | case .v0_11_0: return "2533b977ac8540a30323fde7fdb6ca49219edd21d3753b69d43f39c576b11a88" 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/BazelizeKit/Repo/Repo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Repo.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/5. 6 | // 7 | 8 | // MARK: - Repo 9 | 10 | enum Repo { } 11 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Rule/LoadableRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoadableRule.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/27. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | // MARK: - BuildableRule 12 | 13 | protocol BuildableRule { 14 | /// "ios_application" 15 | var rule: String { get } 16 | } 17 | 18 | // MARK: - LoadableRule 19 | 20 | protocol LoadableRule: BuildableRule { 21 | /// "@build_bazel_rules_apple//apple:ios.bzl" 22 | static var target: String { get } 23 | 24 | /// load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application") 25 | var load: String { get } 26 | } 27 | 28 | extension BuildableRule where Self: RawRepresentable, Self.RawValue == String { 29 | var rule: String { 30 | rawValue 31 | } 32 | } 33 | 34 | extension LoadableRule { 35 | var load: String { 36 | """ 37 | load("\(Self.target)", "\(rule)") 38 | """ 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Rule/RulesApple.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RulesApple.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/1. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://github.com/bazelbuild/rules_apple/tree/master/doc 11 | enum RulesApple { 12 | enum IOS: String, LoadableRule { 13 | static let target = "@build_bazel_rules_apple//apple:ios.bzl" 14 | 15 | case ios_application 16 | case ios_app_clip 17 | case ios_extension 18 | case ios_imessage_application 19 | case ios_imessage_extension 20 | case ios_sticker_pack_extension 21 | case ios_framework 22 | case ios_static_framework 23 | case ios_dynamic_framework 24 | 25 | case ios_ui_test 26 | case ios_ui_test_suite 27 | case ios_unit_test 28 | case ios_unit_test_suite 29 | case ios_build_test 30 | } 31 | 32 | enum Mac: String, LoadableRule { 33 | static let target = "@build_bazel_rules_apple//apple:macos.bzl" 34 | 35 | case macos_application 36 | case macos_bundle 37 | case macos_command_line_application 38 | case macos_extension 39 | 40 | case macos_ui_test 41 | case macos_unit_test 42 | case macos_build_test 43 | 44 | case macos_dylib 45 | case macos_kernel_extension 46 | case macos_quick_look_plugin 47 | case macos_spotlight_importer 48 | case macos_xpc_service 49 | } 50 | 51 | enum TV: String, LoadableRule { 52 | static let target = "@build_bazel_rules_apple//apple:tvos.bzl" 53 | 54 | case tvos_application 55 | case tvos_extension 56 | case tvos_static_framework 57 | case tvos_dynamic_framework 58 | case tvos_ui_test 59 | case tvos_unit_test 60 | case tvos_build_test 61 | } 62 | 63 | enum Watch: String, LoadableRule { 64 | static let target = "@build_bazel_rules_apple//apple:watchos.bzl" 65 | 66 | case watchos_application 67 | case watchos_extension 68 | case watchos_static_framework 69 | case watchos_dynamic_framework 70 | case watchos_ui_test 71 | case watchos_unit_test 72 | case watchos_build_test 73 | } 74 | 75 | enum Verion: String, LoadableRule { 76 | static let target = "@build_bazel_rules_apple//apple:versioning.bzl" 77 | 78 | case apple_bundle_version 79 | } 80 | 81 | enum Apple: String, LoadableRule { 82 | static let target = "@build_bazel_rules_apple//apple:apple.bzl" 83 | 84 | case apple_dynamic_framework_import 85 | case apple_dynamic_xcframework_import 86 | case apple_static_framework_import 87 | case apple_static_library 88 | case apple_static_xcframework 89 | case apple_static_xcframework_import 90 | case apple_universal_binary 91 | case apple_xcframework 92 | case local_provisioning_profile 93 | case provisioning_profile_repository 94 | case provisioning_profile_repository_extension 95 | } 96 | 97 | enum Resource: String, LoadableRule { 98 | static let target = "@build_bazel_rules_apple//apple:resources.bzl" 99 | 100 | case apple_bundle_import 101 | case apple_core_data_model 102 | case apple_core_ml_library 103 | case apple_resource_bundle 104 | case apple_resource_group 105 | case swift_apple_core_ml_library 106 | case swift_intent_library 107 | } 108 | } 109 | 110 | 111 | 112 | // options 113 | // https://github.com/bazelbuild/rules_apple/blob/master/doc/common_info.md 114 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Rule/RulesConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RulesConfig.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/5. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://github.com/bazelbuild/bazel-skylib/blob/main/docs/common_settings_doc.md 11 | enum RulesConfig: String, LoadableRule { 12 | static let target = "@bazel_skylib//rules:common_settings.bzl" 13 | 14 | case bool_flag 15 | case bool_setting 16 | 17 | case int_flag 18 | case int_setting 19 | 20 | case string_flag 21 | case string_setting 22 | 23 | case string_list_flag 24 | case string_list_setting 25 | 26 | case BuildSettingInfo 27 | } 28 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Rule/RulesObjc.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RulesObjc.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/22. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://bazel.build/reference/be/objective-c 11 | enum RulesObjc: String, LoadableRule { 12 | static let target = "@rules_cc//cc:defs.bzl" 13 | 14 | case j2objc_library 15 | case objc_import 16 | case objc_library 17 | case available_xcodes 18 | case xcode_config 19 | case xcode_version 20 | } 21 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Rule/RulesPlist.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RulesPlist.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/26. 6 | // 7 | 8 | import Foundation 9 | 10 | enum RulesPlist: String, LoadableRule { 11 | static let target = "@Plist//build-system/ios-utils:plist_fragment.bzl" 12 | 13 | case plist_fragment 14 | } 15 | -------------------------------------------------------------------------------- /Sources/BazelizeKit/Rule/RulesSwift.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RulesSwift.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/1. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://github.com/bazelbuild/rules_swift 11 | enum RulesSwift: String, LoadableRule { 12 | static let target = "@build_bazel_rules_swift//swift:swift.bzl" 13 | 14 | case swift_binary 15 | case swift_c_module 16 | case swift_feature_allowlist 17 | case swift_grpc_library 18 | case swift_import 19 | case swift_library 20 | case swift_module_alias 21 | case swift_package_configuration 22 | case swift_proto_library 23 | case swift_test 24 | } 25 | -------------------------------------------------------------------------------- /Sources/Cocoapod/CodeGen/NewPod.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NewPodRepository.swift 3 | // 4 | // 5 | // Created by Yume on 2022/5/11. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - NewPodRepository 11 | 12 | /// https://github.com/${organization,user}/${repo}/archive/${commit,branch,tag}.zip 13 | /// 14 | /// new_pod_repository( 15 | /// name = "PINOperation", 16 | /// url = "https://github.com/pinterest/PINOperation/archive/1.2.1.zip", 17 | /// ) 18 | protocol NewPodRepository { 19 | var name: String { get } 20 | var url: String { get } 21 | 22 | var code: String { get } 23 | } 24 | 25 | extension NewPodRepository { 26 | var code: String { 27 | """ 28 | new_pod_repository( 29 | name = "\(name)", 30 | url = "\(url)", 31 | ) 32 | """ 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Cocoapod/Model/PodSpec.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PodSpec.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/25. 6 | // 7 | 8 | import Foundation 9 | import Util 10 | 11 | // MARK: - PodSpec 12 | 13 | struct PodSpec: Codable, JSONParsable, NewPodRepository { 14 | let name: String 15 | let source: PodSpecSource 16 | 17 | var url: String { 18 | source.url 19 | } 20 | } 21 | 22 | // MARK: - PodSpecSource 23 | 24 | // "source": { 25 | // "git": "https://github.com/yagiz/Bagel.git", 26 | // "tag": "1.4.0" 27 | // }, 28 | struct PodSpecSource: Codable { 29 | let git: String 30 | let tag: String 31 | 32 | /// https://github.com/yagiz/Bagel/archive/1.4.0.zip 33 | var url: String { 34 | let base = git.replacingOccurrences(of: ".git", with: "") 35 | return "\(base)/archive/\(tag).zip" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Sources/Cocoapod/Model/Podfile.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Podfile.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/25. 6 | // 7 | 8 | import AnyCodable 9 | import Foundation 10 | import PathKit 11 | import Util 12 | 13 | // MARK: - Podfile 14 | 15 | struct Podfile: Codable, JSONParsable { 16 | // MARK: Internal 17 | 18 | static func process(_ path: Path) async throws -> Podfile { 19 | /// pod ipc podfile-json Podfile 20 | let data = try await Process.execute( 21 | Env.pod, 22 | arguments: "ipc", "podfile-json", path.string) 23 | 24 | return try Podfile.parse(data) 25 | } 26 | 27 | 28 | subscript(targetName: String) -> [String] { 29 | self[target: targetName]?.depsCode ?? [] 30 | } 31 | 32 | // MARK: Fileprivate 33 | 34 | fileprivate let target_definitions: [PodDefinition] 35 | 36 | fileprivate var flatTarget: [PodChildren] { 37 | target_definitions.flatMap(\.flatTarget) 38 | } 39 | 40 | 41 | fileprivate subscript(target targetName: String) -> PodChildren? { 42 | flatTarget.first { _target in 43 | _target.name == targetName 44 | } 45 | } 46 | } 47 | 48 | // MARK: - PodDefinition 49 | 50 | private struct PodDefinition: Codable { 51 | fileprivate let children: [PodChildren] 52 | fileprivate var flatTarget: [PodChildren] { 53 | children.flatMap(\.flatTarget) 54 | } 55 | } 56 | 57 | // MARK: - PodChildren 58 | 59 | private struct PodChildren: Codable { 60 | // MARK: Internal 61 | 62 | var depsCode: [String] { 63 | dependencies? 64 | .sorted { lhs, rhs in 65 | lhs.code < rhs.code 66 | } 67 | .map(\.code) ?? [] 68 | } 69 | 70 | // MARK: Fileprivate 71 | 72 | /// Target 73 | fileprivate let name: String 74 | fileprivate let dependencies: [PodDependency]? 75 | 76 | 77 | fileprivate var flatTarget: [PodChildren] { 78 | if let child = children { 79 | return [self] + child.flatMap(\.flatTarget) 80 | } else { 81 | return [self] 82 | } 83 | } 84 | 85 | // MARK: Private 86 | 87 | // "configuration_pod_whitelist": { 88 | // "Debug": [ 89 | // "Peek", 90 | // "Bagel" 91 | // ] 92 | // }, 93 | // let configuration_pod_whitelist 94 | private let children: [PodChildren]? 95 | } 96 | 97 | // MARK: - PodDependency 98 | 99 | private struct PodDependency: Codable { 100 | // MARK: Lifecycle 101 | 102 | init(from decoder: Decoder) throws { 103 | let container = try decoder.singleValueContainer() 104 | do { 105 | let name = try container.decode(String.self) 106 | (package, target) = Util.parse(name: name) 107 | return 108 | } catch { 109 | let podGraph = try container.decode([String: AnyCodable].self) 110 | guard let name = podGraph.keys.first else { 111 | throw PodError.reason(""" 112 | Parse Podfile fail 113 | Pod: \(podGraph) 114 | """) 115 | } 116 | 117 | (package, target) = Util.parse(name: name) 118 | return 119 | } 120 | } 121 | 122 | // MARK: Internal 123 | 124 | let package: String 125 | let target: String 126 | 127 | 128 | /// //Vendor/__PACKAGE__:__TARGET__ 129 | /// 130 | /// subpsec `Core` in `PINCache` 131 | /// //Vendor/PINCache:Core 132 | /// 133 | /// "//Vendor/RxSwift:RxSwift", 134 | var code: String { 135 | """ 136 | //Vendor/\(package):\(target) 137 | """ 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Sources/Cocoapod/PodError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PodError.swift 3 | // 4 | // 5 | // Created by Yume on 2022/5/11. 6 | // 7 | 8 | import Foundation 9 | 10 | enum PodError: Error { 11 | case reason(String) 12 | } 13 | -------------------------------------------------------------------------------- /Sources/Cocoapod/Util.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Util.swift 3 | // 4 | // 5 | // Created by Yume on 2022/5/11. 6 | // 7 | 8 | import Foundation 9 | 10 | enum Util { 11 | /// name: AFNetworking 12 | /// package: AFNetworking 13 | /// target: AFNetworking 14 | /// 15 | /// name AFNetworking/NSURLSession 16 | /// package: AFNetworking 17 | /// target: NSURLSession 18 | static func parse(name: String) -> (package: String, target: String) { 19 | let parts = name.split(separator: "/").map(String.init) 20 | switch parts.count { 21 | case 1: 22 | return (name, name) 23 | /// 2 up 24 | default: 25 | return (parts[0], parts[1]) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/PluginInterface/Plugin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Plugin.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/16. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | 11 | // MARK: - PluginBuilder 12 | 13 | open class PluginBuilder { 14 | // MARK: Lifecycle 15 | 16 | public init() { } 17 | 18 | // MARK: Open 19 | 20 | open func build(_: XCodeProject) async throws -> Plugin? { 21 | fatalError("You have to override this method.") 22 | } 23 | } 24 | 25 | 26 | // MARK: - Plugin 27 | 28 | public protocol Plugin: AnyObject { 29 | var name: String { get } 30 | var description: String { get } 31 | var version: String { get } 32 | var url: String { get } 33 | 34 | static func load(_ proj: XCodeProject) async throws -> Self? 35 | 36 | subscript(_: String) -> PluginTarget? { get } 37 | 38 | /// # rules_pods 39 | /// http_archive( 40 | /// name = "rules_pods", 41 | /// urls = ["https://github.com/pinterest/PodToBUILD/releases/download/4.1.0-412495/PodToBUILD.zip"], 42 | /// # sha256 = "", 43 | /// ) 44 | /// 45 | /// load("@rules_pods//BazelExtensions:workspace.bzl", "new_pod_repository") 46 | func workspace() -> String 47 | 48 | /// {WORKSPACE}/Pods.WORKSPACE 49 | func generateFile(_ workspace: Path) throws 50 | 51 | /// bazel run @rules_pods//:update_pods -- --src_root `PWD` 52 | func tip() 53 | } 54 | 55 | // MARK: - PluginTarget 56 | 57 | public protocol PluginTarget { 58 | var deps: [String] { get } 59 | var framework: [String] { get } 60 | } 61 | -------------------------------------------------------------------------------- /Sources/PluginInterface/XCodeBuildSetting.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XCodeBuildSetting.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/29. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - XCodeBuildSetting 11 | 12 | public protocol XCodeBuildSetting { 13 | var name: String { get } 14 | 15 | var setting: [String: Any] { get } 16 | 17 | var bundleID: String? { get } 18 | 19 | var team: String? { get } 20 | 21 | /// "5.0" 22 | var swiftVersion: String? { get } 23 | 24 | var deviceFamily: [String] { get } 25 | 26 | /// SDKROOT 27 | var sdk: SDK? { get } 28 | 29 | // MARK: - OS version - 30 | var iOS: String? { get } 31 | 32 | var macOS: String? { get } 33 | 34 | var tvOS: String? { get } 35 | 36 | var watchOS: String? { get } 37 | 38 | var driverKit: String? { get } 39 | 40 | // MARK: - plist - 41 | /// "YES" 42 | var generateInfoPlist: Bool { get } 43 | 44 | var plist: [String] { get } 45 | 46 | /// plist gen keys 47 | var plistKeys: [String] { get } 48 | 49 | /// "ABCDEF/Info.plist" 50 | var infoPlist: String? { get } 51 | 52 | var defaultPlist: [String] { get } 53 | 54 | /// "LaunchScreen" 55 | var launch: String? { get } 56 | 57 | /// "Main" 58 | var storyboard: String? { get } 59 | 60 | var swiftDefine: String? { get } 61 | 62 | /// ios application uitest `Target Application` 63 | /// TEST_TARGET_NAME 64 | var testTargetName: String? { get } 65 | 66 | /// ios application unittest `Host Application` 67 | /// TEST_HOST 68 | var testHost: String? { get } 69 | 70 | /// ios application unittest `Allow testing Host Application APIs` 71 | /// BUNDLE_LOADER 72 | var bundleLoader: String? { get } 73 | 74 | /// CLANG_ENABLE_MODULES 75 | var enableModules: Bool { get } 76 | } 77 | 78 | // MARK: - SDK 79 | 80 | public enum SDK: String, Encodable { 81 | case iOS = "iphoneos" 82 | case macOS = "macosx" 83 | case tvOS = "appletvos" 84 | case watchOS = "watchos" 85 | case DriverKit = "driverkit" 86 | } 87 | -------------------------------------------------------------------------------- /Sources/PluginInterface/XCodeProject.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XCodeProject.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/25. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | 11 | // MARK: - XCodeProject 12 | 13 | public protocol XCodeProject: AnyObject { 14 | /// WORKSPACE 15 | var workspacePath: Path { get } 16 | 17 | /// xxx.xcodeproj 18 | var projectPath: Path { get } 19 | 20 | /// relative path to local spm 21 | // var localSPM: [String] { get } 22 | // 23 | // var spm: [XCodeSPM] { get } 24 | 25 | var targets: [XCodeTarget] { get } 26 | 27 | var config: [String: XCodeBuildSetting]? { get } 28 | 29 | var preferConfig: String? { get } 30 | 31 | func transformToLabel(_ path: String?) -> String? 32 | } 33 | 34 | extension XCodeProject { 35 | // MARK: Public 36 | 37 | public func transformToLabel(_ relativePath: String?) -> String? { 38 | /// DEF/Base.lproj/LaunchScreen.storyboard 39 | guard let path = relativePath else { return nil } 40 | 41 | let commentedLabel = """ 42 | # \(path) 43 | """ 44 | guard let _package = path.split(separator: "/").first else { 45 | return commentedLabel 46 | } 47 | /// DEF 48 | let package = String(_package) 49 | /// Base.lproj/LaunchScreen.storyboard 50 | guard let restPath = path.delete(prefix: package + "/") else { 51 | return commentedLabel 52 | } 53 | 54 | if check(package) { 55 | return """ 56 | //\(package):\(restPath) 57 | """ 58 | } else { 59 | return """ 60 | //:\(package)/\(restPath) 61 | """ 62 | } 63 | } 64 | 65 | // MARK: Private 66 | 67 | private typealias Package = String 68 | 69 | private func check(_ package: Package) -> Bool { 70 | targets.map(\.name).contains(package) 71 | } 72 | } 73 | 74 | extension String { 75 | fileprivate func delete(prefix: String) -> String? { 76 | guard hasPrefix(prefix) else { return nil } 77 | return String(dropFirst(prefix.count)) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Sources/PluginInterface/XCodeTarget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XCodeTarget.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/29. 6 | // 7 | 8 | import Foundation 9 | 10 | public protocol XCodeTarget { 11 | /// Target Name 12 | var name: String { get } 13 | 14 | /// Release/Debug/More ... 15 | var configs: [String] { get } 16 | 17 | var config: [String: XCodeBuildSetting] { get } 18 | 19 | /// `.h` & `.pch` 20 | /// headers in current Target(Bazel Package) 21 | var headers: [String] { get } 22 | 23 | /// `.hpp` 24 | /// headers in current Target(Bazel Package) 25 | var hpps: [String] { get } 26 | 27 | /// all build file 28 | var srcs: [String] { get } 29 | var srcs_c: [String] { get } 30 | var srcs_objc: [String] { get } 31 | var srcs_cpp: [String] { get } 32 | var srcs_objcpp: [String] { get } 33 | var srcs_swift: [String] { get } 34 | var srcs_metal: [String] { get } 35 | 36 | var resources: [String] { get } 37 | 38 | /// use for `frameworks` 39 | var importFrameworks: [String] { get } 40 | 41 | /// use for `frameworks` 42 | // var frameworks: [String] { get } 43 | 44 | // /// use for `xxx_library.deps` 45 | // var frameworks_library: [String] { get } 46 | // 47 | // /// use for `sdk_frameworks` 48 | // var sdkFrameworks: [String] { get } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/PluginLoader/Core.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/24. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import PluginInterface 11 | import Util 12 | 13 | /// start -> load xcode 14 | /// start -> load plugin list 15 | /// load plugin list -> build plugin 16 | /// build plugin -> load plugin 17 | /// load xcode -> load plugin 18 | public func load(manifest: Path, _ proj: XCodeProject) async throws -> [Plugin] { 19 | guard manifest.exists else { 20 | return [] 21 | } 22 | 23 | Log.pluginLoader.info("Parse Manifest: \(manifest.string)") 24 | let infos = try parseManifest(manifest) 25 | 26 | Log.pluginLoader.info("Build Plugins") 27 | let buildPlugins = try PluginBuilder.build(plugins: infos) 28 | 29 | Log.pluginLoader.info("Load Plugins") 30 | let result = try await withThrowingTaskGroup(of: Plugin?.self) { group -> [Plugin?] in 31 | let build = Path.home + ".bazelize" + "build" + swift 32 | for plugin in buildPlugins { 33 | for lib in plugin.libsName { 34 | group.addTask { 35 | let path = (build + plugin.user_repo + lib).string 36 | return try await PluginLoader.load(at: path, proj: proj) 37 | } 38 | } 39 | } 40 | 41 | return try await group.all 42 | } 43 | return result.compactMap { $0 } 44 | } 45 | -------------------------------------------------------------------------------- /Sources/PluginLoader/PluginBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginBuilder.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/24. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import SwiftCommand 11 | import SystemPackage 12 | import Util 13 | 14 | // MARK: - PluginBuilder 15 | 16 | /// ~/.bazelize 17 | /// git/XCodeBazelize_Bazelize 18 | /// build/5.6/XCodeBazelize_Bazelize/1.0.0 19 | enum PluginBuilder { 20 | // MARK: Internal 21 | 22 | static func build(plugins: [PluginInfo]) throws -> [PluginInfo] { 23 | try git.mkpath() 24 | try build.mkpath() 25 | 26 | return plugins.compactMap { info -> PluginInfo? in 27 | if checkExist(plugin: info) { 28 | return info 29 | } 30 | do { 31 | try build(plugin: info) 32 | return info 33 | } catch { 34 | Log.pluginLoader.warning("Build Plugin(\(info.repo)) Fail: \(error.localizedDescription)") 35 | return nil 36 | } 37 | } 38 | } 39 | 40 | // MARK: Private 41 | 42 | private static let root = Path.home + ".bazelize" 43 | private static let git = root + "git" 44 | private static let build = root + "build" + swift 45 | 46 | private static let commandGit = Command.findInPath(withName: "git") 47 | private static let commandSwift = Command.findInPath(withName: "swift") 48 | 49 | 50 | private static func checkExist(plugin: PluginInfo) -> Bool { 51 | plugin.paths 52 | .map { (path: String) -> Path in 53 | build + path 54 | } 55 | .map(\.exists) 56 | .reduce(true) { partialResult, next in 57 | partialResult && next 58 | } 59 | } 60 | 61 | /// cd ~/.bazelize/git 62 | /// test XCodeBazelize_Bazelize 63 | /// false 64 | /// git clone XCodeBazelize/Bazelize.git XCodeBazelize_Bazelize 65 | /// cd XCodeBazelize_Bazelize 66 | /// 67 | /// git pull? 68 | /// git fetch --all --tags? 69 | /// 70 | /// git checkout tag 71 | /// swift build -c release 72 | /// cp .build/release/*.dylib build/XCodeBazelize_Bazelize/tag 73 | private static func build(plugin: PluginInfo) throws { 74 | let repo = git + plugin.user_repo 75 | if !repo.exists { 76 | _ = try commandGit?.setCWD(FilePath(git.string)) 77 | .addArguments("clone", plugin.url, plugin.user_repo) 78 | .setStdout(.null) 79 | .logging() 80 | .wait() 81 | } 82 | 83 | _ = try commandGit?.setCWD(FilePath(repo.string)) 84 | .addArguments("checkout", plugin.tag) 85 | .setStdout(.null) 86 | .logging() 87 | .wait() 88 | 89 | _ = try commandSwift?.setCWD(FilePath(repo.string)) 90 | .addArguments("build", "-c", "release") 91 | .setStdout(.null) 92 | .logging() 93 | .wait() 94 | 95 | let release = repo + ".build" + "release" 96 | 97 | try plugin.libsName.forEach { lib in 98 | let from = release + lib 99 | let toDir = build + plugin.user_repo 100 | try toDir.mkpath() 101 | let to = toDir + lib 102 | Log.pluginLoader.info("cp \(from.string) \(to.string)") 103 | try from.copy(to) 104 | } 105 | } 106 | } 107 | 108 | extension Command { 109 | __consuming func logging() -> Self { 110 | Log.pluginLoader.info(""" 111 | \(cwd?.string ?? "")> \(executablePath) \(arguments.joined(separator: " ")) 112 | """) 113 | 114 | return self 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Sources/PluginLoader/PluginInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PluginInfo.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/24. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import PluginInterface 11 | import Util 12 | 13 | let swift = "5.6" 14 | 15 | // MARK: - PluginInfo 16 | 17 | struct PluginInfo: Codable { 18 | let repo: String 19 | let tag: String 20 | let libs: [String] 21 | 22 | 23 | var url: String { 24 | "https://github.com/\(repo)" 25 | } 26 | 27 | var user_repo: String { 28 | repo.replacingOccurrences(of: "/", with: "_") 29 | } 30 | 31 | /// libPluginA.dylib 32 | var libsName: [String] { 33 | libs.map { lib in 34 | "lib\(lib).dylib" 35 | } 36 | } 37 | 38 | var paths: [String] { 39 | libsName.map { lib in 40 | user_repo + "/" + lib 41 | } 42 | } 43 | } 44 | 45 | // MARK: - Array + Parsable 46 | 47 | extension Array: Parsable where Element: Codable { } 48 | 49 | // MARK: - Array + YamlParsable 50 | 51 | extension Array: YamlParsable where Element: Codable { } 52 | 53 | func parseManifest(_ path: Path) throws -> [PluginInfo] { 54 | try [PluginInfo].parse(path) 55 | } 56 | -------------------------------------------------------------------------------- /Sources/PluginLoader/PluginLoader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/24. 6 | // 7 | 8 | import Foundation 9 | import PluginInterface 10 | 11 | private typealias InitFunction = @convention(c) 12 | () -> UnsafeMutableRawPointer 13 | 14 | // MARK: - DynamicLoadError 15 | 16 | enum DynamicLoadError: Error { 17 | case symbolNotFound(symbolName: String, path: String) 18 | case openFail(reason: String, path: String) 19 | case unknown(path: String) 20 | } 21 | 22 | // MARK: - PluginLoader 23 | 24 | enum PluginLoader { 25 | /// ## Package.swift 26 | /// --- 27 | /// 28 | /// `.library(name: "Cocoapod", type: .dynamic, targets: ["Cocoapod"]),` 29 | /// 30 | /// ### Loadable Plugin Implement 31 | /// 32 | /// ```swift 33 | /// @_cdecl("createPlugin") 34 | /// public func createPlugin() -> UnsafeMutableRawPointer { 35 | /// Unmanaged.passRetained(YourPluginBuilder()).toOpaque() 36 | /// } 37 | /// 38 | /// final class YourPluginBuilder: PluginBuilder { 39 | /// override final func build(_ proj: XCodeProject) async throws -> Plugin? { 40 | /// try await Pod.load(proj) 41 | /// } 42 | /// } 43 | /// ``` 44 | static func load(at path: String, proj: XCodeProject) async throws -> Plugin? { 45 | let openRes = dlopen(path, RTLD_NOW|RTLD_LOCAL) 46 | if openRes != nil { 47 | defer { 48 | dlclose(openRes) 49 | } 50 | 51 | let symbolName = "createPlugin" 52 | let sym = dlsym(openRes, symbolName) 53 | 54 | if sym != nil { 55 | let f: InitFunction = unsafeBitCast(sym, to: InitFunction.self) 56 | let pluginPointer = f() 57 | let builder = Unmanaged.fromOpaque(pluginPointer).takeRetainedValue() 58 | 59 | return try await builder.build(proj) 60 | } else { 61 | throw DynamicLoadError.symbolNotFound(symbolName: symbolName, path: path) 62 | } 63 | } else { 64 | if let err = dlerror() { 65 | throw DynamicLoadError.openFail(reason: String(format: "%s", err), path: path) 66 | } else { 67 | throw DynamicLoadError.unknown(path: path) 68 | } 69 | } 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Builder/PropertyBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PropertyBuilder.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/2. 6 | // 7 | 8 | import Foundation 9 | 10 | @resultBuilder 11 | public enum PropertyBuilder { 12 | public typealias Target = Text 13 | 14 | public static func buildExpression(_ expression: String) -> Target { 15 | Starlark.comment(expression) 16 | } 17 | 18 | public static func buildExpression(_ expression: Target) -> Target { 19 | expression 20 | } 21 | 22 | public static func buildBlock(_ components: Target...) -> [Target] { 23 | components 24 | } 25 | 26 | public static func buildBlock(_ components: [Target]...) -> [Target] { 27 | components.flatMap { $0 } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Builder/StarlarkBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StarlarkBuilder.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/18. 6 | // 7 | 8 | import Foundation 9 | 10 | @resultBuilder 11 | public enum StarlarkBuilder { 12 | public static func buildBlock(_ components: Starlark?...) -> Starlark { 13 | let result = components.compactMap { $0 } 14 | return .init(result) ?? None 15 | } 16 | 17 | // MARK: - expression 18 | public static func buildExpression(_ expression: Starlark) -> Starlark { 19 | expression 20 | } 21 | 22 | public static func buildExpression(_ expression: [Starlark]) -> Starlark { 23 | Starlark(array: expression) 24 | } 25 | 26 | public static func buildExpression(_ expression: [String: String]) -> Starlark { 27 | .init(expression) ?? None 28 | } 29 | 30 | public static func buildExpression(_ expression: [String]?) -> Starlark { 31 | .init(expression) ?? None 32 | } 33 | 34 | public static func buildExpression(_ expression: [String?]) -> Starlark { 35 | .init(expression) ?? None 36 | } 37 | 38 | public static func buildExpression(_ expression: String?) -> Starlark? { 39 | .init(expression) 40 | } 41 | 42 | public static func buildExpression(_ expression: Bool) -> Starlark { 43 | .bool(expression) 44 | } 45 | 46 | public static func buildExpression(_ expression: Starlark.Select) -> Starlark { 47 | .select(expression) 48 | } 49 | 50 | public static func buildOptional(_ component: Starlark?) -> Starlark { 51 | component ?? None 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Starlark/Starlark+Select.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Select.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/18. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - Starlark.Select 11 | 12 | extension Starlark { 13 | public enum Select { 14 | case same(T) 15 | case various([String: T]) 16 | 17 | public func map(_ transform: (T) throws -> U) rethrows -> Select { 18 | switch self { 19 | case .same(let value): 20 | return try .same(transform(value)) 21 | case .various(let value): 22 | return try .various(value.mapValues(transform)) 23 | } 24 | } 25 | } 26 | } 27 | 28 | extension Starlark.Select where T == String { 29 | public var starlark: Starlark { 30 | .select(map(Starlark.init)) 31 | } 32 | } 33 | 34 | extension Starlark.Select where T == String? { 35 | public var starlark: Starlark { 36 | .select(map { 37 | Starlark($0) ?? None 38 | }) 39 | } 40 | } 41 | 42 | extension Starlark.Select where T == [String] { 43 | public var starlark: Starlark { 44 | .select(map { 45 | Starlark($0) ?? .none 46 | }) 47 | } 48 | } 49 | 50 | extension Starlark.Select where T == Bool { 51 | public var starlark: Starlark { 52 | .select(map { 53 | Starlark($0) ?? .none 54 | }) 55 | } 56 | } 57 | 58 | // MARK: - Starlark.Select + Text 59 | 60 | extension Starlark.Select: Text where T == Starlark { 61 | /// select({ 62 | /// "//:Debug": "label1", 63 | /// "//:Release": "label2", 64 | /// "//conditions:default": "label3", 65 | /// }) 66 | public var text: String { 67 | switch self { 68 | case .same(let value): 69 | return value.text 70 | case .various(let value): 71 | let pair = value.map { key, value in 72 | ("//:\(key)", value) 73 | } 74 | let newValue = Starlark.dictionary(Dictionary(uniqueKeysWithValues: pair)) 75 | return """ 76 | select(\(newValue.text)) 77 | """ 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Starlark/StarlarkProperty+Operator.swift: -------------------------------------------------------------------------------- 1 | // Property+Operator.swift 2 | // 3 | // 4 | // Created by Yume on 2022/8/3. 5 | // 6 | 7 | import Foundation 8 | 9 | infix operator => : AssignmentPrecedence 10 | extension String { 11 | public static func =>(propertyName: String, bool: Bool) -> StarlarkProperty { 12 | StarlarkProperty(propertyName, starlark: .bool(bool)) 13 | } 14 | 15 | public static func =>(propertyName: String, label: String?) -> StarlarkProperty { 16 | StarlarkProperty(propertyName, starlark: .init(label) ?? None) 17 | } 18 | 19 | public static func =>(propertyName: String, dictionary: [String: String]) -> StarlarkProperty { 20 | StarlarkProperty(propertyName, starlark: .init(dictionary) ?? None) 21 | } 22 | 23 | public static func =>(propertyName: String, starlark: Starlark) -> StarlarkProperty { 24 | StarlarkProperty(propertyName, starlark: starlark) 25 | } 26 | } 27 | 28 | extension String { 29 | public static func =>(propertyName: String, @StarlarkBuilder builder: () -> Starlark) -> StarlarkProperty { 30 | StarlarkProperty(propertyName, builder: builder) 31 | } 32 | 33 | public static func =>(propertyName: String, labels: [String]) -> StarlarkProperty { 34 | StarlarkProperty(propertyName) { 35 | labels 36 | } 37 | } 38 | 39 | public static func =>(propertyName: String, labels: [String]?) -> StarlarkProperty { 40 | StarlarkProperty(propertyName) { 41 | labels 42 | } 43 | } 44 | 45 | public static func =>(propertyName: String, starlarks: [Starlark]) -> StarlarkProperty { 46 | StarlarkProperty(propertyName) { 47 | starlarks 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Starlark/StarlarkProperty+String.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Property+String.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/2. 6 | // 7 | 8 | import Foundation 9 | 10 | extension String { 11 | public func property(@StarlarkBuilder builder: () -> Starlark) -> StarlarkProperty { 12 | .init(self, builder: builder) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Starlark/StarlarkProperty+Visibility.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Property+Visibility.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/9. 6 | // 7 | 8 | import Foundation 9 | 10 | extension StarlarkProperty { 11 | /// https://bazel.build/concepts/visibility 12 | public enum Visibility { 13 | /// "//visibility:public": Anyone can use this target. (May not be combined with any other specification.) 14 | public static let `public`: StarlarkProperty = "visibility" => ["//visibility:public"] 15 | /// "//visibility:private": Only targets in this package can use this target. (May not be combined with any other specification.) 16 | public static let `private`: StarlarkProperty = "visibility" => ["//visibility:private"] 17 | 18 | /// "//foo/bar:__pkg__": Grants access to targets defined in //foo/bar (but not its subpackages). Here, __pkg__ is a special piece of syntax representing all of the targets in a package. 19 | public static func package(_ packages: String...) -> StarlarkProperty { 20 | group("__pkg__", packages) 21 | } 22 | 23 | /// "//foo/bar:__subpackages__": Grants access to targets defined in //foo/bar, or any of its direct or indirect subpackages. Again, __subpackages__ is special syntax. 24 | public static func subPackage(_ packages: String...) -> StarlarkProperty { 25 | group("__subpackages__", packages) 26 | } 27 | 28 | /// "//foo/bar:my_package_group": Grants access to all of the packages named by the given package group. 29 | public static func group(_ group: String, _ packages: String...) -> StarlarkProperty { 30 | self.group(group, packages) 31 | } 32 | 33 | /// "//foo/bar:my_package_group": Grants access to all of the packages named by the given package group. 34 | public static func group(_ group: String, _ packages: [String]) -> StarlarkProperty { 35 | StarlarkProperty("visibility") { 36 | packages.map { package in 37 | "\(package):\(group)" 38 | } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Starlark/StarlarkProperty.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Property.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/2. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - Property 11 | 12 | public struct StarlarkProperty: Text { 13 | // MARK: Lifecycle 14 | 15 | public init(_ name: String, starlark: Starlark) { 16 | self.name = name 17 | self.starlark = starlark 18 | } 19 | 20 | public init(_ name: String, @StarlarkBuilder builder: () -> Starlark) { 21 | self.init(name, starlark: builder()) 22 | } 23 | 24 | // MARK: Public 25 | 26 | public let name: String 27 | public let starlark: Starlark 28 | 29 | 30 | public var text: String { 31 | switch starlark { 32 | case .comment: 33 | return """ 34 | \(starlark.text) 35 | # \(name) = None, 36 | """ 37 | case .none: 38 | return """ 39 | # \(name) = None, 40 | """ 41 | default: 42 | return "\(name) = \(starlark.text)," 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Starlark/StarlarkRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StarlarkRule.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/1. 6 | // 7 | 8 | import Foundation 9 | import Util 10 | 11 | public struct StarlarkRule { 12 | public let rule: String 13 | public let properties: [PropertyBuilder.Target] 14 | public init(_ rule: String, @PropertyBuilder builder: () -> [PropertyBuilder.Target]) { 15 | self.rule = rule 16 | properties = builder() 17 | } 18 | 19 | public var text: String { 20 | """ 21 | \(rule)( 22 | \(properties.map(\.text).withNewLine.indent(1)) 23 | ) 24 | """ 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/RuleBuilder/Text.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BazelText.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/2. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - Text 11 | 12 | public protocol Text { 13 | var text: String { get } 14 | } 15 | -------------------------------------------------------------------------------- /Sources/Util/Array+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+Extension.swift 3 | // 4 | // 5 | // Created by Yume on 2023/2/1. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Array { 11 | public func toDictionary() -> [K: V] where Element == (K, V) { 12 | return Dictionary(self, uniquingKeysWith: { first, _ in first }) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Sources/Util/AsyncSequence+all.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AsyncSequence+all.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/1. 6 | // 7 | 8 | import Foundation 9 | 10 | extension AsyncSequence { 11 | public var all: [Element] { 12 | get async throws { 13 | var iterator = makeAsyncIterator() 14 | var result: [Element] = [] 15 | while let next = try await iterator.next() { 16 | result.append(next) 17 | } 18 | return result 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sources/Util/Env.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Env.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/27. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum Env { 11 | /// COCOAPOD 12 | public static var pod: String { 13 | ProcessInfo.processInfo.environment["COCOAPOD"] ?? "/usr/local/bin/pod" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/Util/Logger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Logger.swift 3 | // 4 | // 5 | // Created by Yume on 2022/10/10. 6 | // 7 | 8 | import Foundation 9 | import os 10 | import OSLog 11 | 12 | public enum Log { 13 | private static let domain = "com.xcode.bazelize" 14 | 15 | public static let codeGenerate = Logger(subsystem: domain, category: "code generate") 16 | public static let pluginLoader = Logger(subsystem: domain, category: "plugin loader") 17 | public static let dump = Logger(subsystem: domain, category: "dump") 18 | } 19 | -------------------------------------------------------------------------------- /Sources/Util/Parsable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Parsable.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/26. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import Yams 11 | 12 | // MARK: - Parsable 13 | 14 | public protocol Parsable: Decodable { 15 | static func parse(_ path: Path) throws -> Self 16 | static func parse(_ content: String) throws -> Self 17 | static func parse(_ content: Foundation.Data) throws -> Self 18 | } 19 | 20 | extension Parsable { 21 | public static func parse(_ path: Path) throws -> Self { 22 | try parse(path.read()) 23 | } 24 | 25 | public static func parse(_ content: String) throws -> Self { 26 | let data = Data(content.utf8) 27 | return try parse(data) 28 | } 29 | } 30 | 31 | // MARK: - JSONParsable 32 | 33 | public protocol JSONParsable: Parsable { } 34 | extension JSONParsable { 35 | public static func parse(_ content: Data) throws -> Self { 36 | let decoder = JSONDecoder() 37 | return try decoder.decode(Self.self, from: content) 38 | } 39 | } 40 | 41 | // MARK: - YamlParsable 42 | 43 | public protocol YamlParsable: Parsable { } 44 | extension YamlParsable { 45 | public static func parse(_ content: Data) throws -> Self { 46 | let decoder = YAMLDecoder() 47 | return try decoder.decode(Self.self, from: content) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/Util/Process.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Process.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/26. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - Process + Sendable 11 | 12 | extension Process: @unchecked Sendable { 13 | // MARK: Public 14 | 15 | public static func execute(_ command: String, arguments: String...) async throws -> Data { 16 | let task = Process.task 17 | task.setup(command, arguments: arguments) 18 | 19 | let pipe = Pipe() 20 | task.standardOutput = pipe 21 | 22 | return try await withTaskCancellationHandler(operation: { 23 | try await withCheckedThrowingContinuation { continuation in 24 | do { 25 | try task.run() 26 | task.waitUntilExit() 27 | let data = pipe.fileHandleForReading.readDataToEndOfFile() 28 | continuation.resume(returning: data) 29 | } catch { 30 | continuation.resume(throwing: error) 31 | } 32 | } 33 | }, onCancel: { 34 | guard task.isRunning else { return } 35 | // task.interrupt() 36 | task.terminate() 37 | }) 38 | } 39 | 40 | public static func result(_ command: String, arguments: String...) -> Bool { 41 | let task = Process.task 42 | task.setup(command, arguments: arguments) 43 | 44 | task.standardError = Pipe() 45 | task.standardOutput = Pipe() 46 | 47 | do { 48 | try task.run() 49 | task.waitUntilExit() 50 | return task.terminationStatus == 0 51 | } catch { 52 | return false 53 | } 54 | } 55 | 56 | // MARK: Private 57 | 58 | private static var task: Process { 59 | var environment = ProcessInfo.processInfo.environment 60 | environment["LANG"] = "en_US.UTF-8" 61 | 62 | let task = Process() 63 | task.environment = environment 64 | return task 65 | } 66 | 67 | 68 | private func setup(_ command: String, arguments: [String]) { 69 | var args = command.split(separator: " ").map(String.init) 70 | let cmd = args.removeFirst() 71 | executableURL = URL(fileURLWithPath: cmd) 72 | self.arguments = args + arguments 73 | currentDirectoryURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Sources/Util/String+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+NewLine.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/28. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Array where Element == String { 11 | public var withNewLine: String { 12 | joined(separator: "\n") 13 | } 14 | } 15 | 16 | extension String { 17 | public var withComma: String { 18 | "\(self)," 19 | } 20 | 21 | public var comment: String { 22 | split(separator: "\n") 23 | .map { sub in 24 | sub.appending(prefix: "# ") 25 | } 26 | .joined(separator: "\n") 27 | } 28 | } 29 | 30 | extension String { 31 | public func delete(prefix: String) -> String { 32 | guard hasPrefix(prefix) else { return self } 33 | return String(dropFirst(prefix.count)) 34 | } 35 | } 36 | 37 | extension StringProtocol { 38 | public func appending(prefix: String) -> String { 39 | prefix + self 40 | } 41 | 42 | public func appending(suffix: String) -> String { 43 | self + suffix 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Sources/Util/String+Indent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // indent.swift 3 | // 4 | // 5 | // Created by Yume on 2022/6/7. 6 | // 7 | 8 | import Foundation 9 | 10 | extension String { 11 | public func indent(_ count: Int = 1, _ word: String = " ") -> String { 12 | let prefix = Array(repeating: word, count: count).joined(separator: "") 13 | return split(separator: "\n") 14 | .map { sub in 15 | sub.appending(prefix: prefix) 16 | } 17 | .withNewLine 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Sources/XCode/Model/ConfigList.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConfigList.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/1. 6 | // 7 | 8 | import Foundation 9 | import PluginInterface 10 | import XcodeProj 11 | 12 | // MARK: - ConfigList 13 | 14 | struct ConfigList { 15 | // MARK: Lifecycle 16 | 17 | init(_ project: Project, _ target: PBXNativeTarget) { 18 | self.init(project, target.buildConfigurationList) 19 | } 20 | 21 | init(_ project: Project, _ list: XCConfigurationList?) { 22 | self.project = project 23 | native = list 24 | } 25 | 26 | // MARK: Public 27 | 28 | public unowned let project: Project 29 | 30 | // MARK: Internal 31 | 32 | var buildSettings: [String: BuildSetting] { 33 | let pair: [(String, BuildSetting)] = native?.buildConfigurations 34 | .map { 35 | BuildSetting(project, $0) 36 | }.map { 37 | ($0.name, $0) 38 | } ?? [] 39 | 40 | return pair.toDictionary() 41 | } 42 | 43 | /// For XCode Target ConfigList merge default ConfigList 44 | func merge(_ config: ConfigList?) -> [String: BuildSetting] { 45 | guard let config = config else { 46 | return buildSettings 47 | } 48 | 49 | let `default` = config.buildSettings 50 | return buildSettings.mapValues { setting in 51 | setting.merge(`default`[setting.name]) 52 | } 53 | } 54 | 55 | // MARK: Private 56 | 57 | private let native: XCConfigurationList? 58 | } 59 | 60 | // MARK: Hashable 61 | 62 | extension ConfigList: Hashable { 63 | public static func == (lhs: ConfigList, rhs: ConfigList) -> Bool { 64 | lhs.native?.uuid == rhs.native?.uuid 65 | } 66 | 67 | public func hash(into hasher: inout Hasher) { 68 | hasher.combine(native?.uuid) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Sources/XCode/Model/SPMParser.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SPMParser.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/19. 6 | // 7 | 8 | import Foundation 9 | 10 | import Basics 11 | import PathKit 12 | import TSCBasic 13 | import Workspace 14 | 15 | enum SPMParser { 16 | static func parse(path: String) throws -> (products: [String: [String]], targets: [String]) { 17 | let packagePath = try AbsolutePath(validating: path) 18 | let observability = ObservabilitySystem { _,_ in } 19 | 20 | let workspace = try Workspace(forRootPackage: packagePath) 21 | let manifest = try tsc_await { 22 | workspace.loadRootManifest( 23 | at: packagePath, 24 | observabilityScope: observability.topScope, 25 | completion: $0) 26 | } 27 | 28 | let pair = manifest.products.map { ($0.name, $0.targets) } 29 | let products = pair.toDictionary() 30 | let targets = manifest.targets.map { $0.name } 31 | 32 | let productsDetail = products.map { key, value in 33 | """ 34 | \(key): 35 | \(value.withNewLine.indent(1)) 36 | """.indent(2) 37 | }.sorted().withNewLine 38 | 39 | print(""" 40 | Find Local SPM 41 | at: \(path) 42 | products: 43 | \(productsDetail) 44 | """) 45 | 46 | return (products, targets) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sources/XCode/Model/XCode+File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RelativePath.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/25. 6 | // 7 | 8 | import Foundation 9 | import PathKit 10 | import PluginInterface 11 | import XcodeProj 12 | 13 | // MARK: - File 14 | 15 | public final class File { 16 | private unowned let project: XCodeProject 17 | let native: PBXFileElement 18 | 19 | init(native: PBXFileElement, project: XCodeProject) { 20 | self.native = native 21 | self.project = project 22 | } 23 | 24 | /// root: /Users/xxx/git/ABCDEF 25 | /// 26 | /// fullPath: /Users/xxx/git/ABCDEF/DEF/Base.lproj/LaunchScreen.storyboard 27 | /// package: DEF 28 | public var label: String? { 29 | guard let path = relativePath else { 30 | return nil 31 | } 32 | return project.transformToLabel(path) 33 | } 34 | 35 | public var relativePath: String? { 36 | let root = project.workspacePath.string 37 | let fullPath = fullPath ?? "" 38 | guard fullPath.hasPrefix(root + "/") else { 39 | return nil 40 | } 41 | return fullPath.delete(prefix: root + "/") 42 | } 43 | 44 | public var fullPath: String? { 45 | let root = project.workspacePath.string 46 | return try? native.fullPath(sourceRoot: root) 47 | } 48 | 49 | private var ref: PBXFileReference? { 50 | native as? PBXFileReference 51 | } 52 | 53 | /// File type start with `sourcecode.` 54 | public var isSource: Bool { 55 | guard let ref = ref else { return false } 56 | return ref.lastKnownFileType?.hasPrefix("sourcecode.") ?? false 57 | } 58 | 59 | /// File is PBXFileReference 60 | public var isFile: Bool { 61 | native is PBXFileReference 62 | } 63 | 64 | public var lastKnownFileType: LastKnownFileType? { 65 | .init(rawValue: ref?.lastKnownFileType ?? "") 66 | } 67 | 68 | public var explicitFileType: ExplicitFileType? { 69 | .init(rawValue: ref?.explicitFileType ?? "") 70 | } 71 | } 72 | 73 | extension PBXFileElement { 74 | func flatten() -> [PBXFileElement] { 75 | if let group = self as? PBXGroup { 76 | return group.children.flatMap { file in 77 | file.flatten() 78 | } 79 | } 80 | 81 | if let ref = self as? PBXFileReference { 82 | return [ref] 83 | } 84 | 85 | return [] 86 | } 87 | } 88 | 89 | extension Array where Element == File { 90 | var labels: [String] { 91 | compactMap(\.label) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Sources/XCode/Model/XCode+Preffer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XCode+Prefer.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/23. 6 | // 7 | 8 | import Foundation 9 | import PluginInterface 10 | import RuleBuilder 11 | import XcodeProj 12 | 13 | extension Dictionary where Key == String { 14 | fileprivate var sortedByKey: [(key: Key, value: Value)] { 15 | sorted { lhs, rhs in 16 | lhs.key < rhs.key 17 | } 18 | } 19 | } 20 | 21 | extension Dictionary where Key == String, Value == XCodeBuildSetting { 22 | public func prefer(config: String?, _ keyPath: KeyPath) -> T? { 23 | let firstValue = sortedByKey.first?.value[keyPath: keyPath] 24 | guard let key = config else { return firstValue } 25 | let preferValue = self[key]?[keyPath: keyPath] 26 | return preferValue ?? firstValue 27 | } 28 | 29 | // prevent T?? 30 | public func prefer(config: String?, _ keyPath: KeyPath) -> T? { 31 | let firstValue = sortedByKey.first?.value[keyPath: keyPath] 32 | guard let key = config else { return firstValue } 33 | let preferValue = self[key]?[keyPath: keyPath] 34 | return preferValue ?? firstValue 35 | } 36 | } 37 | 38 | extension Target { 39 | public func prefer(_ keyPath: KeyPath) -> T? { 40 | config.prefer(config: project.preferConfig, keyPath) 41 | } 42 | 43 | // prevent T?? 44 | public func prefer(_ keyPath: KeyPath) -> T? { 45 | config.prefer(config: project.preferConfig, keyPath) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/XCode/Model/XCode+RemoteSPMPackage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XCodeSPM.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/25. 6 | // 7 | 8 | import Foundation 9 | import PluginInterface 10 | import Util 11 | import XcodeProj 12 | 13 | extension XCodeRemoteSPM { 14 | public static func parse(_ native: XCSwiftPackageProductDependency) -> XCodeRemoteSPM? { 15 | let package = native.package 16 | guard 17 | let url = package?.repositoryURL, 18 | let requirement = package?.versionRequirement 19 | else { 20 | return nil 21 | } 22 | return XCodeRemoteSPM(url: url, version: requirement.version) 23 | } 24 | } 25 | 26 | extension XCRemoteSwiftPackageReference.VersionRequirement { 27 | var version: XCodeRemoteSPM.Version { 28 | switch self { 29 | case .upToNextMajorVersion(let version): return .upToNextMajorVersion(version) 30 | case .upToNextMinorVersion(let version): return .upToNextMinorVersion(version) 31 | case .range(let from, let to): return .range(from: from, to: to) 32 | case .exact(let version): return .exact(version) 33 | case .branch(let branch): return .branch(branch) 34 | case .revision(let commit): return .revision(commit) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Sources/XCode/Model/XCode+Select.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Target+Select.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/17. 6 | // 7 | 8 | import Foundation 9 | import PluginInterface 10 | import RuleBuilder 11 | import XcodeProj 12 | 13 | extension Dictionary where Key == String, Value == XCodeBuildSetting { 14 | // MARK: Public 15 | 16 | public func select(_ keypath: KeyPath) -> Starlark.Select { 17 | if checkSame(keypath) { 18 | return selectSame(keypath) 19 | } 20 | return selectVarious(keypath) 21 | } 22 | 23 | // MARK: Private 24 | 25 | private func checkSame(_ keypath: KeyPath) -> Bool { 26 | let values: [T] = map { _, setting in 27 | setting[keyPath: keypath] 28 | } 29 | 30 | return Set(values).count == 1 31 | } 32 | 33 | private func selectSame(_ keypath: KeyPath) -> Starlark.Select { 34 | guard let value = first?.value[keyPath: keypath] else { 35 | return selectVarious(keypath) 36 | } 37 | return .same(value) 38 | } 39 | 40 | private func selectVarious(_ keypath: KeyPath) -> Starlark.Select { 41 | let result = mapValues { setting in 42 | setting[keyPath: keypath] 43 | } 44 | return .various(result) 45 | } 46 | } 47 | 48 | extension Target { 49 | public func select(_ keypath: KeyPath) -> Starlark.Select { 50 | config.select(keypath) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sources/XCode/Setting/DeviceFamily.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // 5 | // Created by Yume on 2022/7/1. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - DeviceFamily 11 | 12 | /// "1,2" 13 | /// 1: iphone 14 | /// 2: ipad 15 | /// 3: appletv? 16 | /// 4: applewatch? 17 | /// 5: homepod? 18 | /// 6: mac? 19 | internal enum DeviceFamily: String { 20 | case iphone = "1" 21 | case ipad = "2" 22 | case appletv = "3" 23 | case applewatch = "4" 24 | case homepod = "5" 25 | case mac = "6" 26 | 27 | // MARK: Internal 28 | 29 | internal var code: String { 30 | switch self { 31 | case .iphone: return "iphone" 32 | case .ipad: return "ipad" 33 | case .appletv: return "appletv" 34 | case .applewatch: return "applewatch" 35 | case .homepod: return "homepod" 36 | case .mac: return "mac" 37 | } 38 | } 39 | 40 | 41 | /// `1,2` -> [`"iphone"` `"ipad"`] 42 | internal static func parse(_ code: String?) -> [String] { 43 | code?.split(separator: ",") 44 | .map(String.init) 45 | .compactMap(DeviceFamily.init(rawValue:)) 46 | .map(\.code) ?? [] 47 | } 48 | } 49 | 50 | 51 | // MARK: - SupportedPlatform 52 | 53 | /// SUPPORTED_PLATFORMS 54 | enum SupportedPlatform: String { 55 | case iphonesimulator 56 | case iphoneos 57 | case driverkit 58 | case macosx 59 | case appletvsimulator 60 | case appletvos 61 | case watchsimulator 62 | case watchos 63 | } 64 | 65 | 66 | /// catalyst 67 | /// SUPPORTS_MACCATALYST 68 | 69 | /// design for ipad 70 | /// SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD 71 | -------------------------------------------------------------------------------- /Sources/XCode/Setting/ExplicitFileType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExplicitFileType.swift 3 | // 4 | // 5 | // Created by Yume on 2023/1/18. 6 | // 7 | 8 | import Foundation 9 | 10 | /// `PBXFileReference.explicitFileType` 11 | public enum ExplicitFileType: String, Equatable { 12 | /// libXXX.a 13 | case archive = "archive.ar" 14 | 15 | case framework = "wrapper.framework" 16 | } 17 | -------------------------------------------------------------------------------- /Sources/XCode/Setting/LastKnownFileType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LastKnownFileType.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/4. 6 | // 7 | 8 | import Foundation 9 | 10 | /// `PBXFileReference.lastKnownFileType` 11 | public enum LastKnownFileType: String { 12 | case h = "sourcecode.c.h" 13 | case c = "sourcecode.c.c" 14 | case objc = "sourcecode.c.objc" 15 | case hpp = "sourcecode.cpp.h" 16 | case cpp = "sourcecode.cpp.cpp" 17 | case objcpp = "sourcecode.cpp.objcpp" 18 | case swift = "sourcecode.swift" 19 | case metal = "sourcecode.metal" 20 | 21 | case strings = "text.plist.strings" 22 | case stringsdict = "text.plist.stringsdict" 23 | case plist = "text.plist.xml" 24 | case entitlements = "text.plist.entitlements" 25 | case xcconfig = "text.xcconfig" 26 | 27 | case asset = "folder.assetcatalog" 28 | 29 | case xib = "file.xib" 30 | case storyboard = "file.storyboard" 31 | 32 | case wrapper 33 | case folder 34 | 35 | case framework = "wrapper.framework" 36 | case xcframework = "wrapper.xcframework" 37 | } 38 | -------------------------------------------------------------------------------- /Tests/CocoapodTests/Resource/Podfile: -------------------------------------------------------------------------------- 1 | { 2 | "target_definitions": [ 3 | { 4 | "name": "Pods", 5 | "abstract": true, 6 | "user_project_path": "ABCDEF.xcodeproj", 7 | "children": [ 8 | { 9 | "name": "ABCDEF", 10 | "uses_frameworks": { 11 | "linkage": "dynamic", 12 | "packaging": "framework" 13 | }, 14 | "configuration_pod_whitelist": { 15 | "Debug": [ 16 | "Peek" 17 | ] 18 | }, 19 | "dependencies": [ 20 | "Peek", 21 | { 22 | "AFNetworking": [ 23 | "~> 4.0" 24 | ] 25 | }, 26 | "Moya/RxSwift", 27 | "Moya/Combine", 28 | { 29 | "DataCompression": [ 30 | { 31 | "git": "https://github.com/mw99/DataCompression" 32 | } 33 | ] 34 | }, 35 | { 36 | "XLPagerTabStrip": [ 37 | { 38 | "git": "https://github.com/xmartlabs/XLPagerTabStrip", 39 | "branch": "master" 40 | } 41 | ] 42 | }, 43 | { 44 | "SVProgressHUD": [ 45 | { 46 | "git": "https://github.com/SVProgressHUD/SVProgressHUD", 47 | "tag": "2.2.5" 48 | } 49 | ] 50 | }, 51 | { 52 | "TLPhotoPicker": [ 53 | { 54 | "git": "https://github.com/tilltue/TLPhotoPicker", 55 | "commit": "0d0cbbd2d20ed5fd36e5f4052209f5e2d9aaa8b7" 56 | } 57 | ] 58 | } 59 | ], 60 | "use_modular_headers": { 61 | "for_pods": [ 62 | "AFNetworking" 63 | ] 64 | } 65 | } 66 | ] 67 | } 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /Tests/CocoapodTests/Resource/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (4.0.1): 3 | - AFNetworking/NSURLSession (= 4.0.1) 4 | - AFNetworking/Reachability (= 4.0.1) 5 | - AFNetworking/Security (= 4.0.1) 6 | - AFNetworking/Serialization (= 4.0.1) 7 | - AFNetworking/UIKit (= 4.0.1) 8 | - AFNetworking/NSURLSession (4.0.1): 9 | - AFNetworking/Reachability 10 | - AFNetworking/Security 11 | - AFNetworking/Serialization 12 | - AFNetworking/Reachability (4.0.1) 13 | - AFNetworking/Security (4.0.1) 14 | - AFNetworking/Serialization (4.0.1) 15 | - AFNetworking/UIKit (4.0.1): 16 | - AFNetworking/NSURLSession 17 | - Alamofire (5.6.1) 18 | - DataCompression (3.6.0) 19 | - Moya/Combine (15.0.0): 20 | - Moya/Core 21 | - Moya/Core (15.0.0): 22 | - Alamofire (~> 5.0) 23 | - Moya/RxSwift (15.0.0): 24 | - Moya/Core 25 | - RxSwift (~> 6.0) 26 | - Peek (5.3.0) 27 | - RxSwift (6.5.0) 28 | - SVProgressHUD (2.2.5) 29 | - TLPhotoPicker (2.1.6) 30 | - XLPagerTabStrip (9.0.0) 31 | 32 | DEPENDENCIES: 33 | - AFNetworking (~> 4.0) 34 | - DataCompression (from `https://github.com/mw99/DataCompression`) 35 | - Moya/Combine 36 | - Moya/RxSwift 37 | - Peek 38 | - SVProgressHUD (from `https://github.com/SVProgressHUD/SVProgressHUD`, tag `2.2.5`) 39 | - TLPhotoPicker (from `https://github.com/tilltue/TLPhotoPicker`, commit `0d0cbbd2d20ed5fd36e5f4052209f5e2d9aaa8b7`) 40 | - XLPagerTabStrip (from `https://github.com/xmartlabs/XLPagerTabStrip`, branch `master`) 41 | 42 | SPEC REPOS: 43 | trunk: 44 | - AFNetworking 45 | - Alamofire 46 | - Moya 47 | - Peek 48 | - RxSwift 49 | 50 | EXTERNAL SOURCES: 51 | DataCompression: 52 | :git: https://github.com/mw99/DataCompression 53 | SVProgressHUD: 54 | :git: https://github.com/SVProgressHUD/SVProgressHUD 55 | :tag: 2.2.5 56 | TLPhotoPicker: 57 | :commit: 0d0cbbd2d20ed5fd36e5f4052209f5e2d9aaa8b7 58 | :git: https://github.com/tilltue/TLPhotoPicker 59 | XLPagerTabStrip: 60 | :branch: master 61 | :git: https://github.com/xmartlabs/XLPagerTabStrip 62 | 63 | CHECKOUT OPTIONS: 64 | DataCompression: 65 | :commit: 2c0d48be59acd5bdf1a5352d969d6f24bd7212c9 66 | :git: https://github.com/mw99/DataCompression 67 | SVProgressHUD: 68 | :git: https://github.com/SVProgressHUD/SVProgressHUD 69 | :tag: 2.2.5 70 | TLPhotoPicker: 71 | :commit: 0d0cbbd2d20ed5fd36e5f4052209f5e2d9aaa8b7 72 | :git: https://github.com/tilltue/TLPhotoPicker 73 | XLPagerTabStrip: 74 | :commit: 903b7609b2b2dd1010efb9ee1c6a27edaa9df89b 75 | :git: https://github.com/xmartlabs/XLPagerTabStrip 76 | 77 | SPEC CHECKSUMS: 78 | AFNetworking: 7864c38297c79aaca1500c33288e429c3451fdce 79 | Alamofire: 87bd8c952f9a4454320fce00d9cc3de57bcadaf5 80 | DataCompression: 06628f9c807b6f152e0da37635633f62fc51dc77 81 | Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee 82 | Peek: 4209f7aa72d00244616f6b4804739c04cae2e457 83 | RxSwift: 5710a9e6b17f3c3d6e40d6e559b9fa1e813b2ef8 84 | SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 85 | TLPhotoPicker: 57ad6b54a9cf8c9ec60107be0864d42f3dbe7175 86 | XLPagerTabStrip: 6af5fe7b41c21f371860df6bac2ddf12818c5103 87 | 88 | PODFILE CHECKSUM: 3be7930c466451f51fe2597aada6fdbd7e8817d9 89 | 90 | COCOAPODS: 1.11.3 91 | -------------------------------------------------------------------------------- /Tests/CocoapodTests/SPMTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SPMTests.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/25. 6 | // 7 | 8 | import Foundation 9 | import XCTest 10 | @testable import Cocoapod 11 | 12 | final class SPMTests: XCTestCase { 13 | // MARK: Internal 14 | 15 | /// Total 9 pod 16 | /// 17 | /// - AFNetworking (4.0.1): 18 | /// x dep's dep 19 | /// - Alamofire (5.6.1) 20 | /// - DataCompression (3.6.0) 21 | /// 22 | /// - Moya/Combine (15.0.0): 23 | /// ? Default Subspec 24 | /// - Moya/Core (15.0.0): 25 | /// - Moya/RxSwift (15.0.0): 26 | /// 27 | /// - Peek (5.3.0) 28 | /// x dep's dep 29 | /// - RxSwift (6.5.0) 30 | /// - SVProgressHUD (2.2.5) 31 | /// - TLPhotoPicker (2.1.6) 32 | /// - XLPagerTabStrip (9.0.0) 33 | func testParsePodfileLock() async throws { 34 | let code = try Self.strings("Podfile.lock") 35 | let lock = try PodfileLock.parse(code) 36 | let repos = try await lock.repos 37 | XCTAssertEqual(repos.count, 9) 38 | 39 | XCTAssertEqual(repos[0].name, "AFNetworking") 40 | XCTAssertEqual(repos[1].name, "Alamofire") 41 | XCTAssertEqual(repos[2].name, "DataCompression") 42 | XCTAssertEqual(repos[3].name, "Moya") 43 | XCTAssertEqual(repos[4].name, "Peek") 44 | XCTAssertEqual(repos[5].name, "RxSwift") 45 | XCTAssertEqual(repos[6].name, "SVProgressHUD") 46 | XCTAssertEqual(repos[7].name, "TLPhotoPicker") 47 | XCTAssertEqual(repos[8].name, "XLPagerTabStrip") 48 | 49 | XCTAssertEqual(repos[0].url, "https://github.com/AFNetworking/AFNetworking/archive/4.0.1.zip") 50 | XCTAssertEqual(repos[1].url, "https://github.com/Alamofire/Alamofire/archive/5.6.1.zip") 51 | XCTAssertEqual( 52 | repos[2].url, 53 | "https://github.com/mw99/DataCompression/archive/2c0d48be59acd5bdf1a5352d969d6f24bd7212c9.zip") 54 | XCTAssertEqual(repos[3].url, "https://github.com/Moya/Moya/archive/15.0.0.zip") 55 | XCTAssertEqual(repos[4].url, "https://github.com/shaps80/Peek/archive/5.3.0.zip") 56 | XCTAssertEqual(repos[5].url, "https://github.com/ReactiveX/RxSwift/archive/6.5.0.zip") 57 | XCTAssertEqual(repos[6].url, "https://github.com/SVProgressHUD/SVProgressHUD/archive/2.2.5.zip") 58 | XCTAssertEqual( 59 | repos[7].url, 60 | "https://github.com/tilltue/TLPhotoPicker/archive/0d0cbbd2d20ed5fd36e5f4052209f5e2d9aaa8b7.zip") 61 | XCTAssertEqual(repos[8].url, "https://github.com/xmartlabs/XLPagerTabStrip/archive/master.zip") 62 | } 63 | 64 | func testParsePodfile() async throws { 65 | let code = try Self.strings("Podfile") 66 | let podfile = try Podfile.parse(code) 67 | 68 | let result = podfile["ABCDEF"] 69 | let deps = """ 70 | //Vendor/AFNetworking:AFNetworking 71 | //Vendor/DataCompression:DataCompression 72 | //Vendor/Moya:Combine 73 | //Vendor/Moya:RxSwift 74 | //Vendor/Peek:Peek 75 | //Vendor/SVProgressHUD:SVProgressHUD 76 | //Vendor/TLPhotoPicker:TLPhotoPicker 77 | //Vendor/XLPagerTabStrip:XLPagerTabStrip 78 | """ 79 | 80 | XCTAssertEqual(result.joined(separator: "\n"), deps) 81 | } 82 | 83 | // MARK: Private 84 | 85 | private static let sourceFile: URL = .init(fileURLWithPath: #file) 86 | .deletingLastPathComponent() 87 | .appendingPathComponent("Resource") 88 | 89 | private static func resource(_ file: String) -> String { 90 | sourceFile.appendingPathComponent(file).path 91 | } 92 | 93 | private static func strings(_ file: String) throws -> String { 94 | try String(contentsOfFile: resource(file), encoding: .utf8) 95 | } 96 | 97 | #warning("todo default spec is sub spec") 98 | } 99 | -------------------------------------------------------------------------------- /Tests/RuleBuilderTests/PropertyTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PropertyTests.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/3. 6 | // 7 | 8 | import XCTest 9 | @testable import RuleBuilder 10 | 11 | 12 | 13 | // MARK: - PropertyTests 14 | 15 | final class PropertyTests: XCTestCase { } 16 | 17 | private let label = """ 18 | name = "Target", 19 | """ 20 | 21 | private let labelList = """ 22 | name = [ 23 | "Target", 24 | ], 25 | """ 26 | 27 | // MARK: - Single Label 28 | extension PropertyTests { 29 | func testLabelList1() { 30 | let property = StarlarkProperty("name") { 31 | "Target" 32 | } 33 | XCTAssertEqual(labelList, property.text) 34 | } 35 | 36 | func testLabelList2() { 37 | let property = "name".property { 38 | "Target" 39 | } 40 | XCTAssertEqual(labelList, property.text) 41 | } 42 | 43 | func testLabelList3() { 44 | let property = "name" => { 45 | "Target" 46 | } 47 | XCTAssertEqual(labelList, property.text) 48 | } 49 | 50 | func testLabel() { 51 | let property = "name" => "Target" 52 | 53 | XCTAssertEqual(label, property.text) 54 | } 55 | } 56 | 57 | private let list = """ 58 | families = [ 59 | "1", 60 | "2", 61 | ], 62 | """ 63 | // MARK: - Label List 64 | extension PropertyTests { 65 | func testList1() { 66 | let property = StarlarkProperty("families") { 67 | "1" 68 | "2" 69 | } 70 | XCTAssertEqual(list, property.text) 71 | } 72 | 73 | func testList2() { 74 | let property = "families".property { 75 | "1" 76 | "2" 77 | } 78 | XCTAssertEqual(list, property.text) 79 | } 80 | 81 | func testList3() { 82 | let property = "families" => { 83 | "1" 84 | "2" 85 | } 86 | 87 | XCTAssertEqual(list, property.text) 88 | } 89 | } 90 | 91 | // MARK: - Comment 92 | extension PropertyTests { 93 | func testCommentSingle1() { 94 | let property = "families" => { 95 | Starlark.comment("test") 96 | } 97 | let result = """ 98 | families = [ 99 | # test 100 | ], 101 | """ 102 | XCTAssertEqual(result, property.text) 103 | } 104 | 105 | func testCommentSingle2() { 106 | let property = "families" => Starlark.comment("test") 107 | let result = """ 108 | # test 109 | # families = None, 110 | """ 111 | XCTAssertEqual(result, property.text) 112 | } 113 | } 114 | 115 | // MARK: - Nil Label 116 | extension PropertyTests { 117 | func testNilSingle() { 118 | let nilString: String? = nil 119 | let property = "families" => { 120 | nilString 121 | } 122 | let result = """ 123 | # families = None, 124 | """ 125 | XCTAssertEqual(result, property.text) 126 | } 127 | 128 | func testNilMulti() { 129 | let nilString: String? = nil 130 | let property = "families" => { 131 | Starlark.comment("test") 132 | nilString 133 | "1" 134 | nilString 135 | "2" 136 | nilString 137 | } 138 | let result = """ 139 | families = [ 140 | # test 141 | "1", 142 | "2", 143 | ], 144 | """ 145 | XCTAssertEqual(result, property.text) 146 | } 147 | } 148 | 149 | -------------------------------------------------------------------------------- /Tests/RuleBuilderTests/Starlark/StarlarkTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StarlarkTests.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/18. 6 | // 7 | 8 | import XCTest 9 | @testable import RuleBuilder 10 | 11 | // MARK: - StarlarkTests 12 | 13 | final class StarlarkTests: XCTestCase { 14 | func build(@StarlarkBuilder builder: () -> Starlark) -> Starlark { 15 | builder() 16 | } 17 | 18 | func testComment() { 19 | let code: Starlark = .comment("test") 20 | XCTAssertEqual(code.text, "# test") 21 | } 22 | 23 | func testLabelString() { 24 | let code: Starlark = "test" 25 | XCTAssertEqual(code.text, "\"test\"") 26 | } 27 | 28 | func testLabel() { 29 | let code: Starlark = .label("test") 30 | XCTAssertEqual(code.text, "\"test\"") 31 | } 32 | 33 | func testNil() { 34 | let code: Starlark = nil 35 | XCTAssertEqual(code.text, "None") 36 | } 37 | 38 | func testNilString() { 39 | let nilString: String? = nil 40 | let code: Starlark = build { 41 | nilString 42 | } 43 | 44 | XCTAssertEqual(code.text, "None") 45 | } 46 | 47 | func testTrue() { 48 | let code: Starlark = true 49 | XCTAssertEqual(code.text, "True") 50 | } 51 | 52 | func testFalse() { 53 | let code: Starlark = false 54 | XCTAssertEqual(code.text, "False") 55 | } 56 | 57 | func testDictionary() { 58 | let code: Starlark = [ 59 | "b": "bbb", 60 | "a": "aaa", 61 | "c": "ccc", 62 | ] 63 | 64 | let result = """ 65 | { 66 | "a": "aaa", 67 | "b": "bbb", 68 | "c": "ccc" 69 | } 70 | """ 71 | XCTAssertEqual(code.text, result) 72 | } 73 | 74 | func testArray() { 75 | let code: Starlark = ["1", "2"] 76 | 77 | let result = """ 78 | [ 79 | "1", 80 | "2", 81 | ] 82 | """ 83 | XCTAssertEqual(code.text, result) 84 | } 85 | 86 | func testArrayWithNilString() { 87 | let nilString: String? = nil 88 | let code = build { 89 | [ 90 | nilString, 91 | "1", 92 | "2", 93 | "3", 94 | nilString, 95 | ] 96 | }.text 97 | 98 | XCTAssertEqual(code, """ 99 | [ 100 | "1", 101 | "2", 102 | "3", 103 | ] 104 | """) 105 | } 106 | 107 | func testArrayWithNilString2() { 108 | let nilString: String? = nil 109 | let code = build { 110 | nilString 111 | "1" 112 | "2" 113 | "3" 114 | nilString 115 | }.text 116 | 117 | XCTAssertEqual(code, """ 118 | [ 119 | "1", 120 | "2", 121 | "3", 122 | ] 123 | """) 124 | } 125 | } 126 | 127 | // MARK: Select 128 | extension StarlarkTests { 129 | func testSelectSame() { 130 | let code = Starlark.Select.same("test").starlark 131 | XCTAssertEqual(code.text, "\"test\"") 132 | } 133 | 134 | func testSelectVarious() { 135 | let code = Starlark.Select.various([ 136 | "Release": "r", 137 | "Debug": "d", 138 | ]).starlark 139 | 140 | XCTAssertEqual(code.text, """ 141 | select({ 142 | "//:Debug": "d", 143 | "//:Release": "r" 144 | }) 145 | """) 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /Tests/UtilTests/UtilTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SPMTests.swift 3 | // 4 | // 5 | // Created by Yume on 2022/4/25. 6 | // 7 | 8 | import Foundation 9 | import XCTest 10 | @testable import Util 11 | 12 | final class UtilTests: XCTestCase { 13 | func testIndent1() throws { 14 | let origin = """ 15 | 1 16 | 2 17 | 3 18 | """ 19 | let result = """ 20 | 1 21 | 2 22 | 3 23 | """ 24 | 25 | XCTAssertEqual(origin.indent(1, " "), result) 26 | } 27 | 28 | func testIndent2() throws { 29 | let origin = """ 30 | 1 31 | 2 32 | 3 33 | """ 34 | let result = """ 35 | 1 36 | 2 37 | 3 38 | """ 39 | 40 | XCTAssertEqual(origin.indent(2, " "), result) 41 | } 42 | 43 | func testIndent2_1() throws { 44 | let origin = """ 45 | 1 46 | 2 47 | 3 48 | """ 49 | let result = """ 50 | 1 51 | 2 52 | 3 53 | """ 54 | 55 | XCTAssertEqual(origin.indent(2, " "), result) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Tests/XCodeTests/PropertyTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PropertyTests.swift 3 | // 4 | // 5 | // Created by Yume on 2022/8/3. 6 | // 7 | 8 | import PluginInterface 9 | import XcodeProj 10 | import XCTest 11 | @testable import XCode 12 | 13 | // MARK: - Setting 14 | 15 | private struct Setting: XCodeBuildSetting { 16 | // MARK: Lifecycle 17 | 18 | init(_ setting: [String: Any]) { 19 | self.setting = setting 20 | } 21 | 22 | // MARK: Internal 23 | 24 | let setting: [String: Any] 25 | 26 | var plist: [String] { [] } 27 | 28 | var name: String { "" } 29 | 30 | var bundleID: String? { self[#function] } 31 | 32 | var team: String? { self[#function] } 33 | 34 | var swiftVersion: String? { self[#function] } 35 | 36 | var deviceFamily: [String] { [] } 37 | 38 | var sdk: SDK? { nil } 39 | 40 | var iOS: String? { self[#function] } 41 | 42 | var macOS: String? { self[#function] } 43 | 44 | var tvOS: String? { self[#function] } 45 | 46 | var watchOS: String? { self[#function] } 47 | 48 | var driverKit: String? { self[#function] } 49 | 50 | var generateInfoPlist: Bool { false } 51 | 52 | var plistKeys: [String] { [] } 53 | 54 | var infoPlist: String? { nil } 55 | 56 | var defaultPlist: [String] { [] } 57 | 58 | var launch: String? { self[#function] } 59 | 60 | var storyboard: String? { self[#function] } 61 | 62 | var testHost: String? { nil } 63 | var testTargetName: String? { nil } 64 | var bundleLoader: String? { nil } 65 | 66 | var swiftDefine: String? { nil } 67 | var enableModules: Bool { false } 68 | 69 | // MARK: Private 70 | 71 | private subscript(key: String) -> T? { 72 | setting[key] as? T 73 | } 74 | } 75 | 76 | // MARK: - XCodeTests 77 | 78 | final class XCodeTests: XCTestCase { 79 | private static let release = Setting([ 80 | "iOS": "9.0", 81 | "macOS": "10.15", 82 | ]) 83 | private static let debug = Setting([ 84 | "iOS": "10.0", 85 | "macOS": "10.15", 86 | ]) 87 | private static let config: [String: XCodeBuildSetting] = [ 88 | "Release": release, 89 | "Debug": debug, 90 | ] 91 | } 92 | 93 | // MARK: Test Select 94 | extension XCodeTests { 95 | func testSelectSame() { 96 | let code = Self.config.select(\.macOS).starlark.text 97 | XCTAssertEqual(code, """ 98 | "10.15" 99 | """) 100 | } 101 | 102 | func testSelectVarious() { 103 | let code = Self.config.select(\.iOS).starlark.text 104 | XCTAssertEqual(code, """ 105 | select({ 106 | "//:Debug": "10.0", 107 | "//:Release": "9.0" 108 | }) 109 | """) 110 | } 111 | } 112 | 113 | // MARK: Test Prefer 114 | extension XCodeTests { 115 | func testPreferHit() { 116 | let code = Self.config.prefer(config: "Release", \.iOS) 117 | XCTAssertEqual(code, "9.0") 118 | } 119 | 120 | func testPreferNotHit() { 121 | let code = Self.config.prefer(config: "Release2", \.iOS) 122 | XCTAssertEqual(code, "10.0") 123 | } 124 | 125 | func testPreferNoValue() { 126 | let config: [String: XCodeBuildSetting] = [:] 127 | let code = config.prefer(config: "Release", \.iOS) 128 | XCTAssertEqual(code, nil) 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /docs/Design.md: -------------------------------------------------------------------------------- 1 | # Bazelize 2 | 3 | --- 4 | 5 | ## `Bazelize` Objectives 6 | 7 | 1. Migrating to `bazel` with minimal impact on existing `XCode` projects. 8 | * See [Ref](#Ref) 9 | 2. Migrating `xxx.xcodeproj` and its dependencies to `bazel`, for example, `pod`, `spm`. 10 | 11 | ---- 12 | 13 | ### Parsing `xcodeproj` 14 | 15 | The project is parsed by [XcodeProj](https://github.com/tuist/XcodeProj) to get the `XCode Target` settings, and then filled into the corresponding `rules`. 16 | 17 | (Follow-up implmentation direction: `XCode Target` -> middle layer -> generate code) 18 | 19 | > `Xcode Target` is treated as [Bazel Packages](https://docs.bazel.build/versions/4.2.1/build-ref.html#packages) 20 | 21 | See [`XCode Target` setting](#XCode-Target-setting) 22 | --- 23 | 24 | ## Dependency Management 25 | 26 | See [Dependecy](Dependecy.md) 27 | --- 28 | 29 | ## Design of Bazelize 30 | 31 | ---- 32 | 33 | ### xxx_library 34 | 35 | First, let's talk about the code part. Our code will be applied to special rules, such as `xxx_library`. 36 | 37 | (Currently, only `xxx_library` can be applied to the same language) 38 | 39 | We are currently focusing on `swift_library` and `objc_library` implementations. 40 | 41 | Fortunately, `XCode Target` seems to support only one language. 42 | 43 | > Except for application, we can use `bridge-header` or generated header `${target_name}-Swift.h` 44 | 45 | 46 | ### `XCode Target` type 47 | 48 | We will start with the `XCode Target` type, and then we will implement the most common types. 49 | 50 | See [PBXProductType][product_type]. 51 | 52 | #### Identifying `XCode Target` type 53 | 54 | The criterion are [PBXProductType][product_type] and [XCConfigurationList][config_list]. 55 | 56 | ### `XCode Target` + `Naming Rule` 57 | 58 | `BUILD` file contains two types of rules, `xxx_library` and `main rule`. 59 | 60 | (working in progress) 61 | -------------------------------------------------------------------------------- /docs/Podfile+PodToBUILD.md: -------------------------------------------------------------------------------- 1 | # Podfile 2 | 3 | --- 4 | 5 | ## PodToBUILD Dependency 6 | 7 | > `//Vendor/__PACKAGE__:__TARGET__` 8 | 9 | ## Get information from Podfile 10 | 11 | ```sh 12 | pod ipc podfile-json Podfile 13 | ``` 14 | 15 | ```json 16 | { 17 | // ... 18 | "name": "SOME_TARGET", 19 | "dependencies": [ 20 | "Peek", 21 | { 22 | "AFNetworking": [ 23 | "~> 4.0" 24 | ] 25 | }, 26 | "Moya/RxSwift", 27 | "Moya/Combine", 28 | { 29 | "DataCompression": [ 30 | { 31 | "git": "https://github.com/mw99/DataCompression" 32 | } 33 | ] 34 | }, 35 | ] 36 | } 37 | ``` 38 | 39 | ## Dependencies 40 | 41 | ```yaml 42 | target: SOME_TARGET 43 | dependency: 44 | - "//Vendor/Peek:Peek" 45 | - "//Vendor/AFNetworking:AFNetworking" 46 | - "//Vendor/Moya:RxSwift" 47 | - "//Vendor/Moya:Combine" 48 | - "//Vendor/DataCompression:DataCompression" 49 | ``` -------------------------------------------------------------------------------- /docs/Podfile.lock.md: -------------------------------------------------------------------------------- 1 | # Podfile.Lock -> Pods.WORKSPACE 2 | 3 | --- 4 | 5 | ### Github 6 | 7 | > https://github.com/${organization,user}/${repo}/archive/${commit,branch,tag}.zip 8 | 9 | ### Regular Pod 10 | 11 | #### Podfile 12 | 13 | ```ruby 14 | pod Bagel 15 | ``` 16 | 17 | #### Pod Spec Command 18 | 19 | ```sh 20 | pod spec cat Bagel --version=1.4.0 21 | ``` 22 | 23 | ```json 24 | { 25 | // ... 26 | "source": { 27 | "git": "https://github.com/yagiz/Bagel.git", 28 | "tag": "1.4.0" 29 | }, 30 | } 31 | ``` 32 | 33 | #### Result 34 | 35 | ```bazel 36 | new_pod_repository( 37 | name = "Bagel", 38 | url = "https://github.com/yagiz/Bagel/archive/1.4.0.zip" 39 | ) 40 | ``` 41 | 42 | ---- 43 | 44 | ### From a podspec in the root of a library repository. 45 | 46 | #### Podfile 47 | 48 | ```ruby 49 | pod 'XLPagerTabStrip', :git => "https://github.com/xmartlabs/XLPagerTabStrip", :branch => 'master' 50 | ``` 51 | 52 | #### Podfile.lock 53 | 54 | ```yaml 55 | # ... 56 | 57 | EXTERNAL SOURCES: 58 | XLPagerTabStrip: 59 | :branch: master 60 | :git: https://github.com/xmartlabs/XLPagerTabStrip 61 | 62 | CHECKOUT OPTIONS: 63 | XLPagerTabStrip: 64 | :commit: 903b7609b2b2dd1010efb9ee1c6a27edaa9df89b 65 | :git: https://github.com/xmartlabs/XLPagerTabStrip 66 | ``` 67 | 68 | 69 | #### Result 70 | 71 | ```bazel 72 | new_pod_repository( 73 | name = "XLPagerTabStrip", 74 | url = "https://github.com/xmartlabs/XLPagerTabStrip/archive/master.zip" 75 | ) 76 | ``` -------------------------------------------------------------------------------- /docs/Podfile.md: -------------------------------------------------------------------------------- 1 | # [Podfile](https://guides.cocoapods.org/using/the-podfile.html) 2 | 3 | * Build configurations 4 | * `:configurations => ['Debug', 'Beta']` 5 | * Modular Headers 6 | * `:modular_headers => true` 7 | * Source 8 | * `:source => 'https://github.com/CocoaPods/Specs.git'` 9 | * Subspecs 10 | * `pod 'QueryKit/Attribute'` 11 | * `pod 'QueryKit', :subspecs => ['Attribute', 'QuerySet']` 12 | * Test Specs 13 | * `:testspecs => ['UnitTests', 'SomeOtherTests']` 14 | * local path 15 | * `:path => '~/Documents/AFNetworking'` 16 | * From a podspec in the root of a library repository. 17 | * `pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'` 18 | * `pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :branch => 'dev'` 19 | * `pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :tag => '0.7.0'` 20 | * `pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'` 21 | * From a podspec outside a spec repository, for a library without podspec. 22 | * `:podspec => 'https://example.com/JSONKit.podspec'` -------------------------------------------------------------------------------- /docs/Rules.md: -------------------------------------------------------------------------------- 1 | # Bazel Rules 2 | 3 | * [rules_apple](https://github.com/bazelbuild/rules_apple/tree/master/doc) 4 | * [frameworks](https://github.com/bazelbuild/rules_apple/blob/master/doc/frameworks.md) 5 | * prebuilt 6 | `apple_dynamic_framework_import` 7 | `apple_static_framework_import` 8 | * [resources](https://github.com/bazelbuild/rules_apple/blob/master/doc/resources.md) 9 | * [rules_swift](https://github.com/bazelbuild/rules_swift/blob/master/doc/rules.md#swift_proto_library) 10 | * [PodToBUILD](https://github.com/pinterest/PodToBUILD/blob/master/BazelExtensions/workspace.bzl#L218) 11 | -------------------------------------------------------------------------------- /docs/SPM.md: -------------------------------------------------------------------------------- 1 | ## workspace 2 | 3 | ```bazel 4 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 5 | 6 | http_archive( 7 | name = "cgrindel_rules_spm", 8 | sha256 = "ba4310ba33cd1864a95e41d1ceceaa057e56ebbe311f74105774d526d68e2a0d", 9 | strip_prefix = "rules_spm-0.10.0", 10 | urls = [ 11 | "http://github.com/cgrindel/rules_spm/archive/v0.10.0.tar.gz", 12 | ], 13 | ) 14 | 15 | load( 16 | "@cgrindel_rules_spm//spm:deps.bzl", 17 | "spm_rules_dependencies", 18 | ) 19 | 20 | spm_rules_dependencies() 21 | 22 | load( 23 | "@build_bazel_rules_swift//swift:repositories.bzl", 24 | "swift_rules_dependencies", 25 | ) 26 | 27 | swift_rules_dependencies() 28 | 29 | load( 30 | "@build_bazel_rules_swift//swift:extras.bzl", 31 | "swift_rules_extra_dependencies", 32 | ) 33 | 34 | swift_rules_extra_dependencies() 35 | ``` 36 | 37 | ## Workspace 38 | 39 | ```bazel 40 | load("@cgrindel_rules_spm//spm:defs.bzl", "spm_pkg", "spm_repositories") 41 | 42 | spm_repositories( 43 | name = "swift_pkgs", 44 | dependencies = [ 45 | spm_pkg( 46 | "https://github.com/apple/swift-log.git", 47 | exact_version = "1.4.2", 48 | products = ["Logging"], 49 | ), 50 | ], 51 | ) 52 | ``` 53 | 54 | ## import 55 | 56 | ```bazel 57 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_binary") 58 | 59 | swift_binary( 60 | name = "simple", 61 | srcs = ["main.swift"], 62 | visibility = ["//swift:__subpackages__"], 63 | deps = [ 64 | "@swift_pkgs//swift-log:Logging", 65 | ], 66 | ) 67 | ``` 68 | -------------------------------------------------------------------------------- /fixture/iOS/.bazelrc: -------------------------------------------------------------------------------- 1 | import %workspace%/config.bazelrc 2 | 3 | build --disk_cache=cache 4 | # build --experimental_enable_bzlmod 5 | 6 | # build --apple_platform_type=ios 7 | # build --verbose_failures 8 | 9 | 10 | # build --macos_minimum_os=10.15 11 | 12 | # # Make sure no warnings slip into the C++ tools we vendor 13 | # build --features treat_warnings_as_errors 14 | 15 | # # The default strategy is worker, which has sandboxing disabled by default, 16 | # # which can hide issues with non-hermetic bugs. 17 | # build --strategy=SwiftCompile=sandboxed 18 | 19 | # # build --ios_minimum_os=15.5 20 | # # build --ios_simulator_device="iPhone 13" 21 | # # build --ios_simulator_version=15.5 22 | # # build --xcode_version=13.4.1 -------------------------------------------------------------------------------- /fixture/iOS/.bazelversion: -------------------------------------------------------------------------------- 1 | 6.0.0 -------------------------------------------------------------------------------- /fixture/iOS/Example/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "universal", 6 | "reference" : "systemMintColor" 7 | }, 8 | "idiom" : "universal" 9 | } 10 | ], 11 | "info" : { 12 | "author" : "xcode", 13 | "version" : 1 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fixture/iOS/Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "bazel.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fixture/iOS/Example/Assets.xcassets/AppIcon.appiconset/bazel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/Example/Assets.xcassets/AppIcon.appiconset/bazel.png -------------------------------------------------------------------------------- /fixture/iOS/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /fixture/iOS/Example/Assets.xcassets/bazel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "bazel.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /fixture/iOS/Example/Assets.xcassets/bazel.imageset/bazel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/Example/Assets.xcassets/bazel.imageset/bazel.png -------------------------------------------------------------------------------- /fixture/iOS/Example/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Example 4 | // 5 | // Created by Yume on 2023/1/7. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | // MARK: - Frameworks 12 | import Framework1 13 | import Framework2 14 | import Framework3 15 | 16 | // MARK: - Static 17 | #if canImport(Static) 18 | import Static 19 | #endif 20 | #if canImport(Static2) 21 | import Static2 22 | #endif 23 | 24 | // MARK: - Remote SPM 25 | #if canImport(AnyCodable) 26 | import AnyCodable 27 | #endif 28 | 29 | // MARK: - Local SPM deps 30 | #if canImport(RxSwift) 31 | import RxSwift 32 | #endif 33 | 34 | // MARK: - Local SPM 35 | #if canImport(LocalTarget1) 36 | import LocalTarget1 37 | #endif 38 | #if canImport(LocalTarget2) 39 | import LocalTarget2 40 | #endif 41 | #if canImport(LocalTarget3) 42 | import LocalTarget3 43 | #endif 44 | 45 | // MARK: - Imported Framework 46 | import SVProgressHUDShare 47 | 48 | // MARK: - ContentView 49 | 50 | struct ContentView: View { 51 | var body: some View { 52 | VStack { 53 | VStack { 54 | Text("Assets") 55 | Image("bazel") 56 | .imageScale(.large) 57 | .foregroundColor(.accentColor) 58 | }.background(Color.brown) 59 | VStack { 60 | Text("Localize") 61 | Text("hello") 62 | }.background(Color.red) 63 | VStack { 64 | Text("Config") 65 | #if YDebug 66 | Text("Debug") 67 | #elseif YRelease 68 | Text("Release") 69 | #else 70 | Text("None") 71 | #endif 72 | }.background(Color.green) 73 | VStack { 74 | Text("Frameworks") 75 | Text(Framework1.test()) 76 | Text(Framework2.test()) 77 | Text(Framework3.test()) 78 | #if canImport(Static) 79 | Text(Static.test()) 80 | #endif 81 | #if canImport(Static2) 82 | Text(Static2.test()) 83 | #endif 84 | }.background(Color.blue) 85 | VStack { 86 | Text("SPM") 87 | #if canImport(AnyCodable) 88 | Text(type: AnyCodable.self) 89 | #endif 90 | #if canImport(RxSwift) 91 | Text(type: MainScheduler.self) 92 | #endif 93 | #if canImport(LocalTarget1) 94 | Text(type: LocalTarget1.self) 95 | #endif 96 | #if canImport(LocalTarget2) 97 | Text(type: LocalTarget2.self) 98 | #endif 99 | #if canImport(LocalTarget3) 100 | Text(type: LocalTarget3.self) 101 | Text("\(LocalTarget3.test())") 102 | #endif 103 | }.background(Color.red) 104 | VStack { 105 | Text("Imported") 106 | Text(type: SVProgressHUD.self) 107 | }.background(Color.green) 108 | } 109 | .foregroundColor(Color.white) 110 | .padding() 111 | } 112 | } 113 | 114 | extension Text { 115 | init(type: T.Type) { 116 | let text = "\(type)" 117 | self.init(text) 118 | } 119 | } 120 | 121 | 122 | // MARK: - ContentView_Previews 123 | 124 | struct ContentView_Previews: PreviewProvider { 125 | static var previews: some View { 126 | ContentView() 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /fixture/iOS/Example/ExampleApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleApp.swift 3 | // Example 4 | // 5 | // Created by Yume on 2023/1/7. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct ExampleApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /fixture/iOS/Example/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /fixture/iOS/Example/Test.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Test.swift 3 | // Example 4 | // 5 | // Created by Yume on 2023/1/7. 6 | // 7 | 8 | import Foundation 9 | 10 | func test() -> Int { 11 | 0 12 | } 13 | -------------------------------------------------------------------------------- /fixture/iOS/Example/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | Example 4 | 5 | Created by Yume on 2023/1/9. 6 | 7 | */ 8 | 9 | "hello" = "Hello, world!!"; 10 | -------------------------------------------------------------------------------- /fixture/iOS/Example/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | Example 4 | 5 | Created by Yume on 2023/1/9. 6 | 7 | */ 8 | 9 | "hello" = "你好世界!!!"; 10 | -------------------------------------------------------------------------------- /fixture/iOS/ExampleTests/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test") 5 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 6 | 7 | swift_library( 8 | name = "ExampleTests_swift", 9 | module_name = "ExampleTests", 10 | srcs = [ 11 | "//ExampleTests:ExampleTests.swift", 12 | ], 13 | testonly = True, 14 | deps = [ 15 | "//Example:Example_library", 16 | ], 17 | # data = None, 18 | defines = None, 19 | visibility = [ 20 | "//visibility:private", 21 | ], 22 | ) 23 | 24 | alias( 25 | name = "ExampleTests_library", 26 | actual = "ExampleTests_swift", 27 | visibility = [ 28 | "//visibility:public", 29 | ], 30 | ) 31 | 32 | plist_fragment( 33 | name = "plist_default", 34 | extension = "plist", 35 | template = ''' 36 | CFBundleDevelopmentRegion 37 | $(DEVELOPMENT_LANGUAGE) 38 | CFBundleExecutable 39 | $(EXECUTABLE_NAME) 40 | CFBundleIdentifier 41 | $(PRODUCT_BUNDLE_IDENTIFIER) 42 | CFBundleName 43 | $(PRODUCT_NAME) 44 | CFBundlePackageType 45 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 46 | CFBundleShortVersionString 47 | 1.0 48 | CFBundleVersion 49 | 1 50 | ''', 51 | visibility = [ 52 | "//visibility:private", 53 | ], 54 | ) 55 | 56 | ios_unit_test( 57 | name = "ExampleTests", 58 | minimum_os_version = "16.2", 59 | deps = [ 60 | ":ExampleTests_library", 61 | ], 62 | visibility = [ 63 | "//visibility:public", 64 | ], 65 | ) -------------------------------------------------------------------------------- /fixture/iOS/ExampleTests/ExampleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleTests.swift 3 | // ExampleTests 4 | // 5 | // Created by Yume on 2023/1/7. 6 | // 7 | 8 | import XCTest 9 | @testable import Example 10 | 11 | final class ExampleTests: XCTestCase { 12 | func testExample() throws { 13 | XCTAssertEqual(test(), 0) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fixture/iOS/ExampleUITests/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_ui_test") 5 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 6 | 7 | swift_library( 8 | name = "ExampleUITests_swift", 9 | module_name = "ExampleUITests", 10 | srcs = [ 11 | "//ExampleUITests:ExampleUITests.swift", 12 | "//ExampleUITests:ExampleUITestsLaunchTests.swift", 13 | ], 14 | testonly = True, 15 | # deps = None, 16 | # data = None, 17 | defines = None, 18 | visibility = [ 19 | "//visibility:private", 20 | ], 21 | ) 22 | 23 | alias( 24 | name = "ExampleUITests_library", 25 | actual = "ExampleUITests_swift", 26 | visibility = [ 27 | "//visibility:public", 28 | ], 29 | ) 30 | 31 | plist_fragment( 32 | name = "plist_default", 33 | extension = "plist", 34 | template = ''' 35 | CFBundleDevelopmentRegion 36 | $(DEVELOPMENT_LANGUAGE) 37 | CFBundleExecutable 38 | $(EXECUTABLE_NAME) 39 | CFBundleIdentifier 40 | $(PRODUCT_BUNDLE_IDENTIFIER) 41 | CFBundleName 42 | $(PRODUCT_NAME) 43 | CFBundlePackageType 44 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 45 | CFBundleShortVersionString 46 | 1.0 47 | CFBundleVersion 48 | 1 49 | ''', 50 | visibility = [ 51 | "//visibility:private", 52 | ], 53 | ) 54 | 55 | ios_ui_test( 56 | name = "ExampleUITests", 57 | test_host = "//Example:Example", 58 | minimum_os_version = "16.2", 59 | deps = [ 60 | ":ExampleUITests_library", 61 | ], 62 | visibility = [ 63 | "//visibility:public", 64 | ], 65 | ) -------------------------------------------------------------------------------- /fixture/iOS/ExampleUITests/ExampleUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleUITests.swift 3 | // ExampleUITests 4 | // 5 | // Created by Yume on 2023/1/7. 6 | // 7 | 8 | import XCTest 9 | 10 | final class ExampleUITests: XCTestCase { 11 | override func setUpWithError() throws { 12 | // Put setup code here. This method is called before the invocation of each test method in the class. 13 | 14 | // In UI tests it is usually best to stop immediately when a failure occurs. 15 | continueAfterFailure = false 16 | 17 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 18 | } 19 | 20 | override func tearDownWithError() throws { 21 | // Put teardown code here. This method is called after the invocation of each test method in the class. 22 | } 23 | 24 | func testExample() throws { 25 | // UI tests must launch the application that they test. 26 | let app = XCUIApplication() 27 | app.launch() 28 | 29 | // Use XCTAssebrt and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | func testLaunchPerformance() throws { 33 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { 34 | // This measures how long it takes to launch your application. 35 | measure(metrics: [XCTApplicationLaunchMetric()]) { 36 | XCUIApplication().launch() 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /fixture/iOS/ExampleUITests/ExampleUITestsLaunchTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleUITestsLaunchTests.swift 3 | // ExampleUITests 4 | // 5 | // Created by Yume on 2023/1/7. 6 | // 7 | 8 | import XCTest 9 | 10 | final class ExampleUITestsLaunchTests: XCTestCase { 11 | override class var runsForEachTargetApplicationUIConfiguration: Bool { 12 | true 13 | } 14 | 15 | override func setUpWithError() throws { 16 | continueAfterFailure = false 17 | } 18 | 19 | func testLaunch() throws { 20 | let app = XCUIApplication() 21 | app.launch() 22 | 23 | // Insert steps here to perform after app launch but before taking a screenshot, 24 | // such as logging into a test account or navigating somewhere in the app 25 | 26 | let attachment = XCTAttachment(screenshot: app.screenshot()) 27 | attachment.name = "Launch Screen" 28 | attachment.lifetime = .keepAlways 29 | add(attachment) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /fixture/iOS/Framework1/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_framework") 5 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 6 | 7 | swift_library( 8 | name = "Framework1_swift", 9 | module_name = "Framework1", 10 | srcs = [ 11 | "//Framework1:Test.swift", 12 | ], 13 | testonly = False, 14 | deps = [ 15 | "//Framework2:Framework2_library", 16 | "//Static:Static_library", 17 | ], 18 | # data = None, 19 | defines = None, 20 | visibility = [ 21 | "//visibility:private", 22 | ], 23 | ) 24 | 25 | alias( 26 | name = "Framework1_library", 27 | actual = "Framework1_swift", 28 | visibility = [ 29 | "//visibility:public", 30 | ], 31 | ) 32 | 33 | plist_fragment( 34 | name = "plist_auto", 35 | extension = "plist", 36 | template = ''' 37 | 38 | 39 | ''', 40 | visibility = [ 41 | "//visibility:private", 42 | ], 43 | ) 44 | 45 | plist_fragment( 46 | name = "plist_default", 47 | extension = "plist", 48 | template = ''' 49 | CFBundleDevelopmentRegion 50 | $(DEVELOPMENT_LANGUAGE) 51 | CFBundleExecutable 52 | $(EXECUTABLE_NAME) 53 | CFBundleIdentifier 54 | $(PRODUCT_BUNDLE_IDENTIFIER) 55 | CFBundleName 56 | $(PRODUCT_NAME) 57 | CFBundlePackageType 58 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 59 | CFBundleShortVersionString 60 | 1.0 61 | CFBundleVersion 62 | 1 63 | ''', 64 | visibility = [ 65 | "//visibility:private", 66 | ], 67 | ) 68 | 69 | ios_framework( 70 | name = "Framework1", 71 | bundle_id = "com.bazel.Framework1", 72 | families = [ 73 | "iphone", 74 | "ipad", 75 | ], 76 | minimum_os_version = "16.2", 77 | infoplists = [ 78 | ":plist_auto", 79 | ], 80 | deps = [ 81 | ":Framework1_library", 82 | "//Framework2:Framework2", 83 | "//Static:Static", 84 | ], 85 | visibility = [ 86 | "//visibility:public", 87 | ], 88 | ) -------------------------------------------------------------------------------- /fixture/iOS/Framework1/Framework1.h: -------------------------------------------------------------------------------- 1 | // 2 | // Framework1.h 3 | // Framework1 4 | // 5 | // Created by Yume on 2023/1/10. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for Framework1. 11 | FOUNDATION_EXPORT double Framework1VersionNumber; 12 | 13 | //! Project version string for Framework1. 14 | FOUNDATION_EXPORT const unsigned char Framework1VersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /fixture/iOS/Framework1/Test.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Test.swift 3 | // Framework1 4 | // 5 | // Created by Yume on 2023/1/10. 6 | // 7 | 8 | import Foundation 9 | import Framework2 10 | import Static 11 | 12 | public enum Framework1 { 13 | public static func test() -> String { 14 | "Framework1+Swift" 15 | } 16 | 17 | public static func test2() -> String { 18 | Framework2.test() 19 | } 20 | 21 | public static func test3() -> String { 22 | Static.test() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /fixture/iOS/Framework1Tests/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test") 5 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 6 | 7 | swift_library( 8 | name = "Framework1Tests_swift", 9 | module_name = "Framework1Tests", 10 | srcs = [ 11 | "//Framework1Tests:Framework1Tests.swift", 12 | ], 13 | testonly = True, 14 | deps = [ 15 | "//Framework1:Framework1_library", 16 | ], 17 | # data = None, 18 | defines = None, 19 | visibility = [ 20 | "//visibility:private", 21 | ], 22 | ) 23 | 24 | alias( 25 | name = "Framework1Tests_library", 26 | actual = "Framework1Tests_swift", 27 | visibility = [ 28 | "//visibility:public", 29 | ], 30 | ) 31 | 32 | plist_fragment( 33 | name = "plist_default", 34 | extension = "plist", 35 | template = ''' 36 | CFBundleDevelopmentRegion 37 | $(DEVELOPMENT_LANGUAGE) 38 | CFBundleExecutable 39 | $(EXECUTABLE_NAME) 40 | CFBundleIdentifier 41 | $(PRODUCT_BUNDLE_IDENTIFIER) 42 | CFBundleName 43 | $(PRODUCT_NAME) 44 | CFBundlePackageType 45 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 46 | CFBundleShortVersionString 47 | 1.0 48 | CFBundleVersion 49 | 1 50 | ''', 51 | visibility = [ 52 | "//visibility:private", 53 | ], 54 | ) 55 | 56 | ios_unit_test( 57 | name = "Framework1Tests", 58 | minimum_os_version = "16.2", 59 | deps = [ 60 | ":Framework1Tests_library", 61 | ], 62 | visibility = [ 63 | "//visibility:public", 64 | ], 65 | ) -------------------------------------------------------------------------------- /fixture/iOS/Framework1Tests/Framework1Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Framework1Tests.swift 3 | // Framework1Tests 4 | // 5 | // Created by Yume on 2023/1/10. 6 | // 7 | 8 | import AVFoundation 9 | import Framework2 10 | import Static 11 | import XCTest 12 | @testable import Framework1 13 | 14 | final class Framework1Tests: XCTestCase { 15 | func testFramework1() throws { 16 | XCTAssertEqual(Framework1.test(), "Framework1+Swift") 17 | XCTAssertEqual(Framework1.test2(), "Framework2+Swift") 18 | } 19 | 20 | func testFramework2() throws { 21 | XCTAssertEqual(Framework2.test(), "Framework2+Swift") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fixture/iOS/Framework2/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_framework") 5 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 6 | 7 | swift_library( 8 | name = "Framework2_swift", 9 | module_name = "Framework2", 10 | srcs = [ 11 | "//Framework2:Test.swift", 12 | ], 13 | testonly = False, 14 | # deps = None, 15 | # data = None, 16 | defines = None, 17 | visibility = [ 18 | "//visibility:private", 19 | ], 20 | ) 21 | 22 | alias( 23 | name = "Framework2_library", 24 | actual = "Framework2_swift", 25 | visibility = [ 26 | "//visibility:public", 27 | ], 28 | ) 29 | 30 | plist_fragment( 31 | name = "plist_auto", 32 | extension = "plist", 33 | template = ''' 34 | 35 | 36 | ''', 37 | visibility = [ 38 | "//visibility:private", 39 | ], 40 | ) 41 | 42 | plist_fragment( 43 | name = "plist_default", 44 | extension = "plist", 45 | template = ''' 46 | CFBundleDevelopmentRegion 47 | $(DEVELOPMENT_LANGUAGE) 48 | CFBundleExecutable 49 | $(EXECUTABLE_NAME) 50 | CFBundleIdentifier 51 | $(PRODUCT_BUNDLE_IDENTIFIER) 52 | CFBundleName 53 | $(PRODUCT_NAME) 54 | CFBundlePackageType 55 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 56 | CFBundleShortVersionString 57 | 1.0 58 | CFBundleVersion 59 | 1 60 | ''', 61 | visibility = [ 62 | "//visibility:private", 63 | ], 64 | ) 65 | 66 | ios_framework( 67 | name = "Framework2", 68 | bundle_id = "com.bazel.Framework2", 69 | families = [ 70 | "iphone", 71 | "ipad", 72 | ], 73 | minimum_os_version = "16.2", 74 | infoplists = [ 75 | ":plist_auto", 76 | ], 77 | deps = [ 78 | ":Framework2_library", 79 | ], 80 | visibility = [ 81 | "//visibility:public", 82 | ], 83 | ) -------------------------------------------------------------------------------- /fixture/iOS/Framework2/Framework2.h: -------------------------------------------------------------------------------- 1 | // 2 | // Framework2.h 3 | // Framework2 4 | // 5 | // Created by Yume on 2023/1/10. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for Framework2. 11 | FOUNDATION_EXPORT double Framework2VersionNumber; 12 | 13 | //! Project version string for Framework2. 14 | FOUNDATION_EXPORT const unsigned char Framework2VersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /fixture/iOS/Framework2/Test.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Test.swift 3 | // Framework2 4 | // 5 | // Created by Yume on 2023/1/10. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum Framework2 { 11 | public static func test() -> String { 12 | "Framework2+Swift" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fixture/iOS/Framework2Tests/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test") 5 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 6 | 7 | swift_library( 8 | name = "Framework2Tests_swift", 9 | module_name = "Framework2Tests", 10 | srcs = [ 11 | "//Framework2Tests:Framework2Tests.swift", 12 | ], 13 | testonly = True, 14 | deps = [ 15 | "//Framework2:Framework2_library", 16 | ], 17 | # data = None, 18 | defines = None, 19 | visibility = [ 20 | "//visibility:private", 21 | ], 22 | ) 23 | 24 | alias( 25 | name = "Framework2Tests_library", 26 | actual = "Framework2Tests_swift", 27 | visibility = [ 28 | "//visibility:public", 29 | ], 30 | ) 31 | 32 | plist_fragment( 33 | name = "plist_default", 34 | extension = "plist", 35 | template = ''' 36 | CFBundleDevelopmentRegion 37 | $(DEVELOPMENT_LANGUAGE) 38 | CFBundleExecutable 39 | $(EXECUTABLE_NAME) 40 | CFBundleIdentifier 41 | $(PRODUCT_BUNDLE_IDENTIFIER) 42 | CFBundleName 43 | $(PRODUCT_NAME) 44 | CFBundlePackageType 45 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 46 | CFBundleShortVersionString 47 | 1.0 48 | CFBundleVersion 49 | 1 50 | ''', 51 | visibility = [ 52 | "//visibility:private", 53 | ], 54 | ) 55 | 56 | ios_unit_test( 57 | name = "Framework2Tests", 58 | minimum_os_version = "16.2", 59 | deps = [ 60 | ":Framework2Tests_library", 61 | ], 62 | visibility = [ 63 | "//visibility:public", 64 | ], 65 | ) -------------------------------------------------------------------------------- /fixture/iOS/Framework2Tests/Framework2Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Framework2Tests.swift 3 | // Framework2Tests 4 | // 5 | // Created by Yume on 2023/1/10. 6 | // 7 | 8 | import XCTest 9 | @testable import Framework2 10 | 11 | final class Framework2Tests: XCTestCase { 12 | func testExample() throws { 13 | XCTAssertEqual(Framework2.test(), "Framework2+Swift") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fixture/iOS/Framework3/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_framework") 5 | load("@rules_cc//cc:defs.bzl", "objc_library") 6 | 7 | objc_library( 8 | name = "Framework3_objc", 9 | module_name = "Framework3", 10 | srcs = [ 11 | "//Framework3:Framework.m", 12 | ], 13 | hdrs = [ 14 | "//Framework3:Framework3.h", 15 | "//Framework3:Framework.h", 16 | ], 17 | enable_modules = True, 18 | # pch = None, 19 | copts = [ 20 | "-fblocks", 21 | "-fobjc-arc", 22 | "-fPIC", 23 | "-fmodule-name=Framework3", 24 | ], 25 | testonly = False, 26 | # defines = None, 27 | # linkopts = None, 28 | includes = [ 29 | ".", 30 | ], 31 | # deps = None, 32 | visibility = [ 33 | "//visibility:private", 34 | ], 35 | ) 36 | 37 | alias( 38 | name = "Framework3_library", 39 | actual = "Framework3_objc", 40 | visibility = [ 41 | "//visibility:public", 42 | ], 43 | ) 44 | 45 | plist_fragment( 46 | name = "plist_auto", 47 | extension = "plist", 48 | template = ''' 49 | 50 | 51 | ''', 52 | visibility = [ 53 | "//visibility:private", 54 | ], 55 | ) 56 | 57 | plist_fragment( 58 | name = "plist_default", 59 | extension = "plist", 60 | template = ''' 61 | CFBundleDevelopmentRegion 62 | $(DEVELOPMENT_LANGUAGE) 63 | CFBundleExecutable 64 | $(EXECUTABLE_NAME) 65 | CFBundleIdentifier 66 | $(PRODUCT_BUNDLE_IDENTIFIER) 67 | CFBundleName 68 | $(PRODUCT_NAME) 69 | CFBundlePackageType 70 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 71 | CFBundleShortVersionString 72 | 1.0 73 | CFBundleVersion 74 | 1 75 | ''', 76 | visibility = [ 77 | "//visibility:private", 78 | ], 79 | ) 80 | 81 | ios_framework( 82 | name = "Framework3", 83 | bundle_id = "com.yume190.Framework3", 84 | families = [ 85 | "iphone", 86 | "ipad", 87 | ], 88 | minimum_os_version = "16.2", 89 | infoplists = [ 90 | ":plist_auto", 91 | ], 92 | deps = [ 93 | ":Framework3_library", 94 | ], 95 | visibility = [ 96 | "//visibility:public", 97 | ], 98 | ) -------------------------------------------------------------------------------- /fixture/iOS/Framework3/Framework.h: -------------------------------------------------------------------------------- 1 | // 2 | // Framework.h 3 | // Framework3 4 | // 5 | // Created by Yume on 2023/2/2. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface Framework3 : NSObject 13 | + (NSString*) test; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /fixture/iOS/Framework3/Framework.m: -------------------------------------------------------------------------------- 1 | // 2 | // Framework.m 3 | // Framework3 4 | // 5 | // Created by Yume on 2023/2/2. 6 | // 7 | 8 | #import "Framework.h" 9 | 10 | @implementation Framework3 11 | + (NSString*) test { 12 | return @"Framework3+Objc"; 13 | } 14 | @end 15 | -------------------------------------------------------------------------------- /fixture/iOS/Framework3/Framework3.h: -------------------------------------------------------------------------------- 1 | // 2 | // Framework3.h 3 | // Framework3 4 | // 5 | // Created by Yume on 2023/2/2. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for Framework3. 11 | FOUNDATION_EXPORT double Framework3VersionNumber; 12 | 13 | //! Project version string for Framework3. 14 | FOUNDATION_EXPORT const unsigned char Framework3VersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | //#import 19 | //#include 20 | #import "Framework.h" 21 | //#include "Framework.h" 22 | 23 | -------------------------------------------------------------------------------- /fixture/iOS/Framework3Tests/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test") 5 | load("@rules_cc//cc:defs.bzl", "objc_library") 6 | 7 | objc_library( 8 | name = "Framework3Tests_objc", 9 | module_name = "Framework3Tests", 10 | srcs = [ 11 | "//Framework3Tests:Framework3Tests.m", 12 | ], 13 | # hdrs = None, 14 | enable_modules = True, 15 | # pch = None, 16 | copts = [ 17 | "-fblocks", 18 | "-fobjc-arc", 19 | "-fPIC", 20 | "-fmodule-name=Framework3Tests", 21 | ], 22 | testonly = True, 23 | # defines = None, 24 | # linkopts = None, 25 | includes = [ 26 | ".", 27 | ], 28 | deps = [ 29 | "//Framework3:Framework3_library", 30 | ], 31 | visibility = [ 32 | "//visibility:private", 33 | ], 34 | ) 35 | 36 | alias( 37 | name = "Framework3Tests_library", 38 | actual = "Framework3Tests_objc", 39 | visibility = [ 40 | "//visibility:public", 41 | ], 42 | ) 43 | 44 | plist_fragment( 45 | name = "plist_default", 46 | extension = "plist", 47 | template = ''' 48 | CFBundleDevelopmentRegion 49 | $(DEVELOPMENT_LANGUAGE) 50 | CFBundleExecutable 51 | $(EXECUTABLE_NAME) 52 | CFBundleIdentifier 53 | $(PRODUCT_BUNDLE_IDENTIFIER) 54 | CFBundleName 55 | $(PRODUCT_NAME) 56 | CFBundlePackageType 57 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 58 | CFBundleShortVersionString 59 | 1.0 60 | CFBundleVersion 61 | 1 62 | ''', 63 | visibility = [ 64 | "//visibility:private", 65 | ], 66 | ) 67 | 68 | ios_unit_test( 69 | name = "Framework3Tests", 70 | minimum_os_version = "16.2", 71 | deps = [ 72 | ":Framework3Tests_library", 73 | ], 74 | visibility = [ 75 | "//visibility:public", 76 | ], 77 | ) -------------------------------------------------------------------------------- /fixture/iOS/Framework3Tests/Framework3Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Framework3Tests.m 3 | // Framework3Tests 4 | // 5 | // Created by Yume on 2023/2/2. 6 | // 7 | 8 | #import 9 | // @import Framework3; 10 | // #import 11 | #import "Framework3/Framework3.h" 12 | 13 | @interface Framework3Tests : XCTestCase 14 | 15 | @end 16 | 17 | @implementation Framework3Tests 18 | 19 | 20 | - (void)testExample { 21 | // This is an example of a functional test case. 22 | // Use XCTAssert and related functions to verify your tests produce the correct results. 23 | XCTAssertEqual(Framework3.test, @"Framework3+Objc"); 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /fixture/iOS/Local1/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /fixture/iOS/Local1/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.7 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Local1", 8 | products: [ 9 | // Products define the executables and libraries a package produces, and make them visible to other packages. 10 | .library( 11 | name: "LocalLib1", 12 | targets: ["LocalTarget1", "LocalTarget3"]), 13 | .library( 14 | name: "LocalLib2", 15 | targets: ["LocalTarget2"]), 16 | ], 17 | dependencies: [ 18 | // Dependencies declare other packages that this package depends on. 19 | .package(url: "https://github.com/ReactiveX/RxSwift", from: "6.5.0"), 20 | ], 21 | targets: [ 22 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 23 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 24 | .target( 25 | name: "LocalTarget1", 26 | dependencies: ["RxSwift"]), 27 | .target( 28 | name: "LocalTarget2", 29 | dependencies: ["RxSwift"]), 30 | .target( 31 | name: "LocalTarget3"), 32 | .testTarget( 33 | name: "Local1Tests", 34 | dependencies: ["LocalTarget1"]), 35 | ]) 36 | -------------------------------------------------------------------------------- /fixture/iOS/Local1/README.md: -------------------------------------------------------------------------------- 1 | # Local1 2 | 3 | A description of this package. 4 | -------------------------------------------------------------------------------- /fixture/iOS/Local1/Sources/LocalTarget1/LocalTarget1.swift: -------------------------------------------------------------------------------- 1 | public struct LocalTarget1 { 2 | public private(set) var text = "Hello, World!" 3 | 4 | public init() { } 5 | } 6 | -------------------------------------------------------------------------------- /fixture/iOS/Local1/Sources/LocalTarget2/LocalTarget2.swift: -------------------------------------------------------------------------------- 1 | public struct LocalTarget2 { 2 | public private(set) var text = "Hello, World!" 3 | 4 | public init() { } 5 | } 6 | -------------------------------------------------------------------------------- /fixture/iOS/Local1/Sources/LocalTarget3/include/LocalTarget3.h: -------------------------------------------------------------------------------- 1 | // 2 | // Framework.h 3 | // Framework3 4 | // 5 | // Created by Yume on 2023/2/2. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface LocalTarget3 : NSObject 13 | + (int) test; 14 | - (int) test2; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /fixture/iOS/Local1/Sources/LocalTarget3/src/LocalTarget3.m: -------------------------------------------------------------------------------- 1 | // 2 | // Framework.m 3 | // Framework3 4 | // 5 | // Created by Yume on 2023/2/2. 6 | // 7 | 8 | #import "LocalTarget3.h" 9 | 10 | @implementation LocalTarget3 11 | + (int) test { 12 | return 1 << 4; 13 | } 14 | - (int) test2 { 15 | return LocalTarget3.test; 16 | } 17 | @end 18 | -------------------------------------------------------------------------------- /fixture/iOS/Local1/Tests/Local1Tests/Local1Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import LocalTarget1 3 | 4 | final class Local1Tests: XCTestCase { 5 | func testExample() throws { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | XCTAssertEqual(LocalTarget1().text, "Hello, World!") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fixture/iOS/Local2/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /fixture/iOS/Local2/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.7 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Local2", 8 | products: [ 9 | // Products define the executables and libraries a package produces, and make them visible to other packages. 10 | .library( 11 | name: "Local2", 12 | targets: ["Local2"]), 13 | ], 14 | dependencies: [ 15 | // Dependencies declare other packages that this package depends on. 16 | // .package(url: /* package url */, from: "1.0.0"), 17 | ], 18 | targets: [ 19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 20 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 21 | .target( 22 | name: "Local2", 23 | dependencies: []), 24 | .testTarget( 25 | name: "Local2Tests", 26 | dependencies: ["Local2"]), 27 | ]) 28 | -------------------------------------------------------------------------------- /fixture/iOS/Local2/README.md: -------------------------------------------------------------------------------- 1 | # Local2 2 | 3 | A description of this package. 4 | -------------------------------------------------------------------------------- /fixture/iOS/Local2/Sources/Local2/Local2.swift: -------------------------------------------------------------------------------- 1 | public struct Local2 { 2 | public private(set) var text = "Hello, World!" 3 | 4 | public init() { } 5 | } 6 | -------------------------------------------------------------------------------- /fixture/iOS/Local2/Tests/Local2Tests/Local2Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import Local2 3 | 4 | final class Local2Tests: XCTestCase { 5 | func testExample() throws { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | XCTAssertEqual(Local2().text, "Hello, World!") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fixture/iOS/MODULE.bazel: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | module( 4 | name = "example", 5 | version = "0.0.1", 6 | ) 7 | 8 | bazel_dep( 9 | name = "bazel_skylib", 10 | version = "bazel_skylib", 11 | # repo_name = None, 12 | ) 13 | 14 | bazel_dep( 15 | name = "rules_apple", 16 | version = "rules_apple", 17 | repo_name = "build_bazel_rules_apple", 18 | ) 19 | 20 | bazel_dep(name = "rules_swift", version = "1.5.0", repo_name = "build_bazel_rules_swift") 21 | 22 | bazel_dep(name = "rules_xcodeproj", version = "0.12.3") 23 | 24 | bazel_dep(name = "rules_apple_linker", version = "0.3.0") -------------------------------------------------------------------------------- /fixture/iOS/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: bazelize 2 | bazelize: 3 | @bazelize --project Example.xcodeproj 4 | @bazel run //:swift_update_pkgs 5 | 6 | .PHONY: clear 7 | clear: 8 | @bazelize --project Example.xcodeproj --clear 9 | 10 | .PHONY: build 11 | build: 12 | bazel build Example 13 | 14 | .PHONY: updatePkg 15 | updatePkg: 16 | bazel run //:swift_update_pkgs 17 | 18 | .PHONY: run 19 | run: 20 | bazel run --config=Debug Example 21 | 22 | .PHONY: releaseRun 23 | releaseRun: 24 | bazel run --config=Release Example 25 | 26 | .PHONY: test 27 | test: 28 | bazel test \ 29 | --sandbox_debug \ 30 | ExampleTests \ 31 | Framework1Tests \ 32 | Framework2Tests \ 33 | Framework3Tests 34 | 35 | 36 | .PHONY: uitest 37 | uitest: 38 | bazel test ExampleUITests 39 | 40 | 41 | # 42 | # bazel run //:update_build_files 43 | # bazel test //... 44 | # --experimental_enable_bzlmod -------------------------------------------------------------------------------- /fixture/iOS/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "anycodable", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/Flight-School/AnyCodable", 7 | "state" : { 8 | "revision" : "862808b2070cd908cb04f9aafe7de83d35f81b05", 9 | "version" : "0.6.7" 10 | } 11 | }, 12 | { 13 | "identity" : "rxswift", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/ReactiveX/RxSwift", 16 | "state" : { 17 | "revision" : "b4307ba0b6425c0ba4178e138799946c3da594f8", 18 | "version" : "6.5.0" 19 | } 20 | } 21 | ], 22 | "version" : 2 23 | } 24 | -------------------------------------------------------------------------------- /fixture/iOS/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.7 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "MySwiftPackage", 6 | dependencies: [ 7 | .package(url: "https://github.com/Flight-School/AnyCodable", from: "0.6.7"), 8 | .package(path: "Local1"), 9 | ]) -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AvailableLibraries 6 | 7 | 8 | LibraryIdentifier 9 | ios-arm64_armv7 10 | LibraryPath 11 | SVProgressHUDShare.framework 12 | SupportedArchitectures 13 | 14 | arm64 15 | armv7 16 | 17 | SupportedPlatform 18 | ios 19 | 20 | 21 | LibraryIdentifier 22 | ios-arm64_x86_64-simulator 23 | LibraryPath 24 | SVProgressHUDShare.framework 25 | SupportedArchitectures 26 | 27 | arm64 28 | x86_64 29 | 30 | SupportedPlatform 31 | ios 32 | SupportedPlatformVariant 33 | simulator 34 | 35 | 36 | CFBundlePackageType 37 | XFWK 38 | XCFrameworkFormatVersion 39 | 1.0 40 | 41 | 42 | -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/Info.plist -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module SVProgressHUDShare { 2 | umbrella header "SVProgressHUD.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask@2x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask@3x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/error.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/error@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/error@2x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/error@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/error@3x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/info.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/info@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/info@2x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/info@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/info@3x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/success.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/success@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/success@2x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/success@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUD.bundle/success@3x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUDShare: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_armv7/SVProgressHUDShare.framework/SVProgressHUDShare -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/Info.plist -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module SVProgressHUDShare { 2 | umbrella header "SVProgressHUD.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask@2x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/angle-mask@3x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/error.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/error@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/error@2x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/error@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/error@3x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/info.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/info@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/info@2x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/info@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/info@3x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/success.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/success@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/success@2x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/success@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUD.bundle/success@3x.png -------------------------------------------------------------------------------- /fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUDShare: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XCodeBazelize/Bazelize/9d0f0d1e22b02fd36dafc0d43edf5c6a9ccd4217/fixture/iOS/SVProgressHUD.xcframework/ios-arm64_x86_64-simulator/SVProgressHUDShare.framework/SVProgressHUDShare -------------------------------------------------------------------------------- /fixture/iOS/Static/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 5 | 6 | swift_library( 7 | name = "Static_swift", 8 | module_name = "Static", 9 | srcs = [ 10 | "//Static:Static.swift", 11 | ], 12 | testonly = False, 13 | # deps = None, 14 | # data = None, 15 | defines = None, 16 | visibility = [ 17 | "//visibility:private", 18 | ], 19 | ) 20 | 21 | alias( 22 | name = "Static_library", 23 | actual = "Static_swift", 24 | visibility = [ 25 | "//visibility:public", 26 | ], 27 | ) 28 | 29 | plist_fragment( 30 | name = "plist_default", 31 | extension = "plist", 32 | template = ''' 33 | CFBundleDevelopmentRegion 34 | $(DEVELOPMENT_LANGUAGE) 35 | CFBundleExecutable 36 | $(EXECUTABLE_NAME) 37 | CFBundleIdentifier 38 | $(PRODUCT_BUNDLE_IDENTIFIER) 39 | CFBundleName 40 | $(PRODUCT_NAME) 41 | CFBundlePackageType 42 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 43 | CFBundleShortVersionString 44 | $(MARKETING_VERSION) 45 | CFBundleVersion 46 | $(CURRENT_PROJECT_VERSION) 47 | ''', 48 | visibility = [ 49 | "//visibility:private", 50 | ], 51 | ) 52 | 53 | alias( 54 | name = "Static", 55 | actual = "Static_library", 56 | visibility = [ 57 | "//visibility:public", 58 | ], 59 | ) -------------------------------------------------------------------------------- /fixture/iOS/Static/Static.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Static.swift 3 | // Static 4 | // 5 | // Created by Yume on 2023/1/10. 6 | // 7 | 8 | // MARK: - Static 9 | 10 | public enum Static { 11 | public static func test() -> String { 12 | "Static+Swift" 13 | } 14 | } 15 | 16 | public func test3() -> Int { 17 | 3 18 | } 19 | 20 | -------------------------------------------------------------------------------- /fixture/iOS/Static2/BUILD: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | load("@Plist//build-system/ios-utils:plist_fragment.bzl", "plist_fragment") 4 | load("@rules_cc//cc:defs.bzl", "objc_library") 5 | 6 | objc_library( 7 | name = "Static2_objc", 8 | module_name = "Static2", 9 | srcs = [ 10 | "//Static2:Static2.m", 11 | ], 12 | hdrs = [ 13 | "//Static2:Static2.h", 14 | ], 15 | enable_modules = True, 16 | # pch = None, 17 | copts = [ 18 | "-fblocks", 19 | "-fobjc-arc", 20 | "-fPIC", 21 | "-fmodule-name=Static2", 22 | ], 23 | testonly = False, 24 | # defines = None, 25 | # linkopts = None, 26 | includes = [ 27 | ".", 28 | ], 29 | # deps = None, 30 | visibility = [ 31 | "//visibility:private", 32 | ], 33 | ) 34 | 35 | alias( 36 | name = "Static2_library", 37 | actual = "Static2_objc", 38 | visibility = [ 39 | "//visibility:public", 40 | ], 41 | ) 42 | 43 | plist_fragment( 44 | name = "plist_default", 45 | extension = "plist", 46 | template = ''' 47 | CFBundleDevelopmentRegion 48 | $(DEVELOPMENT_LANGUAGE) 49 | CFBundleExecutable 50 | $(EXECUTABLE_NAME) 51 | CFBundleIdentifier 52 | $(PRODUCT_BUNDLE_IDENTIFIER) 53 | CFBundleName 54 | $(PRODUCT_NAME) 55 | CFBundlePackageType 56 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 57 | CFBundleShortVersionString 58 | $(MARKETING_VERSION) 59 | CFBundleVersion 60 | $(CURRENT_PROJECT_VERSION) 61 | ''', 62 | visibility = [ 63 | "//visibility:private", 64 | ], 65 | ) 66 | 67 | alias( 68 | name = "Static2", 69 | actual = "Static2_library", 70 | visibility = [ 71 | "//visibility:public", 72 | ], 73 | ) -------------------------------------------------------------------------------- /fixture/iOS/Static2/Static2.h: -------------------------------------------------------------------------------- 1 | // 2 | // Static2.h 3 | // Static2 4 | // 5 | // Created by Yume on 2023/2/2. 6 | // 7 | 8 | #import 9 | 10 | @interface Static2 : NSObject 11 | + (NSString*) test; 12 | @end 13 | -------------------------------------------------------------------------------- /fixture/iOS/Static2/Static2.m: -------------------------------------------------------------------------------- 1 | // 2 | // Static2.m 3 | // Static2 4 | // 5 | // Created by Yume on 2023/2/2. 6 | // 7 | 8 | #import "Static2.h" 9 | 10 | @implementation Static2 11 | + (NSString*) test { 12 | return @"Static2+Objc"; 13 | } 14 | @end 15 | -------------------------------------------------------------------------------- /fixture/iOS/config.bazelrc: -------------------------------------------------------------------------------- 1 | # Generated using Bazelize 0.0.4 - https://github.com/XCodeBazelize/Bazelize 2 | 3 | build:Debug --//:mode=Debug 4 | build:Release --//:mode=Release -------------------------------------------------------------------------------- /fixture/iOS/swift_deps.bzl: -------------------------------------------------------------------------------- 1 | load("@cgrindel_swift_bazel//swiftpkg:defs.bzl", "local_swift_package", "swift_package") 2 | 3 | # Contents of swift_deps.bzl 4 | def swift_dependencies(): 5 | local_swift_package( 6 | name = "swiftpkg_local1", 7 | dependencies_index = "@//:swift_deps_index.json", 8 | path = "Local1", 9 | ) 10 | 11 | # version: 0.6.7 12 | swift_package( 13 | name = "swiftpkg_anycodable", 14 | commit = "862808b2070cd908cb04f9aafe7de83d35f81b05", 15 | dependencies_index = "@//:swift_deps_index.json", 16 | remote = "https://github.com/Flight-School/AnyCodable", 17 | ) 18 | 19 | # version: 6.5.0 20 | swift_package( 21 | name = "swiftpkg_rxswift", 22 | commit = "b4307ba0b6425c0ba4178e138799946c3da594f8", 23 | dependencies_index = "@//:swift_deps_index.json", 24 | remote = "https://github.com/ReactiveX/RxSwift", 25 | ) 26 | -------------------------------------------------------------------------------- /git_release.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import sys 3 | import hashlib 4 | 5 | if __name__ == "__main__": 6 | print(sys.argv) 7 | if (len(sys.argv) < 5): 8 | print("please input with user/repo rule_name output_file_path") 9 | exit(1) 10 | 11 | repo = sys.argv[1] 12 | name = sys.argv[2] 13 | path = sys.argv[3] 14 | count = sys.argv[4] 15 | isArchive = sys.argv[5] == 'archive' 16 | 17 | headers = { 18 | 'Accept': 'application/vnd.github+json' 19 | } 20 | # https://docs.github.com/en/rest/releases/releases 21 | url = 'https://api.github.com/repos/{0}/releases?per_page={1}'.format(repo, count) 22 | print(url) 23 | r = requests.get(url, headers = headers) 24 | 25 | if r.status_code != 200: 26 | r.raise_for_status() 27 | exit(1) 28 | 29 | with open(path, 'w') as file: 30 | print( 31 | ''' 32 | extension Repo {{ 33 | /// https://github.com/{1} 34 | enum {0}: String {{'''.format(name, repo), file=file, end='') 35 | 36 | for release in r.json(): 37 | tag = release["tag_name"] 38 | 39 | if "dev" in tag or "alpha" in tag or "beta" in tag: 40 | continue 41 | 42 | _tag_name = tag.replace(".", "_").replace("-", "_") 43 | tag_name = 'v{0}'.format(_tag_name) if _tag_name[:1].isdigit() else _tag_name 44 | print( 45 | ''' 46 | case {0} = "{1}"'''.format(tag_name, tag), file=file, end='') 47 | 48 | print( 49 | ''' 50 | // MARK: Internal 51 | 52 | var version: String { 53 | if rawValue.first == "v" { 54 | return String(rawValue.dropFirst()) 55 | } 56 | return rawValue 57 | } 58 | 59 | var sha256: String { 60 | switch self {''', file=file, end='') 61 | 62 | for release in r.json(): 63 | tag = release["tag_name"] 64 | 65 | if "dev" in tag or "alpha" in tag or "beta" in tag: 66 | continue 67 | _tag_name = tag.replace(".", "_").replace("-", "_") 68 | tag_name = 'v{0}'.format(_tag_name) if _tag_name[:1].isdigit() else _tag_name 69 | 70 | tarURL = '' 71 | if isArchive: 72 | # v0.11.2 73 | tarURL = 'http://github.com/cgrindel/rules_spm/archive/{0}.tar.gz'.format(tag) 74 | else: 75 | tarURL = release.get("assets")[0].get("browser_download_url") 76 | 77 | if not tarURL is None: 78 | print("compute sha256: {0}".format(tarURL)) 79 | tar = requests.get(tarURL) 80 | if tar.status_code != 200: 81 | tar.raise_for_status() 82 | exit(1) 83 | print( 84 | ''' 85 | case .{0}: return "{1}"'''.format(tag_name, hashlib.sha256(tar.content).hexdigest()), file=file, end='') 86 | 87 | print( 88 | ''' 89 | } 90 | } 91 | } 92 | }''', file=file, end='') 93 | --------------------------------------------------------------------------------