diff --git a/KissMe/Sources/Common/ArrayDecodable.swift b/KissMe/Sources/Common/ArrayDecodable.swift new file mode 100644 index 0000000..f060e01 --- /dev/null +++ b/KissMe/Sources/Common/ArrayDecodable.swift @@ -0,0 +1,13 @@ +// +// ArrayDecodable.swift +// KissMe +// +// Created by ened-book-m1 on 2023/06/30. +// + +import Foundation + + +public protocol ArrayDecodable { + init(array: [String], source: String.SubSequence) throws +} diff --git a/KissMe/Sources/Common/Foundation+Extensions.swift b/KissMe/Sources/Common/Foundation+Extensions.swift index a09573f..cddbc08 100644 --- a/KissMe/Sources/Common/Foundation+Extensions.swift +++ b/KissMe/Sources/Common/Foundation+Extensions.swift @@ -332,114 +332,6 @@ public func valueToString(_ any: Any) -> String { } -extension Array where Element: PropertyIterable { - - public func mergeCsv(toFile file: URL, merging: (_ this: [Element], _ file: [Element]) -> [Element], localized: Bool) throws where Element: ArrayDecodable { - guard file.isFileExists == true else { - try writeCsv(toFile: file, localized: localized) - return - } - let oldData = try Self.readCsv(fromFile: file, verifyHeader: true) - let finalData = merging(self, oldData) - try finalData.writeCsv(toFile: file, localized: localized) - } - - public func writeCsv(toFile file: URL, appendable: Bool = false, localized: Bool) throws { - if appendable, file.isFileExists == true { - try appendAtEnd(ofCsv: file) - } - else { - try overwrite(toCsv: file, localized: localized) - } - return - - // Nested function - func appendAtEnd(ofCsv file: URL) throws { - let oldHeader = try String.readCsvHeader(fromFile: file) - - var stringCsv = "" - for item in self { - let all = try item.allProperties() - - if stringCsv.isEmpty { - let header = all.map{ $0.0 } - if oldHeader != header { - let (_, field) = oldHeader.getDiff(from: header) ?? (-1, "") - throw GeneralError.incorrectCsvHeaderField(field) - } - } - - let values = all.map{ valueToString($0.1) }.joined(separator: ",").appending("\n") - stringCsv.append(values) - } - try stringCsv.writeAppending(toFile: file.path) - } - - // Nested function - func overwrite(toCsv file: URL, localized: Bool) throws { - var stringCsv = "" - for item in self { - let all = try item.allProperties() - if stringCsv.isEmpty { - let header = all.map { prop in - localized ? localizeString(prop.0): prop.0 - }.joined(separator: ",").appending("\n") - - stringCsv.append(header) - } - let values = all.map{ valueToString($0.1) }.joined(separator: ",").appending("\n") - stringCsv.append(values) - } - try stringCsv.write(toFile: file.path, atomically: true, encoding: .utf8) - } - } - - public static func readCsv(fromFile: URL, verifyHeader: Bool = true) throws -> [Element] where Element: ArrayDecodable { - let stringCsv = try String(contentsOfFile: fromFile.path, encoding: .utf8) - return try parseCsv(stringCsv: stringCsv, verifyHeader: verifyHeader, filePath: fromFile.path) - } - - private static func parseCsv(stringCsv: String, verifyHeader: Bool, filePath: String) throws -> [Element] where Element: ArrayDecodable { - let items = stringCsv.split(separator: "\n") - guard items.count > 0 else { - return [] - } - - var headerItems = [String]() - var elements = [Element]() - - for (index, item) in items.enumerated() { - if index == 0 { - headerItems = item.split(separator: ",", omittingEmptySubsequences: false).map { String($0) } - continue - } - let array = item.split(separator: ",", omittingEmptySubsequences: false).map { String($0) } - - //print("index: \(index), \(fromFile.path)") - let element = try Element(array: array, source: item) - - if index == 1, verifyHeader { - // Validate property with header - let properties = try element.allProperties() - for (label, _) in properties { - if false == headerItems.contains(where: { $0 == label }) { - printError("index: \(index), \(filePath)") - throw GeneralError.headerNoFiendName(label) - } - } - } - elements.append(element) - } - return elements - } - - public static func readCsvTop(fromFile: URL, verifyHeader: Bool = true, by rowCount: Int) throws -> [Element] where Element: ArrayDecodable { - let stringCsv = try String(rowCount+1, lineOfFile: fromFile.path) - return try parseCsv(stringCsv: stringCsv, verifyHeader: verifyHeader, filePath: fromFile.path) - } -} - - public func printError(_ items: Any..., separator: String = " ", terminator: String = "\n") { let output = items.map { "*\($0)" }.joined(separator: separator).appending("\n") FileHandle.standardError.write(Data(output.utf8)) diff --git a/KissMe/Sources/Common/GeneralError.swift b/KissMe/Sources/Common/GeneralError.swift new file mode 100644 index 0000000..521ee9b --- /dev/null +++ b/KissMe/Sources/Common/GeneralError.swift @@ -0,0 +1,28 @@ +// +// GeneralError.swift +// KissMe +// +// Created by ened-book-m1 on 2023/06/30. +// + +import Foundation + + +public enum GeneralError: Error { + case noServerJsonFile + case invalidInstance + case invalidAccessToken + case invalidAccountNo + case unsupportedQueryAtMockServer + case emptyData(String) + case cannotReadFile + case cannotWriteFile + case cannotReadFileLine + case cannotReadFileToConvertString + case incorrectArrayItems(String, Int, Int) + case headerNoFiendName(String) + case noCsvFile + case invalidCandleCsvFile(String) + case incorrectCsvHeaderField(String) + case noData +} diff --git a/KissMe/Sources/Common/PropertyIterable.swift b/KissMe/Sources/Common/PropertyIterable.swift index 80175f7..381b4c6 100644 --- a/KissMe/Sources/Common/PropertyIterable.swift +++ b/KissMe/Sources/Common/PropertyIterable.swift @@ -33,6 +33,109 @@ public extension PropertyIterable { } -public protocol ArrayDecodable { - init(array: [String], source: String.SubSequence) throws +extension Array where Element: PropertyIterable { + + public func mergeCsv(toFile file: URL, merging: (_ this: [Element], _ file: [Element]) -> [Element], localized: Bool) throws where Element: ArrayDecodable { + guard file.isFileExists == true else { + try writeCsv(toFile: file, localized: localized) + return + } + let oldData = try Self.readCsv(fromFile: file, verifyHeader: true) + let finalData = merging(self, oldData) + try finalData.writeCsv(toFile: file, localized: localized) + } + + public func writeCsv(toFile file: URL, appendable: Bool = false, localized: Bool) throws { + if appendable, file.isFileExists == true { + try appendAtEnd(ofCsv: file) + } + else { + try overwrite(toCsv: file, localized: localized) + } + return + + // Nested function + func appendAtEnd(ofCsv file: URL) throws { + let oldHeader = try String.readCsvHeader(fromFile: file) + + var stringCsv = "" + for item in self { + let all = try item.allProperties() + + if stringCsv.isEmpty { + let header = all.map{ $0.0 } + if oldHeader != header { + let (_, field) = oldHeader.getDiff(from: header) ?? (-1, "") + throw GeneralError.incorrectCsvHeaderField(field) + } + } + + let values = all.map{ valueToString($0.1) }.joined(separator: ",").appending("\n") + stringCsv.append(values) + } + try stringCsv.writeAppending(toFile: file.path) + } + + // Nested function + func overwrite(toCsv file: URL, localized: Bool) throws { + var stringCsv = "" + for item in self { + let all = try item.allProperties() + if stringCsv.isEmpty { + let header = all.map { prop in + localized ? localizeString(prop.0): prop.0 + }.joined(separator: ",").appending("\n") + + stringCsv.append(header) + } + let values = all.map{ valueToString($0.1) }.joined(separator: ",").appending("\n") + stringCsv.append(values) + } + try stringCsv.write(toFile: file.path, atomically: true, encoding: .utf8) + } + } + + public static func readCsv(fromFile: URL, verifyHeader: Bool = true) throws -> [Element] where Element: ArrayDecodable { + let stringCsv = try String(contentsOfFile: fromFile.path, encoding: .utf8) + return try parseCsv(stringCsv: stringCsv, verifyHeader: verifyHeader, filePath: fromFile.path) + } + + private static func parseCsv(stringCsv: String, verifyHeader: Bool, filePath: String) throws -> [Element] where Element: ArrayDecodable { + let items = stringCsv.split(separator: "\n") + guard items.count > 0 else { + return [] + } + + var headerItems = [String]() + var elements = [Element]() + + for (index, item) in items.enumerated() { + if index == 0 { + headerItems = item.split(separator: ",", omittingEmptySubsequences: false).map { String($0) } + continue + } + let array = item.split(separator: ",", omittingEmptySubsequences: false).map { String($0) } + + //print("index: \(index), \(fromFile.path)") + let element = try Element(array: array, source: item) + + if index == 1, verifyHeader { + // Validate property with header + let properties = try element.allProperties() + for (label, _) in properties { + if false == headerItems.contains(where: { $0 == label }) { + printError("index: \(index), \(filePath)") + throw GeneralError.headerNoFiendName(label) + } + } + } + elements.append(element) + } + return elements + } + + public static func readCsvTop(fromFile: URL, verifyHeader: Bool = true, by rowCount: Int) throws -> [Element] where Element: ArrayDecodable { + let stringCsv = try String(rowCount+1, lineOfFile: fromFile.path) + return try parseCsv(stringCsv: stringCsv, verifyHeader: verifyHeader, filePath: fromFile.path) + } } diff --git a/KissMe/Sources/Common/Request.swift b/KissMe/Sources/Common/Request.swift index cf183bd..59ce3c7 100644 --- a/KissMe/Sources/Common/Request.swift +++ b/KissMe/Sources/Common/Request.swift @@ -26,25 +26,6 @@ extension Method: CustomStringConvertible { } } -public enum GeneralError: Error { - case noServerJsonFile - case invalidInstance - case invalidAccessToken - case invalidAccountNo - case unsupportedQueryAtMockServer - case emptyData(String) - case cannotReadFile - case cannotWriteFile - case cannotReadFileLine - case cannotReadFileToConvertString - case incorrectArrayItems(String, Int, Int) - case headerNoFiendName(String) - case noCsvFile - case invalidCandleCsvFile(String) - case incorrectCsvHeaderField(String) - case noData -} - public enum QueryError: Error { case invalidUrl diff --git a/KissMe/Sources/Index/IndexResult.swift b/KissMe/Sources/Index/IndexResult.swift index 0346602..75b8cf7 100644 --- a/KissMe/Sources/Index/IndexResult.swift +++ b/KissMe/Sources/Index/IndexResult.swift @@ -39,3 +39,16 @@ public struct KissIndexResult: Codable { self.output = output } } + + +public struct KissMatrixResult: Codable { + public let code: Int + public let kmis: [String] + public let output: [KissIndexResult.Output] + + public init(code: Int, kmis: [String], output: [KissIndexResult.Output]) { + self.code = code + self.kmis = kmis + self.output = output + } +} diff --git a/KissMeGolder/Package.swift b/KissMeGolder/Package.swift new file mode 100644 index 0000000..0876e67 --- /dev/null +++ b/KissMeGolder/Package.swift @@ -0,0 +1,34 @@ +// swift-tools-version: 5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "KissMeGolder", + platforms: [ + .macOS(.v13), .iOS(.v14), .tvOS(.v14) + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .executable( + name: "KissMeGolder", + targets: ["KissMeGolder"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + //.package(url: "../KissMe", from: "1.0.0"), + .package(path: "../KissMe"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .executableTarget( + name: "KissMeGolder", + dependencies: ["KissMe"], + path: "Sources"), + //.testTarget( + // name: "KissMeGolderTests", + // dependencies: ["KissMeGolder"], + // path: "Tests"), + ] +) diff --git a/KissMeGolder/Sources/KissGolder.swift b/KissMeGolder/Sources/KissGolder.swift new file mode 100644 index 0000000..239538c --- /dev/null +++ b/KissMeGolder/Sources/KissGolder.swift @@ -0,0 +1,16 @@ +// +// KissGolder.swift +// KissMeGolder +// +// Created by ened-book-m1 on 2023/06/30. +// + +import Foundation + + +class KissMatrix { + + func run() { + print("hello..") + } +} diff --git a/KissMeGolder/Sources/main.swift b/KissMeGolder/Sources/main.swift index 68cb406..480b58e 100644 --- a/KissMeGolder/Sources/main.swift +++ b/KissMeGolder/Sources/main.swift @@ -7,5 +7,4 @@ import Foundation -print("Hello, World!") - +KissMatrix().run() diff --git a/KissMeIndex/Sources/KissIndex+0005.swift b/KissMeIndex/Sources/KissIndex+0005.swift index 3521395..7e1c355 100644 --- a/KissMeIndex/Sources/KissIndex+0005.swift +++ b/KissMeIndex/Sources/KissIndex+0005.swift @@ -12,6 +12,10 @@ import KissMe extension KissIndex { func indexSet_0005(date: Date, config: String?, kmi: KissIndexType) { + if productsCount == 0 { + loadShop(url: KissIndex.shopProductsUrl) + } + let belongs: [BelongClassCode] = [.averageVolume, .volumeIncreaseRate, .averageVolumeTurnoverRate, .transactionValue, .averageTransactionValueTurnoverRate] do { diff --git a/KissMeIndex/Sources/KissIndex.swift b/KissMeIndex/Sources/KissIndex.swift index c9f5fca..ec0ae18 100644 --- a/KissMeIndex/Sources/KissIndex.swift +++ b/KissMeIndex/Sources/KissIndex.swift @@ -82,7 +82,7 @@ class KissIndex: KissMe.ShopContext { //print(jsonString) FileHandle.standardOutput.write(jsonData) } catch { - assertionFailure(error.localizedDescription) + printError(error) } } diff --git a/KissMeMatrix/Package.swift b/KissMeMatrix/Package.swift new file mode 100644 index 0000000..0aa32bd --- /dev/null +++ b/KissMeMatrix/Package.swift @@ -0,0 +1,34 @@ +// swift-tools-version: 5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "KissMeMatrix", + platforms: [ + .macOS(.v13), .iOS(.v14), .tvOS(.v14) + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .executable( + name: "KissMeMatrix", + targets: ["KissMeMatrix"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + //.package(url: "../KissMe", from: "1.0.0"), + .package(path: "../KissMe"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .executableTarget( + name: "KissMeMatrix", + dependencies: ["KissMe"], + path: "Sources"), + //.testTarget( + // name: "KissMeMatrixTests", + // dependencies: ["KissMeMatrix"], + // path: "Tests"), + ] +) diff --git a/KissMeMatrix/Sources/KissMatrix.swift b/KissMeMatrix/Sources/KissMatrix.swift index f120f0c..951f1e8 100644 --- a/KissMeMatrix/Sources/KissMatrix.swift +++ b/KissMeMatrix/Sources/KissMatrix.swift @@ -96,7 +96,7 @@ class KissMatrix { let semaphore = DispatchSemaphore(value: 0) Task { - let indexResult = try await withThrowingTaskGroup(of: KissIndexResult?.self, returning: [KissIndexResult].self) { taskGroup in + let results = try await withThrowingTaskGroup(of: KissIndexResult?.self, returning: [KissIndexResult].self) { taskGroup in for indexSet in model.indexSets { guard let (runUrl, args) = indexSet.build(date: runDate) else { print("Cannot get command from \(indexSet.name)") @@ -121,9 +121,7 @@ class KissMatrix { return taskResult } - //for result in indexResult { - // print(result) - //} + mergeResult(results) semaphore.signal() } semaphore.wait() @@ -181,6 +179,40 @@ class KissMatrix { } + private func mergeResult(_ results: [KissIndexResult]) { + let indexCount = results.count + var mergedOutput = [String: [KissIndexResult.Output]]() + for result in results { + for item in result.output { + if let _ = mergedOutput[item.shortCode] { + mergedOutput[item.shortCode]!.append(item) + } + else { + mergedOutput[item.shortCode] = [item] + } + } + } + + var normalized = [KissIndexResult.Output]() + for (productNo, output) in mergedOutput { + let weight = output.reduce(0.0, { $0 + $1.weight }) / Double(indexCount) + let output = KissIndexResult.Output(shortCode: productNo, productName: output.first?.productName, weight: weight) + normalized.append(output) + } + normalized.sort(by: { $0.weight > $1.weight }) + + + let kmis = results.map { $0.kmi } + let matrixResult = KissMatrixResult(code: 200, kmis: kmis, output: normalized) + do { + let jsonData = try JSONEncoder().encode(matrixResult) + try FileHandle.standardOutput.write(contentsOf: jsonData) + } catch { + printError(error) + } + } + + private func loadModel(_ jsonFile: String) -> Model? { do { let configUrl = URL.currentDirectory().appending(path: jsonFile) diff --git a/README.md b/README.md index 4038b08..d337aa6 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Command | 설명 WIP `modify (PNO) (ONO) (가격) (수량)` | 주문 내역을 변경. (수량) 에 -82 로 입력하면 전체수량. `open bag` | 보유 종목 열람. 보유 주식은 **data/account-stocks.csv** 파일로 저장. 잔고 상황은 **data/account-amount.csv** 파일로 저장. `now [PNO]` | 종목의 현재가 열람. PNO 은 생략 가능. **data/(PNO)/price/prices-(yyyyMM01).csv** 파일로 저장. +`now all` | 모든 종목의 현재가를 열람. **data/(PNO)/price/prices-(yyyyMM01).csv** 파일로 저장. `candle [PNO]` | 종목의 분봉 열람. PNO 은 생략 가능. **data/(PNO)/min/candle-(yyyyMMdd).csv** 파일로 저장. `candle all [resume]` | 모든 종목의 분봉 열람. cron job 으로 돌리기 위해서 추가. **data/(PNO)/min/candle-(yyyyMMdd).csv** 파일로 저장. (resume) 을 기입하면, 이미 받은 파일은 검사하여, 데이터에 오류가 있으면 다시 받고 오류가 없으면 새롭게 열람하지 않음. `candle day [PNO]` | 종목의 최근 250일 동안의 일봉 열람. PNO 은 생략 가능. **data/(PNO)/day/candle-(yyyyMMdd).csv** 파일로 저장. diff --git a/bin/data b/bin/data index 33e59cb..8ef77ec 160000 --- a/bin/data +++ b/bin/data @@ -1 +1 @@ -Subproject commit 33e59cbae44f1516827c9c842604d8d835c3bce3 +Subproject commit 8ef77ece1861f8231174c003e3578d651cce8f9c diff --git a/projects/macos/KissMe.xcodeproj/project.pbxproj b/projects/macos/KissMe.xcodeproj/project.pbxproj index 7170cb9..208947d 100644 --- a/projects/macos/KissMe.xcodeproj/project.pbxproj +++ b/projects/macos/KissMe.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 340A4DBD2A4C34BE005A1FBA /* IndexContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340A4DBC2A4C34BE005A1FBA /* IndexContext.swift */; }; + 340A4DC42A4E4345005A1FBA /* ArrayDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340A4DC32A4E4345005A1FBA /* ArrayDecodable.swift */; }; + 340A4DC82A4E43C5005A1FBA /* GeneralError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340A4DC72A4E43C5005A1FBA /* GeneralError.swift */; }; 341F5EB02A0A80EC00962D48 /* KissMe.docc in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EAF2A0A80EC00962D48 /* KissMe.docc */; }; 341F5EB62A0A80EC00962D48 /* KissMe.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 341F5EAB2A0A80EC00962D48 /* KissMe.framework */; }; 341F5EBB2A0A80EC00962D48 /* KissMeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EBA2A0A80EC00962D48 /* KissMeTests.swift */; }; @@ -55,6 +57,8 @@ /* Begin PBXFileReference section */ 340A4DBC2A4C34BE005A1FBA /* IndexContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndexContext.swift; sourceTree = ""; }; + 340A4DC32A4E4345005A1FBA /* ArrayDecodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayDecodable.swift; sourceTree = ""; }; + 340A4DC72A4E43C5005A1FBA /* GeneralError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralError.swift; sourceTree = ""; }; 341F5EAB2A0A80EC00962D48 /* KissMe.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KissMe.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 341F5EAE2A0A80EC00962D48 /* KissMe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KissMe.h; sourceTree = ""; }; 341F5EAF2A0A80EC00962D48 /* KissMe.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; name = KissMe.docc; path = ../KissMe.docc; sourceTree = ""; }; @@ -201,6 +205,8 @@ 341F5F0E2A15223A00962D48 /* SeibroRequest.swift */, 341F5F102A1685E700962D48 /* ShopRequest.swift */, 341F5F022A11A2BC00962D48 /* Credential.swift */, + 340A4DC72A4E43C5005A1FBA /* GeneralError.swift */, + 340A4DC32A4E4345005A1FBA /* ArrayDecodable.swift */, 341F5F062A14634F00962D48 /* Foundation+Extensions.swift */, 34D3680E2A2AA0BE005E6756 /* PropertyIterable.swift */, ); @@ -359,6 +365,8 @@ buildActionMask = 2147483647; files = ( 341F5EFB2A10909D00962D48 /* LoginResult.swift in Sources */, + 340A4DC42A4E4345005A1FBA /* ArrayDecodable.swift in Sources */, + 340A4DC82A4E43C5005A1FBA /* GeneralError.swift in Sources */, 341F5F0B2A15115400962D48 /* KissShop.swift in Sources */, 3435A7F72A35D82000D604F1 /* DomesticShortSelling.swift in Sources */, 341F5F072A14634F00962D48 /* Foundation+Extensions.swift in Sources */, diff --git a/projects/macos/KissMeGolder.xcodeproj/project.pbxproj b/projects/macos/KissMeGolder.xcodeproj/project.pbxproj index beeab21..fc835b0 100644 --- a/projects/macos/KissMeGolder.xcodeproj/project.pbxproj +++ b/projects/macos/KissMeGolder.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 340A4DCC2A4E4C37005A1FBA /* KissGolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340A4DCB2A4E4C37005A1FBA /* KissGolder.swift */; }; 3498435C2A24DC1300E85B08 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3498435B2A24DC1300E85B08 /* main.swift */; }; 349843642A24DC7800E85B08 /* KissMe.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 349843632A24DC7800E85B08 /* KissMe.framework */; }; 349843652A24DC7800E85B08 /* KissMe.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 349843632A24DC7800E85B08 /* KissMe.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -36,6 +37,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 340A4DCB2A4E4C37005A1FBA /* KissGolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissGolder.swift; sourceTree = ""; }; 349843582A24DC1300E85B08 /* KissMeGolder */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = KissMeGolder; sourceTree = BUILT_PRODUCTS_DIR; }; 3498435B2A24DC1300E85B08 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 349843632A24DC7800E85B08 /* KissMe.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = KissMe.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -74,6 +76,7 @@ isa = PBXGroup; children = ( 3498435B2A24DC1300E85B08 /* main.swift */, + 340A4DCB2A4E4C37005A1FBA /* KissGolder.swift */, ); name = KissMeGolder; path = ../../KissMeGolder/Sources; @@ -146,6 +149,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 340A4DCC2A4E4C37005A1FBA /* KissGolder.swift in Sources */, 3498435C2A24DC1300E85B08 /* main.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/projects/macos/KissMeGolder.xcodeproj/xcshareddata/xcschemes/KissMeGolder.xcscheme b/projects/macos/KissMeGolder.xcodeproj/xcshareddata/xcschemes/KissMeGolder.xcscheme new file mode 100644 index 0000000..b68b664 --- /dev/null +++ b/projects/macos/KissMeGolder.xcodeproj/xcshareddata/xcschemes/KissMeGolder.xcscheme @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/build.sh b/scripts/build.sh index c1b7c16..5d3ea23 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -9,6 +9,7 @@ THIS_PATH=`dirname "$0"` ${THIS_PATH}/build_any.sh KissMeConsole ${THIS_PATH}/build_any.sh KissMeIndex +${THIS_PATH}/build_any.sh KissMeMatrix #${THIS_PATH}/build_any.sh KissMeBatch #${THIS_PATH}/build_any.sh KissGram diff --git a/scripts/build_any.sh b/scripts/build_any.sh index f8f96a8..704b54e 100755 --- a/scripts/build_any.sh +++ b/scripts/build_any.sh @@ -14,7 +14,7 @@ cd ${CONSOLE_APP} rm -rf .build -swift build -c release +swift build -c release --enable-dead-strip cp ./.build/release/${CONSOLE_APP} ../bin