diff --git a/Sources/swcomp/Benchmarks/RunBenchmarkCommand.swift b/Sources/swcomp/Benchmarks/RunBenchmarkCommand.swift index befc39ce..28585daf 100644 --- a/Sources/swcomp/Benchmarks/RunBenchmarkCommand.swift +++ b/Sources/swcomp/Benchmarks/RunBenchmarkCommand.swift @@ -23,6 +23,9 @@ final class RunBenchmarkCommand: Command { @Key("-s", "--save", description: "Saves the results into the specified file") var savePath: String? + @Flag("-a", "--append", description: "Appends results to a file instead of overwriting it") + var append: Bool + @Key("-c", "--compare", description: "Compares the results with other results saved in the specified file") var comparePath: String? @@ -117,9 +120,27 @@ final class RunBenchmarkCommand: Command { } if let savePath = self.savePath { - let uuid = UUID() let metadata = try BenchmarkMetadata(self.description) - let saveFile = SaveFile(metadatas: [uuid: metadata], runs: [SaveFile.Run(metadataUUID: uuid, results: newResults)]) + var saveFile: SaveFile + + var isDir = ObjCBool(false) + let saveFileExists = FileManager.default.fileExists(atPath: savePath, isDirectory: &isDir) + + if self.append && saveFileExists { + if isDir.boolValue { + swcompExit(.benchmarkCannotAppendToDirectory) + } + saveFile = try SaveFile.load(from: savePath) + var uuid: UUID + repeat { + uuid = UUID() + } while saveFile.metadatas[uuid] != nil + saveFile.metadatas[uuid] = metadata + saveFile.runs.append(SaveFile.Run(metadataUUID: uuid, results: newResults)) + } else { + let uuid = UUID() + saveFile = SaveFile(metadatas: [uuid: metadata], runs: [SaveFile.Run(metadataUUID: uuid, results: newResults)]) + } let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted diff --git a/Sources/swcomp/SwcompError.swift b/Sources/swcomp/SwcompError.swift index a9d0407b..671a7c7a 100644 --- a/Sources/swcomp/SwcompError.swift +++ b/Sources/swcomp/SwcompError.swift @@ -18,6 +18,7 @@ enum SwcompError { case benchmarkCannotMeasureBadOutSize(Benchmark.Type) case benchmarkReaderTarNoInputSize(String) case benchmarkCannotGetSubcommandPathWindows + case benchmarkCannotAppendToDirectory case containerSymLinkDestPath(String) case containerNoEntryData(String) case containerOutPathExistsNotDir @@ -50,6 +51,8 @@ enum SwcompError { return 205 case .benchmarkCannotGetSubcommandPathWindows: return 206 + case .benchmarkCannotAppendToDirectory: + return 207 case .containerSymLinkDestPath: return 301 case .containerNoEntryData: @@ -91,6 +94,8 @@ enum SwcompError { return "ReaderTAR.benchmarkSetUp(): file size is not available for input=\(input)." case .benchmarkCannotGetSubcommandPathWindows: return "Cannot get subcommand path on Windows. (This error should never be shown!)" + case .benchmarkCannotAppendToDirectory: + return "Cannot append results to the save path since it is a directory." case .containerSymLinkDestPath(let entryName): return "Unable to get destination path for symbolic link \(entryName)." case .containerNoEntryData(let entryName):