diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..236415237 --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +%: + ./make.sh $@ +.PHONY: % \ No newline at end of file diff --git a/Package.resolved b/Package.resolved index 471804826..109daf1de 100644 --- a/Package.resolved +++ b/Package.resolved @@ -75,11 +75,11 @@ }, { "package": "Sourcery", - "repositoryURL": "https://github.com/krzysztofzablocki/Sourcery.git", + "repositoryURL": "https://github.com/avito-tech/Sourcery.git", "state": { "branch": null, - "revision": "0c6dc860b1e7afc2e025cb63f66ab5dfd69bb743", - "version": "1.0.0" + "revision": "10a8955f07a1dfeb9c9ad40b97fe8f95ff14dc29", + "version": null } }, { diff --git a/Package.swift b/Package.swift index f81946a2a..423faee72 100644 --- a/Package.swift +++ b/Package.swift @@ -1,5 +1,7 @@ // swift-tools-version:5.2 +// swiftlint:disable all + import PackageDescription let package = Package( @@ -22,24 +24,27 @@ let package = Package( dependencies: [ .package(url: "https://github.com/jpsim/SourceKitten.git", .exact("0.23.1")), .package(url: "https://github.com/kylef/PathKit.git", .branch("master")), - .package(url: "https://github.com/krzysztofzablocki/Sourcery.git", .exact("1.0.0")) + .package(url: "https://github.com/avito-tech/Sourcery.git", .revision("10a8955f07a1dfeb9c9ad40b97fe8f95ff14dc29")), ], targets: [ .target( + // MARK: MixboxMocksGeneration name: "MixboxMocksGeneration", dependencies: [ "PathKit", .product(name: "SourceryFramework", package: "Sourcery"), - .product(name: "SourceryRuntime", package: "Sourcery") + .product(name: "SourceryRuntime", package: "Sourcery"), ], - path: "Frameworks/MocksGeneration" + path: "Frameworks/MocksGeneration/Sources" ), .target( + // MARK: MixboxMocksGenerator name: "MixboxMocksGenerator", dependencies: [ - "MixboxMocksGeneration" + "MixboxMocksGeneration", + "PathKit", ], - path: "MocksGenerator" - ) + path: "MocksGenerator/Sources" + ), ] ) diff --git a/Package.template.swift b/Package.template.swift new file mode 100644 index 000000000..e922f7b98 --- /dev/null +++ b/Package.template.swift @@ -0,0 +1,32 @@ +// swift-tools-version:5.2 + +// swiftlint:disable all + +import PackageDescription + +let package = Package( + name: "Mixbox", + platforms: [.macOS(.v10_15)], + products: [ + .library( + name: "MixboxMocksGeneration", + targets: [ + "MixboxMocksGeneration" + ] + ), + .executable( + name: "MixboxMocksGenerator", + targets: [ + "MixboxMocksGenerator" + ] + ) + ], + dependencies: [ + .package(url: "https://github.com/jpsim/SourceKitten.git", .exact("0.23.1")), + .package(url: "https://github.com/kylef/PathKit.git", .branch("master")), + <__SOURCERY_PACKAGE__> + ], + targets: [ +<__TARGETS__> + ] +) diff --git a/PackageGenerator.swift b/PackageGenerator.swift new file mode 100644 index 000000000..6ff360bcf --- /dev/null +++ b/PackageGenerator.swift @@ -0,0 +1,258 @@ +// swiftlint:disable all + +import Foundation + +let knownImportsToIgnore = [ + "Foundation", + "XCTest", + "CryptoKit", + "Dispatch", +] + +// .product(name: "ArgumentParser", package: "swift-argument-parser") +let explicitlyIdentifiedPackages = [ + "SourceKittenFramework": "SourceKitten", + "SourceryFramework": "Sourcery", + "SourceryRuntime": "Sourcery" +] + +let importStatementExpression = try NSRegularExpression( + pattern: "^(@testable )?import ([a-zA-Z0-9_]+)$", + options: [.anchorsMatchLines] +) + +let moduleDescriptions: [ModuleDescription] = [ + try generate( + moduleName: "MixboxMocksGeneration", + path: "Frameworks/MocksGeneration/Sources", + isTestTarget: false + ), + try generate( + moduleName: "MixboxMocksGenerator", + path: "MocksGenerator/Sources", + isTestTarget: false + ) +] + +func main() throws { + var generatedTargetStatements = [String]() + let sortedModuleDescriptions: [ModuleDescription] = moduleDescriptions.sorted { $0.name < $1.name } + + for moduleDescription in sortedModuleDescriptions { + generatedTargetStatements.append(".\(!moduleDescription.isTest ? "target" : "testTarget")(") + generatedTargetStatements.append(" // MARK: \(moduleDescription.name)") + generatedTargetStatements.append(" name: " + "\"\(moduleDescription.name)\"" + ",") + generatedTargetStatements.append(" dependencies: [") + for dependency in moduleDescription.deps { + if explicitlyIdentifiedPackages.keys.contains(dependency) { + let package = explicitlyIdentifiedPackages[dependency]! + generatedTargetStatements.append(" .product(name: \"\(dependency)\", package: \"\(package)\"),") + } else { + generatedTargetStatements.append(" \"\(dependency)\",") + } + } + generatedTargetStatements.append(" ],") + generatedTargetStatements.append(" path: " + "\"" + moduleDescription.path + "\"") + generatedTargetStatements.append("),") + } + + try generatePackageSwift(replacementForTargets: generatedTargetStatements) +} + +func generate(moduleName: String, path: String, isTestTarget: Bool) throws -> ModuleDescription { + let moduleFolderUrl = repoRoot().appendingPathComponent(path) + + guard directoryExists(url: moduleFolderUrl) else { + throw ErrorString("Directory doesn't exist at \(moduleFolderUrl)") + } + + let moduleEnumerator = FileManager().enumerator( + at: moduleFolderUrl, + includingPropertiesForKeys: [.isRegularFileKey], + options: [.skipsHiddenFiles] + ) + + log("Analyzing \(moduleName) at \(moduleFolderUrl)") + + var importedModuleNames = Set() + + while let moduleFile = moduleEnumerator?.nextObject() as? URL { + if moduleFile.pathExtension != "swift" { + log(" Skipping \(moduleFile.lastPathComponent): is not Swift file") + continue + } + + log(" Analyzing \(moduleFile.lastPathComponent)") + + guard try moduleFile.resourceValues(forKeys: [.isRegularFileKey]).isRegularFile == true else { + log(" Skipping \(moduleFile.lastPathComponent): is not regular file") + continue + } + + let fileContents = try String(contentsOf: moduleFile) + .split(separator: "\n") + .filter { !$0.starts(with: "//") } + + for line in fileContents { + let matches = importStatementExpression.matches(in: String(line), options: [], range: NSMakeRange(0, line.count)) + + guard matches.count == 1 else { + continue + } + + let importedModuleName = (line as NSString).substring(with: matches[0].range(at: 2)) + importedModuleNames.insert(importedModuleName) + } + } + + importedModuleNames.remove(moduleName) + + let dependencies = importedModuleNames.filter { !knownImportsToIgnore.contains($0) }.sorted() + + return ModuleDescription( + name: moduleName, + deps: dependencies, + path: String(path), + isTest: isTestTarget + ) +} + +func generatePackageSwift(replacementForTargets: [String]) throws { + log("Loading template") + var templateContents = try String(contentsOf: URL(fileURLWithPath: "Package.template.swift")) + + templateContents = templateContents.replacingOccurrences( + of: "<__TARGETS__>", + with: replacementForTargets.map { " \($0)" }.joined(separator: "\n") + ) + + templateContents = templateContents.replacingOccurrences( + of: "<__SOURCERY_PACKAGE__>", + with: sourceryPackage() + ) + + if ProcessInfo.processInfo.environment["MIXBOX_CI_IS_CI_BUILD"] != nil { + log("Checking for Package.swift consistency") + let existingContents = try String(contentsOf: URL(fileURLWithPath: "Package.swift")) + if existingContents != templateContents { + print("\(#file):\(#line): MIXBOX_CI_IS_CI_BUILD is set, and Package.swift differs. Please update and commit Package.swift!") + exit(1) + } + } + + log("Saving Package.swift") + try templateContents.write(to: URL(fileURLWithPath: "Package.swift"), atomically: true, encoding: .utf8) +} + +// MARK: - Development dependencies support: Sourcery + +func sourceryPackage() -> String { + do { + if ProcessInfo.processInfo.environment["SYNC_WITH_DEV_PODS"] != "true" { + throw ErrorString("Development pods are disabled") + } + + return """ + .package(name: "Sourcery", path: "\(try sourceryDevelopmentPath())") + """ + } catch { + return """ + .package(url: "https://github.com/avito-tech/Sourcery.git", .revision("10a8955f07a1dfeb9c9ad40b97fe8f95ff14dc29")), + """ + } +} + +func sourceryDevelopmentPath() throws -> String { + return try developmentPodPath( + podName: "Sourcery", + podfileLockContents: mixboxPodfileLockContents() + ) +} + +func repoRoot() -> URL { + return URL(fileURLWithPath: #file, isDirectory: false) + .deletingLastPathComponent() +} + +func mixboxPodfileLockContents() throws -> String { + + let podfileLockPath = repoRoot() + .appendingPathComponent("Tests") + .appendingPathComponent("Podfile.lock") + + return try String(contentsOf: podfileLockPath) +} + +// MARK: - Development dependencies support: Shared + +func developmentPodPath(podName: String, podfileLockContents: String) throws -> String { + return fixPathForSpm( + path: try singleMatch( + regex: "\(podName) \\(from `(.*?)`\\)", + string: podfileLockContents, + groupIndex: 1 + ) + ) +} + +// Without slash SPM fails with this error: +// error: the Package.resolved file is most likely severely out-of-date and is preventing correct resolution; delete the resolved file and try again +func fixPathForSpm(path: String) -> String { + if path.hasSuffix("/") { + return path + } else { + return "\(path)/" + } +} + +func singleMatch(regex: String, string: String, groupIndex: Int) throws -> String { + let regex = try NSRegularExpression(pattern: regex) + let results = regex.matches( + in: string, + range: NSRange(string.startIndex..., in: string) + ) + + guard let first = results.first, results.count == 1 else { + throw ErrorString("Expected exactly one match") + } + + guard let range = Range(first.range(at: groupIndex), in: string) else { + throw ErrorString("Failed to get range from match") + } + + return String(string[range]) +} + +// MARK: - Models + +struct ErrorString: Error, CustomStringConvertible { + let description: String + + init(_ description: String) { + self.description = description + } +} + +struct ModuleDescription { + let name: String + let deps: [String] + let path: String + let isTest: Bool +} + +// MARK: - Utility + +func log(_ text: String) { + if ProcessInfo.processInfo.environment["DEBUG"] != nil { + print(text) + } +} + +func directoryExists(url: URL) -> Bool { + var isDirectory = ObjCBool(false) + return FileManager().fileExists(atPath: url.path, isDirectory: &isDirectory) && isDirectory.boolValue +} + +// MARK: - Main + +try main() \ No newline at end of file diff --git a/Tests/Podfile b/Tests/Podfile index 732b5e005..e875fe148 100644 --- a/Tests/Podfile +++ b/Tests/Podfile @@ -27,7 +27,7 @@ sourcery = Devpods::Repo.new( pod name, local_hash } ) -sourcery.branch_value = 'master' +sourcery.branch_value = 'avito' sourcery.local_path_env = 'MIXBOX_SOURCERY_LOCAL_PATH' def tests_ipc_pods diff --git a/Tests/Podfile.lock b/Tests/Podfile.lock index bdfc4b556..2f2b755b1 100644 --- a/Tests/Podfile.lock +++ b/Tests/Podfile.lock @@ -124,10 +124,10 @@ DEPENDENCIES: - MixboxUiTestsFoundation (from `..`) - SBTUITestTunnel/Client (= 3.0.6) - SBTUITestTunnel/Server (= 3.0.6) - - Sourcery (from `https://github.com/avito-tech/Sourcery.git`, branch `master`) - - SourceryFramework (from `https://github.com/avito-tech/Sourcery.git`, branch `master`) - - SourceryRuntime (from `https://github.com/avito-tech/Sourcery.git`, branch `master`) - - SourceryUtils (from `https://github.com/avito-tech/Sourcery.git`, branch `master`) + - Sourcery (from `https://github.com/avito-tech/Sourcery.git`, branch `avito`) + - SourceryFramework (from `https://github.com/avito-tech/Sourcery.git`, branch `avito`) + - SourceryRuntime (from `https://github.com/avito-tech/Sourcery.git`, branch `avito`) + - SourceryUtils (from `https://github.com/avito-tech/Sourcery.git`, branch `avito`) - SwiftLint (= 0.36.0) - TestsIpc (from `Frameworks/TestsIpc`) @@ -191,32 +191,32 @@ EXTERNAL SOURCES: MixboxUiTestsFoundation: :path: ".." Sourcery: - :branch: master + :branch: avito :git: https://github.com/avito-tech/Sourcery.git SourceryFramework: - :branch: master + :branch: avito :git: https://github.com/avito-tech/Sourcery.git SourceryRuntime: - :branch: master + :branch: avito :git: https://github.com/avito-tech/Sourcery.git SourceryUtils: - :branch: master + :branch: avito :git: https://github.com/avito-tech/Sourcery.git TestsIpc: :path: "Frameworks/TestsIpc" CHECKOUT OPTIONS: Sourcery: - :commit: ab9e4258fd5c534e5edb82ab18a79c69f1b412f4 + :commit: b968aea6d9a9b5f140e90b0583a85346fc70f795 :git: https://github.com/avito-tech/Sourcery.git SourceryFramework: - :commit: ab9e4258fd5c534e5edb82ab18a79c69f1b412f4 + :commit: b968aea6d9a9b5f140e90b0583a85346fc70f795 :git: https://github.com/avito-tech/Sourcery.git SourceryRuntime: - :commit: ab9e4258fd5c534e5edb82ab18a79c69f1b412f4 + :commit: b968aea6d9a9b5f140e90b0583a85346fc70f795 :git: https://github.com/avito-tech/Sourcery.git SourceryUtils: - :commit: ab9e4258fd5c534e5edb82ab18a79c69f1b412f4 + :commit: b968aea6d9a9b5f140e90b0583a85346fc70f795 :git: https://github.com/avito-tech/Sourcery.git SPEC CHECKSUMS: diff --git a/Tests/UnitTests/Tests/MixboxGenerator/Integration/Protocols/MixboxGeneratorIntegrationTestsFixtureProtocol.swift b/Tests/UnitTests/Tests/MixboxGenerator/Integration/Protocols/MixboxGeneratorIntegrationTestsFixtureProtocol.swift index f8464d94d..df8a3aff3 100644 --- a/Tests/UnitTests/Tests/MixboxGenerator/Integration/Protocols/MixboxGeneratorIntegrationTestsFixtureProtocol.swift +++ b/Tests/UnitTests/Tests/MixboxGenerator/Integration/Protocols/MixboxGeneratorIntegrationTestsFixtureProtocol.swift @@ -15,6 +15,7 @@ protocol MixboxGeneratorIntegrationTestsFixtureProtocol: func function(argument0: Int, argument1: Int) // Labels + func functionWithNeitherLabelNorArgumentName(_: Int) func function(_ noLabel: Int) func function(label: Int) diff --git a/ci/bash/bash_ci.sh b/ci/bash/bash_ci.sh index 0487c221b..22ab38ee9 100644 --- a/ci/bash/bash_ci.sh +++ b/ci/bash/bash_ci.sh @@ -15,3 +15,5 @@ PYTHON_ROOT="$REPO_ROOT" source "$REPO_ROOT"/ci/bash/include/python.sh source "$REPO_ROOT"/ci/bash/include/error_handling.sh +source "$REPO_ROOT"/ci/bash/include/swift_package_manager.sh +source "$REPO_ROOT"/ci/bash/include/bash_utils.sh diff --git a/ci/bash/include/bash_utils.sh b/ci/bash/include/bash_utils.sh new file mode 100644 index 000000000..b7ed94ede --- /dev/null +++ b/ci/bash/include/bash_utils.sh @@ -0,0 +1,22 @@ +# Example: +# +# ``` +# local old_options=$(bash_save_options) +# set +u +# +# do_something +# +# bash_restore_options "$old_options" +# ``` +# +# Credits: https://unix.stackexchange.com/questions/310957/how-to-restore-the-value-of-shell-options-like-set-x/310963 +# +bash_save_options() { + echo "$(set +o); set -$-" # POSIXly store all set options. +} + +bash_restore_options() { + local oldstate=$1 + + set -vx; eval "$oldstate" # restore all options stored. +} diff --git a/ci/bash/include/python.sh b/ci/bash/include/python.sh index d21bec58c..7d10835f9 100644 --- a/ci/bash/include/python.sh +++ b/ci/bash/include/python.sh @@ -13,8 +13,9 @@ bash_ci_require_pyenv() { return 0 fi - __install_command_line_tools_if_needed - __install_mac_os_sdk_headers_if_needed + # Seems to be not working: + # __install_command_line_tools_if_needed + # __install_mac_os_sdk_headers_if_needed which pyenv || brew install pyenv which pyenv-virtualenv || brew install pyenv-virtualenv @@ -28,12 +29,24 @@ bash_ci_require_pyenv() { # After those commands pip3/python3/pytest will refer to those in virtualenv eval "$(pyenv init -)" - eval "$(pyenv virtualenv-init -)" + __safely_eval_virtualenv_init pyenv local "$pyenv_name" __PYENV_IS_ALREADY_SET_UP=true } +__safely_eval_virtualenv_init() { + # Fixes this error: `line 42: PROMPT_COMMAND: unbound variable`, it's in virtualenv's code + + local old_options=$(bash_save_options) + + set +u + + eval "$(pyenv virtualenv-init -)" + + bash_restore_options "$old_options" +} + # Installs requirements.txt bash_ci_require_python_packages() { __assert_pyenv_is_set_up @@ -59,8 +72,11 @@ bash_ci_run_python3() { # PRIVATE +# `--no-cache` was added to work around https://github.com/pypa/pip/issues/6240 +# Note: `-vvv` option is useful for debugging. __bash_ci_pip3_install() { pip3 install \ + --no-cache \ -i "https://pypi.org/simple" \ "$@" } diff --git a/ci/swift/make b/ci/bash/include/swift_package_manager.sh old mode 100755 new mode 100644 similarity index 53% rename from ci/swift/make rename to ci/bash/include/swift_package_manager.sh index 82c49acc4..ec5c58263 --- a/ci/swift/make +++ b/ci/bash/include/swift_package_manager.sh @@ -1,70 +1,10 @@ -#!/bin/bash - -set -x - -# ====== bash_ci ====== -# This section should be same across all bash files in the project -source "$(builtin cd "$(dirname "$0")" && git rev-parse --show-toplevel)/ci/bash/bash_ci.sh" -# ===================== - -main() { - local action=$1 - - cd "$SCRIPT_ROOT" - - __MIXBOX_CI_MACOS_DEPLOYMENT_TARGET=x86_64-apple-macosx10.14 - __MIXBOX_CI_OPTIMIZE_SPEED=${__MIXBOX_CI_OPTIMIZE_SPEED:-false} - - case "$action" in - generate) generate_project;; - r) __MIXBOX_CI_OPTIMIZE_SPEED=true; reopen_project;; # `r` is for rapid people - reopen) reopen_project $2;; - clean) clean_project;; - build) build_project $2;; - test) test_project;; - *) __fatal_error "Unknown action: $action. Known actions: generate, reopen, reopen-fast, clean, build (TravisLogicTestsBuild), test";; - esac -} - -# Actions - -generate_project() { - generate_package - - swift package generate-xcodeproj --xcconfig-overrides Package.xcconfig --enable-code-coverage - - local xcodeproj_relative=`ls -1|grep ".xcodeproj"` - local pbxproj_absolute=$SCRIPT_ROOT/$xcodeproj_relative/project.pbxproj - - patch_macosx_deployment_target "$pbxproj_absolute" -} - -# Prevents the following error: -# `Compiling for macOS 10.13, but module 'AtomicModels' has a minimum deployment target of macOS 10.14: /some/path/AtomicModels.framework/Modules/AtomicModels.swiftmodule/x86_64-apple-macos.swiftmodule` -# TODO: Fix SPM in Emcee? -patch_macosx_deployment_target() { - local pbxproj_absolute=$1 - local temporary_file=/tmp/`uuidgen` - - cat "$pbxproj_absolute" \ - | perl -pe 's/MACOSX_DEPLOYMENT_TARGET = "10.13"/MACOSX_DEPLOYMENT_TARGET = "10.14"/' \ - > "$temporary_file" - - rm "$pbxproj_absolute" - mv "$temporary_file" "$pbxproj_absolute" -} - -reopen_project() { +spm_reopen_project() { local xcode_app_name=`xcode-select -p|grep -oE "([^/]+.app)"|sed 's/\.app//'` local xcodeproj_relative=`ls -1|grep ".xcodeproj"` local xcodeproj_absolute=$SCRIPT_ROOT/$xcodeproj_relative - local option=$2 - - # Very useful for local developement - if [ "$option" == fast ] - then - __MIXBOX_CI_OPTIMIZE_SPEED=true - fi + + # To avoid "The file “project.xcworkspace” has been modified by another application." nonsense after reopening Xcode + rm -rfv "$xcodeproj_absolute"/project.xcworkspace || __ignore_error osascript -e ' tell application "'$xcode_app_name'" @@ -73,10 +13,25 @@ reopen_project() { end tell end tell' || __ignore_error - if ! generate_project + if ! spm_generate_xcodeproj then - open "Package.swift" - __fatal_error "Failed to generate project" + echo -e "\033[1;31m" # red color + echo '/!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\' + echo + echo "Failed to generate project!" + echo + echo "Press:" + echo " - [Enter] to open Package.template.swift and PackageGenerator.swift" + echo " - [Ctrl]+[C] to cancel" + echo + echo '/!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\' + echo -e "\033[0m" + + read + + open "Package.template.swift" "PackageGenerator.swift" + + exit 1 fi echo "Ignore the following \"missing value\" log:" @@ -85,27 +40,49 @@ reopen_project() { open "'$xcodeproj_absolute'" end tell' - echo "Quote from Apple:" + echo "Quote from Apple about this \"missing value\" log:" echo "> KNOWN ISSUE: The open command in Xcode sometimes fails to return the opened document." echo "> It is recommended to ignore the result of the open command and instead find the opened" echo "> document in the application's documents." } -clean_project() { +spm_generate_xcodeproj() { + local swift_arguments=(package generate-xcodeproj --enable-code-coverage) + local xcconfig_path=Package.xcconfig + + [ -e "$xcconfig_path" ] && swift_arguments=("${swift_arguments[@]}" --xcconfig-overrides "$xcconfig_path") + + spm_generate_package \ + && swift package generate-xcodeproj --enable-code-coverage \ + && spm_patch_macosx_deployment_target +} + +# Prevents the following error: +# `Compiling for macOS 10.13, but module 'AtomicModels' has a minimum deployment target of macOS 10.14: /some/path/AtomicModels.framework/Modules/AtomicModels.swiftmodule/x86_64-apple-macos.swiftmodule` +# TODO: Fix SPM in Emcee? +spm_patch_macosx_deployment_target() { + local xcodeproj_relative=`ls -1|grep ".xcodeproj"` + local pbxproj_absolute=$SCRIPT_ROOT/$xcodeproj_relative/project.pbxproj + local temporary_file=/tmp/`uuidgen` + + cat "$pbxproj_absolute" \ + | perl -pe 's/MACOSX_DEPLOYMENT_TARGET = "10.13"/MACOSX_DEPLOYMENT_TARGET = "10.14"/' \ + > "$temporary_file" + + rm "$pbxproj_absolute" + mv "$temporary_file" "$pbxproj_absolute" +} + +spm_clean_project() { swift package clean swift package reset rm -rf .build rm -rf *.xcodeproj } -build_project() { +spm_build_project() { local product=$1 - if [ "$__MIXBOX_CI_OPTIMIZE_SPEED" != "true" ] - then - clean_project - fi - args=( \ swift build \ -c release \ @@ -124,33 +101,25 @@ build_project() { "${args[@]}" } -test_project() { - if [ "$__MIXBOX_CI_OPTIMIZE_SPEED" != "true" ] - then - clean_project - fi - +spm_test_project() { swift test \ -Xswiftc -target \ -Xswiftc "$__MIXBOX_CI_MACOS_DEPLOYMENT_TARGET" } -# Support - -generate_package() { - if [ "$__MIXBOX_CI_OPTIMIZE_SPEED" != "true" ] - then - bash_ci_require_pyenv make_v1 - bash_ci_require_python_packages ./MakePackage/requirements.txt - bash_ci_run_python3 ./MakePackage/make_package.py || exit 1 - else - bash_ci_run_python3 ./MakePackage/make_package.py || handle_failure_of_calling_make_package_while_not_using_pyenv || exit 1 - fi -} +spm_make_file_main() { + local action=$1 + + __MIXBOX_CI_MACOS_DEPLOYMENT_TARGET=x86_64-apple-macosx10.14 + + cd "$SCRIPT_ROOT" -handle_failure_of_calling_make_package_while_not_using_pyenv() { - pip3 install -r ./MakePackage/requirements.txt - bash_ci_run_python3 ./MakePackage/make_package.py + case "$action" in + generate) spm_generate_xcodeproj;; + reopen) spm_reopen_project;; + clean) spm_clean_project;; + build) spm_build_project "${2:-}";; + test) spm_test_project;; + *) __fatal_error "Unknown action: $action. Known actions: generate, reopen, reopen-fast, clean, build , test";; + esac } - -main "$@" diff --git a/ci/swift/Makefile b/ci/swift/Makefile index cd92efeea..236415237 100644 --- a/ci/swift/Makefile +++ b/ci/swift/Makefile @@ -1,6 +1,3 @@ -# Writing scripts in Makefile is tedious, -# however, Makefile is kept here due to convenience: -# `make build`, `make clean`, etc %: - ./make $@ + ./make.sh $@ .PHONY: % \ No newline at end of file diff --git a/ci/swift/make.sh b/ci/swift/make.sh new file mode 100755 index 000000000..eb2f11afe --- /dev/null +++ b/ci/swift/make.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -xueo pipefail + +# ====== bash_ci ====== +# This section should be same across all bash files in the project +source "$(builtin cd "$(dirname "$0")" && git rev-parse --show-toplevel)/ci/bash/bash_ci.sh" +# ===================== + +# Overrides + +spm_generate_package() { + bash_ci_require_pyenv make_v1 + bash_ci_require_python_packages ./MakePackage/requirements.txt + bash_ci_run_python3 ./MakePackage/make_package.py || exit +} + +# Main + +spm_make_file_main "$@" diff --git a/ci/swift/run_swift b/ci/swift/run_swift index 9923c37bb..cc3235ee9 100755 --- a/ci/swift/run_swift +++ b/ci/swift/run_swift @@ -68,7 +68,7 @@ build() { # Also this: # /xxx/yyy/DeveloperDirLocator.swift:2:8: error: no such module 'Models' # The latter is maybe due to some SPM cache problems that can be solved (TODO: solve) - if ./make build "${build_options[@]}" + if ./make.sh build "${build_options[@]}" then echo "Build was successful" lastExitCode=0 diff --git a/make.sh b/make.sh new file mode 100755 index 000000000..7fefffd54 --- /dev/null +++ b/make.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -ueo pipefail + +# ====== bash_ci ====== +# This section should be same across all bash files in the project +source "$(builtin cd "$(dirname "$0")" && git rev-parse --show-toplevel)/ci/bash/bash_ci.sh" +# ===================== + +# Overrides + +spm_generate_package() { + local return_value=0 + + cd "$REPO_ROOT" + + swift "PackageGenerator.swift" || return_value=1 + + cd - + + return $return_value +} + +# Main + +spm_make_file_main "$@"