-
-
Notifications
You must be signed in to change notification settings - Fork 624
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
Linux Support #1188
Linux Support #1188
Conversation
Generated by 🚫 Danger |
fixed wrong find-replace
I was able to make tests green on macOS while preserving successful compilation under Linux 🔥 However, I also need support how to setup CircleCI to run 🙏🏻 |
I don't really have experience with Linux but you could also move us to Github actions if you prefer, this project predates them but we could easily use GH actions now |
Thanks @krzysztofzablocki . Apart from all Linux-related stuff, I have faced an issue when running tests with When Looking into it, but this is closely related to why |
Tried to rename My suspicion is that Update: found the relevant Swift forums thread here. I'll try the workaround, once successful, |
My current plan is:
|
Implemented GH actions for macOS and ubuntu; disabled both actions until #1188 is merged.
return try templatePaths(from: from).compactMap { | ||
if $0.extension == "sourcerytemplate" { | ||
let template = try JSONDecoder().decode(SourceryTemplate.self, from: $0.read()) | ||
switch template.instance.kind { | ||
case .ejs: | ||
guard EJSTemplate.ejsPath != nil else { | ||
Log.warning("Skipping template \($0). JavaScript templates require EJS path to be set manually when using Sourcery built with Swift Package Manager. Use `--ejsPath` command line argument to set it.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@krzysztofzablocki here I was really unsure about this guard statements. Due to changes I have introduced in EJSTemplate.swift file in this MR, swift test
started to work, but for tests, not for a release build which I am unsure how to verify.
Could you please share some insight on this, shall I leave these guard statements as they were, or would it actually work due to this change I have mentioned?
Thank you 🙏🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we don't have the EJS contents then the templates wouldn't work but you could also reject it based on env since you mentioned JavascriptCore doesn't work on Linux
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one, thanks. I'll revert these changes to throw a more precise error as before.
Newer SPM (I think 5.9) supports "resources embedded into binary executables" (see .embedInCode
) - maybe we could include EJS template contents into code (encoded, say, with base16/64 encoding or as array of bytes) - I'd need to dig deeper into this, but sounds like some form of convenience for Sourcery. I'll revisit this later.
/// Defines enum case associated value | ||
public final class AssociatedValue: NSObject, SourceryModel, AutoDescription, Typed, Annotated, Diffable, DynamicMemberLookup { | ||
public subscript(dynamicMember member: String) -> Any? { | ||
switch member { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list is not exhaustive, but just to make all unit tests work. It must be autogenerated like init(coder:)
methods, and I'll address it in #1198
import Foundation | ||
|
||
/// Defines Swift enum | ||
public final class Enum: Type { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to limitations how #if
statement can be used in Swift, I figured it is better to have separate files rather than having multiple definitions in already overcrowded files.
context("given array") { | ||
it("doesnt modify the value") { | ||
let result = generate("{% for key,value in type.MyClass.variables.2.annotations %}{{ value | toArray }}{% endfor %}") | ||
expect(result).to(equal("[\"Hello\", \"beautiful\", \"World\"]")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On linux, stringify
from Stencil provides quotes around string values. I could not workaround it, and most likely this is due to differences in how NSObject
works on two platforms.
it("can render variable isOptional") { | ||
expect(generate("{{ type.Complex.variables.first.isOptional }}")).to(equal("0")) | ||
} | ||
#else | ||
it("can render variable isOptional") { | ||
expect(generate("{{ type.Complex.variables.first.isOptional }}")).to(equal("false")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤷🏻 Don't ask me why 🤷🏻 Really weird difference
@@ -1271,14 +1294,15 @@ class SourcerySpecTests: QuickSpec { | |||
}.toNot(throwError()) | |||
} | |||
|
|||
#if canImport(ObjectiveC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is related to crash in Swift compiler reported here.
@@ -82,6 +90,12 @@ class TemplatesTests: QuickSpec { | |||
expect(generatedFileFilteredLines).to(equal(expectedFileFilteredLines)) | |||
} | |||
|
|||
#if !canImport(ObjectiveC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Linux, static func setUp()
is not called, so I needed to manually add this beforeSuite
to generate files before tests are run.
#if canImport(ObjectiveC) | ||
let contextSources = "\(resources)/Context" | ||
#else | ||
let contextSources = "\(resources)/Context_Linux" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Different file folders are used for two reasons:
- SPM does not have a method to specify where to put the copied resources (
Resource.copy(path:locatization:)
). - Because of the crash in Swift compiler,
AutoCodable.swift
file needs to be omitted when tests are run on Linux
AMAZING. Looking forward to seeing this hopefully merged |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some small comments but amazing work 👏
return try templatePaths(from: from).compactMap { | ||
if $0.extension == "sourcerytemplate" { | ||
let template = try JSONDecoder().decode(SourceryTemplate.self, from: $0.read()) | ||
switch template.instance.kind { | ||
case .ejs: | ||
guard EJSTemplate.ejsPath != nil else { | ||
Log.warning("Skipping template \($0). JavaScript templates require EJS path to be set manually when using Sourcery built with Swift Package Manager. Use `--ejsPath` command line argument to set it.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we don't have the EJS contents then the templates wouldn't work but you could also reject it based on env since you mentioned JavascriptCore doesn't work on Linux
Resolves #306
Description
This MR enables support on Linux (particularly was compiled under Ubuntu 22.04, but should work on other version as well if all dependencies are met).
Technical Details
A couple of things were disabled (#1198):
FileWatcher
relies onmacOS
SDK and usesFSEvents
framework, it was disabled, i.e. folder watching flag (--watch
) is not working under LinuxJavaScriptCore
functionality (ejs
templates etc.) were disabled under Linux onlyNSObject
available under Linux does not conform to KVC, thus tests inTypedSpec.generated.swift
were moved to class definitions.Notes
getVaList
was replaced with recommendedwithVaList() {}
(used mostly forCodable
-related code generation)NSException
was replaced withfatalError
only under LinuxCFAbsoluteTimeGetCurrent
was replaced withDate().timeIntervalSince1970
for all platformsFolderWatcher
needs to be implemented probably using approach similar to this onesha256()
ofData
extension is implemented via swift-crypto packageEnvironment Setup
I have installed ubuntu VM through tart and updated to 22.04 according to this guide.
I had to run the following commands prior to being able to run
bundle install
in Sourcery:sudo apt install libffi-dev
sudo apt install build-essential
sudo apt install libsqlite3-dev
sudo apt-get install libncurses5-dev