Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Code Generation with GYB #205

Merged
merged 14 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/danger-swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ jobs:
danger-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Danger
uses: danger/[email protected]
uses: danger/[email protected]
with:
args: --failOnErrors --no-publish-check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 changes: 10 additions & 4 deletions .github/workflows/swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ name: SwiftLint
on:
pull_request:
types: [ opened, synchronize ]
paths:
- '.github/workflows/swiftlint.yml'
- '.swiftlint.yml'
- '**/*.swift'

jobs:
SwiftLint:
runs-on: macos-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Run SwiftLint
run: swiftlint lint --strict --reporter github-actions-logging
- uses: actions/checkout@v3
- name: GitHub Action for SwiftLint
uses: stanfordbdhg/action-swiftlint@v4
with:
args: --strict --reporter github-actions-logging
11 changes: 8 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ let package = Package(
name: "danger-swift",
url: "https://github.com/danger/swift.git",
from: "3.5.0"
)
),
.package(
url: "https://github.com/SimplyDanny/SwiftLintPlugins")
],
targets: [
.target(
Expand All @@ -46,7 +48,8 @@ let package = Package(
"Yams",
"XcodeProj",
.product(name: "ArgumentParser", package: "swift-argument-parser"),
"Stencil"
"Stencil",
"SwiftLintPlugins"
]
),
.target(
Expand All @@ -57,7 +60,9 @@ let package = Package(
),
.testTarget(
name: "VariantsTests",
dependencies: ["Variants"]
dependencies: [
"Variants"
]
)
]
)
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ This file is responsible for:

## Installation

### Dependencies

In order to generate the code from templates, Variants requires Python 2.7. We recommend configuring the python version using a version management tool such as Pyenv.

