Skip to content

Commit

Permalink
support output-dir (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
muukii authored Oct 22, 2022
1 parent c47730c commit 83f2813
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 8 deletions.
18 changes: 18 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/grain.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "GrainDescriptor"
BuildableName = "GrainDescriptor"
BlueprintName = "GrainDescriptor"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
Expand Down Expand Up @@ -78,7 +92,11 @@
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
<<<<<<< Updated upstream
argument = "./Sources/Fixture.swift --verbose"
=======
argument = "./Sources/Fixture.swift ./fixtures/openapi.swift --verbose --output /Users/muukii/Desktop"
>>>>>>> Stashed changes
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
Expand Down
113 changes: 113 additions & 0 deletions Sources/Grain/CLI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import ArgumentParser
import Foundation
import TSCBasic
import TSCUtility
import GrainDescriptor

let RUNTIME_NAME = "GrainDescriptor"

Expand Down Expand Up @@ -31,6 +32,23 @@ struct CLI: AsyncParsableCommand {

struct Render: AsyncParsableCommand {

<<<<<<< Updated upstream
=======
struct RenderResult {
let outputData: Data
let headerData: Data

func header() -> GrainDescriptor.Header {
.decode(headerData)
}

func outputString() -> String {
String(data: outputData, encoding: .utf8)!
}

}

>>>>>>> Stashed changes
struct DomainError: Swift.Error, LocalizedError, Equatable {

var errorDescription: String?
Expand All @@ -46,11 +64,64 @@ struct CLI: AsyncParsableCommand {

mutating func run() async throws {

<<<<<<< Updated upstream
let filePath = localFileSystem.currentWorkingDirectory!.appending(
RelativePath(targetFilePath)
)

guard localFileSystem.exists(filePath) else {
=======
let validatedPaths = targetFilePaths.map {
AbsolutePath($0, relativeTo: localFileSystem.currentWorkingDirectory!)
}

let results = try await withThrowingTaskGroup(of: (AbsolutePath, RenderResult).self) { group in

for path in validatedPaths {
group.addTask {
let result = try await self.render(path)
return (path, result)
}
}

return try await group.reduce(into: [(AbsolutePath, RenderResult)]()) { partialResult, result in
partialResult.append(result)
}

}

if let outputDirectory {

let outputDirectoryAbsolute = AbsolutePath(outputDirectory, relativeTo: localFileSystem.currentWorkingDirectory!)

for result in results {

let path = result.0
let r = result.1
let c = r.header()

let fileName = [path.basenameWithoutExt, c.outputConfiguration.fileExtension].compactMap { $0 }.joined(separator: ".")

let writePath = outputDirectoryAbsolute.appending(component: fileName)

try r.outputData.write(to: URL.init(fileURLWithPath: writePath.pathString), options: [.atomic])

Log.info("\(writePath.pathString)")

}

} else {
for result in results {
print(result.1.outputString())
}
}

}

private func render(_ targetFilePath: AbsolutePath) async throws -> RenderResult {

guard localFileSystem.exists(targetFilePath) else {
>>>>>>> Stashed changes
throw CLIError.fileNotFound
}

Expand Down Expand Up @@ -136,8 +207,13 @@ runtimeFrameworksPath: \(runtimeFrameworksPath)
]
cmd += ["-swift-version", "5"]

<<<<<<< Updated upstream
try await withTemporaryDirectory { workingPath in

=======
return try await withTemporaryDirectory { workingPath -> RenderResult in

>>>>>>> Stashed changes
let compiledFile = workingPath.appending(component: "compiled")

// make a binary
Expand Down Expand Up @@ -167,21 +243,49 @@ runtimeFrameworksPath: \(runtimeFrameworksPath)
do {

let outputFile = workingPath.appending(component: "output")
<<<<<<< Updated upstream

=======
let outputHeaderFile = workingPath.appending(component: "output_header")

>>>>>>> Stashed changes
guard let outputFileDesc = fopen(outputFile.pathString, "w") else {
throw DomainError.couldNotCreateOutputFile
}

<<<<<<< Updated upstream
=======
guard let outputHeaderFileDesc = fopen(outputHeaderFile.pathString, "w") else {
throw DomainError.couldNotCreateOutputFile
}

>>>>>>> Stashed changes
var cmd: [String] = []

cmd += [compiledFile.pathString]
<<<<<<< Updated upstream

cmd += ["-fileno", "\(fileno(outputFileDesc))"]

let result = try await TSCBasic.Process.popen(arguments: cmd, environment: ProcessInfo.processInfo.environment, loggingHandler: { log in })

fclose(outputFileDesc)

=======

cmd += ["-fileno-output", "\(fileno(outputFileDesc))"]
cmd += ["-fileno-header", "\(fileno(outputHeaderFileDesc))"]

let result = try await TSCBasic.Process.popen(
arguments: cmd,
environment: ProcessInfo.processInfo.environment,
loggingHandler: { log in }
)

fclose(outputFileDesc)
fclose(outputHeaderFileDesc)

>>>>>>> Stashed changes
// Return now if there was an error.
if result.exitStatus != .terminated(code: 0) {

Expand All @@ -190,11 +294,20 @@ runtimeFrameworksPath: \(runtimeFrameworksPath)

throw DomainError.failureInMakingOutput
}
<<<<<<< Updated upstream

let output: String = try localFileSystem.readFileContents(outputFile)

print(output)

=======

let output: Data = try localFileSystem.readFileContents(outputFile)
let outputHeader: Data = try localFileSystem.readFileContents(outputHeaderFile)

return .init(outputData: output, headerData: outputHeader)

>>>>>>> Stashed changes
}

}
Expand Down
8 changes: 8 additions & 0 deletions Sources/Grain/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ enum Log {
}
}

static func info(
file: StaticString = #file,
line: UInt = #line,
_ object: @autoclosure () -> Any
) {
print(object())
}

static func error(
file: StaticString = #file,
line: UInt = #line,
Expand Down
60 changes: 52 additions & 8 deletions Sources/GrainDescriptor/Entrypoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,35 @@ public struct Serialization {

}

public struct Header: Codable {
public let outputConfiguration: OutputConfiguration

public func json() -> String {
let e = JSONEncoder()
let d = try! e.encode(self)
return String(data: d, encoding: .utf8)!
}

public static func decode(_ data: Data) -> Self {
let d = JSONDecoder()
let r = try! d.decode(Self.self, from: data)
return r
}
}

public struct OutputConfiguration: Codable {

public var fileExtension: String?

public init(fileExtension: String? = nil) {
self.fileExtension = fileExtension
}

}

public func serialize(
serialization: Serialization = .json,
outputConfiguration: OutputConfiguration = .init(fileExtension: "json"),
@GrainBuilder _ thunk: () throws -> some GrainView
) {

Expand All @@ -56,16 +83,33 @@ public func serialize(
let data = try serialization.encode(value)
let text = String(data: data, encoding: .utf8)!

if let optIdx = CommandLine.arguments.firstIndex(of: "-fileno") {
if let outputFileDesc = Int32(CommandLine.arguments[optIdx + 1]) {
guard let fd = fdopen(outputFileDesc, "w") else {
return
// write output
do {
if let optIdx = CommandLine.arguments.firstIndex(of: "-fileno-output") {
if let outputFileDesc = Int32(CommandLine.arguments[optIdx + 1]) {
guard let fd = fdopen(outputFileDesc, "w") else {
return
}
fputs(text, fd)
fclose(fd)
}
} else {
print(text)
}
}

// write header
do {
if let optIdx = CommandLine.arguments.firstIndex(of: "-fileno-header") {
if let outputFileDesc = Int32(CommandLine.arguments[optIdx + 1]) {
guard let fd = fdopen(outputFileDesc, "w") else {
return
}
fputs(Header.init(outputConfiguration: outputConfiguration).json(), fd)
fclose(fd)
}
fputs(text, fd)
fclose(fd)
} else {
}
} else {
print(text)
}
} catch {
print("❌ Serialization failed:", error)
Expand Down

0 comments on commit 83f2813

Please sign in to comment.