mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Swiftformat on githooks + New swift run tools setup
command (#563)
This commit is contained in:
parent
f0a4cfd946
commit
c8fb93e00d
8
.githooks/post-checkout
Executable file
8
.githooks/post-checkout
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting '.git/hooks/post-checkout'.\n"; exit 2; }
|
||||
git lfs post-checkout "$@"
|
||||
|
||||
#!/bin/bash
|
||||
export PATH="$PATH:/opt/homebrew/bin"
|
||||
|
||||
xcodegen
|
3
.githooks/post-commit
Executable file
3
.githooks/post-commit
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting '.git/hooks/post-commit'.\n"; exit 2; }
|
||||
git lfs post-commit "$@"
|
3
.githooks/post-merge
Executable file
3
.githooks/post-merge
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting '.git/hooks/post-merge'.\n"; exit 2; }
|
||||
git lfs post-merge "$@"
|
10
.githooks/pre-commit
Executable file
10
.githooks/pre-commit
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
export PATH="$PATH:/opt/homebrew/bin"
|
||||
|
||||
if ! swiftformat --lint . > /dev/null 2>&1
|
||||
then
|
||||
echo "pre-commit: Commit aborted due to SwiftFormat warnings. Please check the automatically generated fixes and try again"
|
||||
swiftformat . > /dev/null 2>&1
|
||||
exit 1
|
||||
fi
|
3
.githooks/pre-push
Executable file
3
.githooks/pre-push
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting '.git/hooks/pre-push'.\n"; exit 2; }
|
||||
git lfs pre-push "$@"
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -35,6 +35,9 @@ build
|
||||
Tools/Scripts/element-android
|
||||
/vendor/
|
||||
|
||||
## brew
|
||||
Brewfile.lock.json
|
||||
|
||||
## macOS Files
|
||||
.DS_Store
|
||||
._*
|
||||
|
@ -6,11 +6,24 @@ Element iOS support can be found in this room: [ installed on your mac, and run after the checkout:
|
||||
|
||||
```
|
||||
swift run tools setup-project
|
||||
```
|
||||
|
||||
This will:
|
||||
- Install various brew dependencies required for the project (like xcodegen).
|
||||
- Set up git to use the shared githooks from the repo, instead of the default ones.
|
||||
- Automatically run xcodegen for the first time.
|
||||
|
||||
### Xcode
|
||||
|
||||
We suggest using an Xcode version later than 13.2.1.
|
||||
|
||||
The Xcode project can be directly compiled after checkout through the shared ElementX scheme which includes the main application as well as the unit and UI tests.
|
||||
The Xcode project can be directly compiled through the shared ElementX scheme which includes the main application as well as the unit and UI tests.
|
||||
|
||||
The Xcode project itself is generated through [xcodegen](https://github.com/yonaskolb/XcodeGen) so any changes shouldn't be made directly to it but to the configuration files.
|
||||
|
||||
@ -38,12 +51,20 @@ The project depends on some tools for the build process. These are all included
|
||||
brew bundle
|
||||
```
|
||||
|
||||
Git LFS is used to store UI test snapshots. After cloning the repo this can be configured by running
|
||||
Git LFS is used to store UI test snapshots. `swift run tools setup-project` will already install it, however it can also be installed after a checkout by running:
|
||||
|
||||
```
|
||||
git lfs install
|
||||
```
|
||||
|
||||
### Githooks
|
||||
|
||||
The project uses its own shared githooks stored in the .githooks folder, you will need to configure git to use such folder, this is already done if you have run the setup tool with `swift run tools setup-project` otherwise you would need to run:
|
||||
|
||||
```
|
||||
git config core.hooksPath .githooks
|
||||
```
|
||||
|
||||
### Continuous Integration
|
||||
|
||||
ElementX uses Fastlane for running actions on the CI and tries to keep the configuration confined to either [fastlane](fastlane/Fastfile) or [xcodegen](project.yml).
|
||||
|
@ -11,12 +11,10 @@ struct BuildSDK: ParsableCommand {
|
||||
@Option(help: "The target to build for such as aarch64-apple-ios. Omit this option to build for all targets.")
|
||||
var target: String?
|
||||
|
||||
private var projectDirectoryURL: URL { URL(filePath: FileManager.default.currentDirectoryPath) }
|
||||
private var parentDirectoryURL: URL { projectDirectoryURL.deletingLastPathComponent() }
|
||||
private var parentDirectoryURL: URL { Utilities.projectDirectoryURL.deletingLastPathComponent() }
|
||||
private var sdkDirectoryURL: URL { parentDirectoryURL.appending(path: "matrix-rust-sdk") }
|
||||
|
||||
enum Error: LocalizedError {
|
||||
case scriptFailed
|
||||
case rustupOutputFailure
|
||||
case missingRustTargets([String])
|
||||
case failureParsingProjectYAML
|
||||
@ -49,7 +47,7 @@ struct BuildSDK: ParsableCommand {
|
||||
/// but only when the ``target`` option hasn't been supplied.
|
||||
func checkRustupTargets() throws {
|
||||
guard target == nil else { return }
|
||||
guard let output = try zsh("rustup show", workingDirectoryURL: projectDirectoryURL) else { throw Error.rustupOutputFailure }
|
||||
guard let output = try Utilities.zsh("rustup show") else { throw Error.rustupOutputFailure }
|
||||
|
||||
var requiredTargets = [
|
||||
"aarch64-apple-darwin": false,
|
||||
@ -71,13 +69,13 @@ struct BuildSDK: ParsableCommand {
|
||||
/// Clones the Rust SDK if a copy isn't found in the parent directory.
|
||||
func cloneSDKIfNeeded() throws {
|
||||
guard !FileManager.default.fileExists(atPath: sdkDirectoryURL.path) else { return }
|
||||
try zsh("git clone https://github.com/matrix-org/matrix-rust-sdk", workingDirectoryURL: parentDirectoryURL)
|
||||
try Utilities.zsh("git clone https://github.com/matrix-org/matrix-rust-sdk", workingDirectoryURL: parentDirectoryURL)
|
||||
}
|
||||
|
||||
/// Checkout the specified branch of the SDK if supplied.
|
||||
func checkoutBranchIfSupplied() throws {
|
||||
guard let branch else { return }
|
||||
try zsh("git checkout \(branch)", workingDirectoryURL: sdkDirectoryURL)
|
||||
try Utilities.zsh("git checkout \(branch)", workingDirectoryURL: sdkDirectoryURL)
|
||||
}
|
||||
|
||||
/// Build the Rust SDK as an XCFramework with the debug profile.
|
||||
@ -86,18 +84,18 @@ struct BuildSDK: ParsableCommand {
|
||||
if let target {
|
||||
buildCommand.append(" --only-target \(target)")
|
||||
}
|
||||
try zsh(buildCommand, workingDirectoryURL: sdkDirectoryURL)
|
||||
try Utilities.zsh(buildCommand, workingDirectoryURL: sdkDirectoryURL)
|
||||
}
|
||||
|
||||
/// Update the Xcode project to use the build of the SDK.
|
||||
func updateXcodeProject() throws {
|
||||
try updateProjectYAML()
|
||||
try zsh("xcodegen", workingDirectoryURL: projectDirectoryURL)
|
||||
try Utilities.zsh("xcodegen")
|
||||
}
|
||||
|
||||
/// Update project.yml with the local path of the SDK.
|
||||
func updateProjectYAML() throws {
|
||||
let yamlURL = projectDirectoryURL.appending(path: "project.yml")
|
||||
let yamlURL = Utilities.projectDirectoryURL.appending(path: "project.yml")
|
||||
let yamlString = try String(contentsOf: yamlURL)
|
||||
guard var projectConfig = try Yams.compose(yaml: yamlString) else { throw Error.failureParsingProjectYAML }
|
||||
|
||||
@ -106,24 +104,4 @@ struct BuildSDK: ParsableCommand {
|
||||
let updatedYAMLString = try Yams.serialize(node: projectConfig)
|
||||
try updatedYAMLString.write(to: yamlURL, atomically: true, encoding: .utf8)
|
||||
}
|
||||
|
||||
/// Runs a command in zsh.
|
||||
@discardableResult
|
||||
func zsh(_ command: String, workingDirectoryURL: URL) throws -> String? {
|
||||
let process = Process()
|
||||
process.executableURL = URL(filePath: "/bin/zsh")
|
||||
process.arguments = ["-c", command]
|
||||
process.currentDirectoryURL = workingDirectoryURL
|
||||
|
||||
let outputPipe = Pipe()
|
||||
process.standardOutput = outputPipe
|
||||
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
|
||||
guard process.terminationReason == .exit, process.terminationStatus == 0 else { throw Error.scriptFailed }
|
||||
|
||||
guard let outputData = try outputPipe.fileHandleForReading.readToEnd() else { return nil }
|
||||
return String(data: outputData, encoding: .utf8)
|
||||
}
|
||||
}
|
||||
|
24
Tools/Sources/SetupProject.swift
Normal file
24
Tools/Sources/SetupProject.swift
Normal file
@ -0,0 +1,24 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
|
||||
struct SetupProject: ParsableCommand {
|
||||
static var configuration = CommandConfiguration(abstract: "A tool to setup the required components to efficiently run and contribute to Element X iOS")
|
||||
|
||||
func run() throws {
|
||||
try setupGitHooks()
|
||||
try brewBundleInstall()
|
||||
try xcodegen()
|
||||
}
|
||||
|
||||
func setupGitHooks() throws {
|
||||
try Utilities.zsh("git config core.hooksPath .githooks")
|
||||
}
|
||||
|
||||
func brewBundleInstall() throws {
|
||||
try Utilities.zsh("brew bundle install")
|
||||
}
|
||||
|
||||
func xcodegen() throws {
|
||||
try Utilities.zsh("xcodegen")
|
||||
}
|
||||
}
|
@ -4,5 +4,6 @@ import Foundation
|
||||
@main
|
||||
struct Tools: ParsableCommand {
|
||||
static var configuration = CommandConfiguration(abstract: "A collection of command line tools for ElementX",
|
||||
subcommands: [BuildSDK.self])
|
||||
subcommands: [BuildSDK.self,
|
||||
SetupProject.self])
|
||||
}
|
||||
|
37
Tools/Sources/Utilities.swift
Normal file
37
Tools/Sources/Utilities.swift
Normal file
@ -0,0 +1,37 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
|
||||
enum Utilities {
|
||||
enum Error: LocalizedError {
|
||||
case scriptFailed(command: String, path: String)
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case let .scriptFailed(command, path):
|
||||
return "command \(command) failed in path: \(path)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static var projectDirectoryURL: URL { URL(filePath: FileManager.default.currentDirectoryPath) }
|
||||
|
||||
/// Runs a command in zsh.
|
||||
@discardableResult
|
||||
static func zsh(_ command: String, workingDirectoryURL: URL = projectDirectoryURL) throws -> String? {
|
||||
let process = Process()
|
||||
process.executableURL = URL(filePath: "/bin/zsh")
|
||||
process.arguments = ["-c", command]
|
||||
process.currentDirectoryURL = workingDirectoryURL
|
||||
|
||||
let outputPipe = Pipe()
|
||||
process.standardOutput = outputPipe
|
||||
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
|
||||
guard process.terminationReason == .exit, process.terminationStatus == 0 else { throw Error.scriptFailed(command: command, path: workingDirectoryURL.absoluteString) }
|
||||
|
||||
guard let outputData = try outputPipe.fileHandleForReading.readToEnd() else { return nil }
|
||||
return String(data: outputData, encoding: .utf8)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user