For details on how to install and use it check the [Pyenv repo](https://github.com/pyenv/pyenv).

### On Github Actions CI

See [Switching Variants on CI](docs/GITHUB_ACTION.md) for a better understanding and examples.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class AndroidProject: Project {
try gradleFactory.createScript(with: configuration, variant: defaultVariant)
}

// swiftlint:disable function_body_length
// swiftlint:disable:next function_body_length
private func setupFastlane(with configuration: AndroidConfiguration, skip: Bool) {
if skip {
Logger.shared.logInfo("Skipped Fastlane setup", item: "")
Expand Down Expand Up @@ -183,7 +183,6 @@ class AndroidProject: Project {
}
}
}
// swiftlint:enable function_body_length

private func storeFastlaneParams(for variant: AndroidVariant, configuration: AndroidConfiguration) throws {
var customProperties: [CustomProperty] = (variant.custom ?? []) + (configuration.custom ?? [])
Expand Down
7 changes: 3 additions & 4 deletions Sources/VariantsCore/Custom Types/Project/iOSProject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
// Created by Balazs Toth
//

// swiftlint:disable type_name

import Foundation
import ArgumentParser
import PathKit

// swiftlint:disable type_name

class iOSProject: Project {
init(
specHelper: SpecHelper,
Expand Down Expand Up @@ -140,7 +140,7 @@ class iOSProject: Project {
}
}

// swiftlint:disable function_body_length
// swiftlint:disable:next function_body_length
private func setupFastlane(with configuration: iOSConfiguration, skip: Bool) {
if skip {
Logger.shared.logInfo("Skipped Fastlane setup", item: "")
Expand Down Expand Up @@ -225,7 +225,6 @@ class iOSProject: Project {
}
}
}
// swiftlint:enable function_body_length

private func storeFastlaneParams(_ properties: [CustomProperty]) throws {
let fastlaneProperties = properties.filter { $0.destination == .fastlane }
Expand Down
94 changes: 60 additions & 34 deletions Sources/VariantsCore/Factory/iOS/VariantsFileFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class VariantsFileFactory {
"secrets": secrets,
"configurationValues": configurationValues
] as [String: Any]

let environment = Environment(loader: FileSystemLoader(paths: [variantsGybTemplatePath.absolute()]))
let rendered = try environment.renderTemplate(name: StaticPath.Template.variantsSwiftGybFileName,
context: context)
Expand All @@ -53,41 +52,68 @@ class VariantsFileFactory {
}

private func write(_ data: Data, using folder: Path = Path("/tmp/")) throws {
if folder.isDirectory, folder.exists {
let variantsGybFile = try folder.safeJoin(path: Path(StaticPath.Xcode.variantsGybFileName))

// Only proceed to write to file if such doesn't yet exist
// Or does exist and 'isWritable'
guard !variantsGybFile.exists
|| variantsGybFile.isWritable else {
throw TemplateDoesNotExist(templateNames: [folder.string])
}

// Write to file
try variantsGybFile.write(data)

if
try UtilsDirectory().path.exists,
let gybExecutablePath = try? UtilsDirectory().path.safeJoin(path: "gyb"),
let fileContent = try? variantsGybFile.read(),
fileContent == data {

try Bash(gybExecutablePath.absolute().description,
arguments:
"--line-directive",
"",
"-o",
"Variants.swift",
variantsGybFile.absolute().description
).run()

logger.logInfo("⚙️ ", item: """
'\(variantsGybFile.parent().abbreviate().string)/Variants.swift' has been generated with success
""", color: .green)
}
} else {
guard folder.isDirectory, folder.exists else {
throw TemplateDoesNotExist(templateNames: [folder.string])
}

let variantsGybFile = try folder.safeJoin(path: Path(StaticPath.Xcode.variantsGybFileName))
// Only proceed to write to file if such doesn't yet exist
// Or does exist and 'isWritable'
guard !variantsGybFile.exists || variantsGybFile.isWritable else {
throw TemplateDoesNotExist(templateNames: [folder.string])
}

try variantsGybFile.write(data)
guard
try UtilsDirectory().path.exists,
let gybExecutablePath = try? UtilsDirectory().path.safeJoin(path: "gyb"),
let fileContent = try? variantsGybFile.read(),
fileContent == data
else { return }

let gybStdErr = try Bash(gybExecutablePath.absolute().description,
arguments:
"--line-directive",
"",
"-o",
"Variants.swift",
variantsGybFile.absolute().description
).capture(stream: .stderr)
let variantsFilePath = "\(variantsGybFile.parent().abbreviate().string)/Variants.swift"
handleGybErrors(message: gybStdErr, variantsFilePath: variantsFilePath)
logger.logInfo("⚙️ ", item: "'\(variantsFilePath)' has been generated with success", color: .green)
}

private func handleGybErrors(message: String?, variantsFilePath: String) {
guard let message, !message.isEmpty else { return }

switch message {
case _ where message.contains("env: python2.7: No such file or directory"):
logger.logFatal(item:
"""
We're unable to find a 'python2.7' executable.
Install 'python2.7' or ensure it's in your executables path and try running this Variants command again.
Tip:
* Install pyenv (brew install pyenv)
* Install python2.7 (pyenv install python2.7)
* Add "$(pyenv root)/shims" to your PATH
""")
case _ where message.contains("for chunk in chunks(encode(os.environ.get("):
logger.logFatal(item:
"""
We're unable to create 'Variants.Secrets' in '\(variantsFilePath)'.
Ensure that custom config values whose `env: true` are actually environment variables.
""")
case _ where message.contains("pyenv: python2.7: command not found"):
logger.logFatal(item:
"""
Looks like you have pyenv installed but the current configured version is not correct.
Please, select the latest build of python 2.7 as local version.
For example: `pyenv local 2.7`
""")
default:
logger.logFatal(item: message as Any)
}
}

let logger: Logger
Expand Down
30 changes: 22 additions & 8 deletions Sources/VariantsCore/Helpers/Bash.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ struct Bash {
var command: String
var arguments: [String]

enum Stream {
case stdout
case stderr
}

init(_ command: String, arguments: String...) {
self.command = command
self.arguments = arguments
Expand All @@ -20,12 +25,12 @@ struct Bash {
_ = try capture()
}

func capture() throws -> String? {
func capture(stream: Stream = .stdout) throws -> String? {
guard var bashCommand = try execute(command: "/bin/bash", arguments: ["-l", "-c", "which \(command)"]) else {
throw RuntimeError("\(command) not found")
}
bashCommand = bashCommand.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)
if let output = try execute(command: bashCommand, arguments: arguments) {
if let output = try execute(command: bashCommand, arguments: arguments, stream: stream) {
// `dropLast()` is required as the output always contains a new line (`\n`) at the end.
return String(output.dropLast())
}
Expand All @@ -34,11 +39,13 @@ struct Bash {

// MARK: - Private

private func execute(command: String, arguments: [String] = []) throws -> String? {
private func execute(command: String, arguments: [String] = [], stream: Stream = .stdout) throws -> String? {
let process = Process()
let pipe = Pipe()
let stdoutPipe = Pipe()
let stderrPipe = Pipe()
GMinucci marked this conversation as resolved.
Show resolved Hide resolved
process.arguments = arguments
process.standardOutput = pipe
process.standardOutput = stdoutPipe
process.standardError = stderrPipe

if #available(OSX 10.13, *) {
process.executableURL = URL(fileURLWithPath: command)
Expand All @@ -48,8 +55,15 @@ struct Bash {
process.launch()
}

let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
return output
switch stream {
case .stdout:
let stdoutData = stdoutPipe.fileHandleForReading.readDataToEndOfFile()
let stdout = String(data: stdoutData, encoding: .utf8)
return stdout
case .stderr:
let stderrData = stderrPipe.fileHandleForReading.readDataToEndOfFile()
let stderr = String(data: stderrData, encoding: .utf8)
return stderr
}
}
}
4 changes: 2 additions & 2 deletions Sources/VariantsCore/Helpers/SpecHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
// Created by Arthur Alves
//

// swiftlint:disable type_name

import Foundation
import PathKit

// swiftlint:disable type_name

enum iOSProjectKey: String, CaseIterable {
case project = "PROJECT"
case target = "TARGET"
Expand Down
4 changes: 2 additions & 2 deletions Sources/VariantsCore/Schemas/iOS/iOSConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
// Created by Arthur Alves
//

import Foundation

// swiftlint:disable type_name

import Foundation

internal extension CodingUserInfoKey {
static let bundleID = CodingUserInfoKey(rawValue: "bundle_id")!
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/VariantsCore/Schemas/iOS/iOSSigning.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
// Created by Arthur Alves
//

import Foundation

// swiftlint:disable type_name

import Foundation

struct iOSSigning: Codable {
let teamName: String?
let teamID: String?
Expand Down
4 changes: 2 additions & 2 deletions Sources/VariantsCore/Schemas/iOS/iOSTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
// Created by Arthur Alves
//

import Foundation

// swiftlint:disable type_name

import Foundation

public typealias NamedTarget = (key: String, value: iOSTarget)

public struct iOSTarget: Codable {
Expand Down
4 changes: 2 additions & 2 deletions Sources/VariantsCore/Schemas/iOS/iOSVariant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
// Created by Arthur Alves
//

import Foundation

// swiftlint:disable type_name

import Foundation

public struct iOSVariant: Variant {
let name: String
let versionName: String
Expand Down
Loading
Loading