From cbfce83b11a5e8d33a18bc52f1e77b1d27ce254c Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 01:39:33 +0900 Subject: [PATCH 01/10] Support Swift 5.1 --- Package.resolved | 14 +- Package.swift | 6 +- Sources/Hexaville/main.swift | 2 +- Sources/HexavilleCore/Constant.swift | 4 +- .../HexavilleCore/HexavilleFile/Version.swift | 2 +- Sources/HexavilleCore/Util/Hashids.swift | 619 +++++++++--------- templates/SwiftProject/Swift5/Package.swift | 14 + 7 files changed, 342 insertions(+), 319 deletions(-) create mode 100644 templates/SwiftProject/Swift5/Package.swift diff --git a/Package.resolved b/Package.resolved index 7a03bdb..eb8de9f 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,17 +6,17 @@ "repositoryURL": "https://github.com/jakeheis/SwiftCLI.git", "state": { "branch": null, - "revision": "5318c37d3cacc8780f50b87a8840a6774320ebdf", - "version": "5.2.2" + "revision": "ba2268e67c07b9f9cfbc0801385e6238b36255eb", + "version": "5.3.2" } }, { "package": "SwiftyJSON", - "repositoryURL": "https://github.com/IBM-Swift/SwiftyJSON.git", + "repositoryURL": "https://github.com/SwiftyJSON/SwiftyJSON.git", "state": { "branch": null, - "revision": "f2612ea3ac29996ae9601bdcb00cc1c29e26f104", - "version": "17.0.4" + "revision": "2b6054efa051565954e1d2b9da831680026cd768", + "version": "5.0.0" } }, { @@ -24,8 +24,8 @@ "repositoryURL": "https://github.com/jpsim/Yams.git", "state": { "branch": null, - "revision": "26ab35f50ea891e8edefcc9d975db2f6b67e1d68", - "version": "1.0.1" + "revision": "c947a306d2e80ecb2c0859047b35c73b8e1ca27f", + "version": "2.0.0" } } ] diff --git a/Package.swift b/Package.swift index 1a02676..3263df8 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:4.2 +// swift-tools-version:5.1 import PackageDescription let package = Package( @@ -8,9 +8,9 @@ let package = Package( .executable(name: "hexaville", targets: ["Hexaville"]) ], dependencies: [ - .package(url: "https://github.com/IBM-Swift/SwiftyJSON.git", .upToNextMajor(from: "17.0.1")), + .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", .upToNextMajor(from: "5.0.0")), .package(url: "https://github.com/jakeheis/SwiftCLI.git", .upToNextMajor(from: "5.0.0")), - .package(url: "https://github.com/jpsim/Yams.git", .upToNextMajor(from: "1.0.1")) + .package(url: "https://github.com/jpsim/Yams.git", .upToNextMajor(from: "2.0.0")) ], targets: [ .target(name: "HexavilleCore", dependencies: [ diff --git a/Sources/Hexaville/main.swift b/Sources/Hexaville/main.swift index 5b6e9b5..2eddb88 100644 --- a/Sources/Hexaville/main.swift +++ b/Sources/Hexaville/main.swift @@ -33,7 +33,7 @@ class GenerateProject: Command { let name = "generate" let shortDescription = "Generate initial project" let projectName = Parameter() - let swiftToolVersion = Key("--swift-tools-version", description: "Major Swift Tool Version for this project. default is 4.2") + let swiftToolVersion = Key("--swift-tools-version", description: "Major Swift Tool Version for this project. default is 5.1") let dest = Key("-o", "--dest", description: "Destination for the project") private func resolveSwiftVersion() throws -> SwiftVersion { diff --git a/Sources/HexavilleCore/Constant.swift b/Sources/HexavilleCore/Constant.swift index 8c11985..1688d24 100644 --- a/Sources/HexavilleCore/Constant.swift +++ b/Sources/HexavilleCore/Constant.swift @@ -13,11 +13,11 @@ public struct Constant { ] public static var supportedSwiftVersionsRange: CountableClosedRange { - return 3...4 + return 5...5 } public static var defaultSwiftVersion: SwiftVersion { - return .release(Version(major: 4, minor: 2)) + return .release(Version(major: 5, minor: 1)) } public static let appPrefix = "hexaville" diff --git a/Sources/HexavilleCore/HexavilleFile/Version.swift b/Sources/HexavilleCore/HexavilleFile/Version.swift index 45ac728..fdfcf05 100644 --- a/Sources/HexavilleCore/HexavilleFile/Version.swift +++ b/Sources/HexavilleCore/HexavilleFile/Version.swift @@ -72,7 +72,7 @@ extension Version { throw VersionError.notEmpty } - var intCastedComponents: [Int] = try components.map({ + let intCastedComponents: [Int] = try components.map({ guard let int = Int($0) else { throw VersionError.invalidVersion(string) } diff --git a/Sources/HexavilleCore/Util/Hashids.swift b/Sources/HexavilleCore/Util/Hashids.swift index 7458c03..e077f29 100644 --- a/Sources/HexavilleCore/Util/Hashids.swift +++ b/Sources/HexavilleCore/Util/Hashids.swift @@ -20,46 +20,53 @@ //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //SOFTWARE. +// +// HashIds.swift +// http://hashids.org +// +// Author https://github.com/malczak +// Licensed under the MIT license. +// import Foundation // MARK: Hashids options public struct HashidsOptions { - - static let VERSION = "1.1.0" - - static var MIN_ALPHABET_LENGTH: Int = 16 - - static var SEP_DIV: Double = 3.5 - - static var GUARD_DIV: Double = 12 - - static var ALPHABET: String = "abcdefghijklmnopqrstuvwxyz" - - static var SEPARATORS: String = "cfhistuCFHISTU" - + + static let VERSION = "1.1.0" + + static var MIN_ALPHABET_LENGTH: Int = 16 + + static var SEP_DIV: Double = 3.5 + + static var GUARD_DIV: Double = 12 + + static var ALPHABET: String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + + static var SEPARATORS: String = "cfhistuCFHISTU" + } // MARK: Hashids protocol public protocol HashidsGenerator { - associatedtype Char - - func encode(_ value: Int64...) -> String? - - func encode(_ values: [Int64]) -> String? - - func encode(_ value: Int...) -> String? - - func encode(_ values: [Int]) -> String? - - func decode(_ value: String!) -> [Int] - - func decode(_ value: [Char]) -> [Int] - - func decode64(_ value: String) -> [Int64] - - func decode64(_ value: [Char]) -> [Int64] - + associatedtype Char + + func encode(_ value: Int64...) -> String? + + func encode(_ values: [Int64]) -> String? + + func encode(_ value: Int...) -> String? + + func encode(_ values: [Int]) -> String? + + func decode(_ value: String!) -> [Int] + + func decode(_ value: [Char]) -> [Int] + + func decode64(_ value: String) -> [Int64] + + func decode64(_ value: [Char]) -> [Int64] + } @@ -69,315 +76,317 @@ public typealias Hashids = Hashids_ // MARK: Hashids generic class open class Hashids_: HashidsGenerator where T:UnsignedInteger { - public typealias Char = T - - fileprivate var minHashLength: UInt - - fileprivate var alphabet: [Char] - - fileprivate var seps: [Char] - - fileprivate var salt: [Char] - - fileprivate var guards: [Char] - - public init(salt: String!, minHashLength: UInt = 0, alphabet: String? = nil) { - var _alphabet = (alphabet != nil) ? alphabet! : HashidsOptions.ALPHABET - var _seps = HashidsOptions.SEPARATORS - - self.minHashLength = minHashLength - self.guards = [Char]() - self.salt = salt.unicodeScalars.map() { - numericCast($0.value) - } - self.seps = _seps.unicodeScalars.map() { - numericCast($0.value) - } - self.alphabet = unique(_alphabet.unicodeScalars.map() { - numericCast($0.value) - }) - - self.seps = intersection(self.alphabet, self.seps) - self.alphabet = difference(self.alphabet, self.seps) - shuffle(&self.seps, self.salt) - - - let sepsLength = self.seps.count - let alphabetLength = self.alphabet.count - - if (0 == sepsLength) || (Double(alphabetLength) / Double(sepsLength) > HashidsOptions.SEP_DIV) { - - var newSepsLength = Int(ceil(Double(alphabetLength) / HashidsOptions.SEP_DIV)) - - if 1 == newSepsLength { - newSepsLength += 1 - } - - if newSepsLength > sepsLength { - let diff = self.alphabet.startIndex.advanced(by: newSepsLength - sepsLength) - let range = 0 ..< diff - self.seps += self.alphabet[range] - self.alphabet.removeSubrange(range) - } else { - let pos = self.seps.startIndex.advanced(by: newSepsLength) - self.seps.removeSubrange(pos + 1 ..< self.seps.count) - } - } - - shuffle(&self.alphabet, self.salt) - - let guard_i = Int(ceil(Double(alphabetLength) / HashidsOptions.GUARD_DIV)) - if alphabetLength < 3 { - let seps_guard = self.seps.startIndex.advanced(by: guard_i) - let range = 0 ..< seps_guard - self.guards += self.seps[range] - self.seps.removeSubrange(range) - } else { - let alphabet_guard = self.alphabet.startIndex.advanced(by: guard_i) - let range = 0 ..< alphabet_guard - self.guards += self.alphabet[range] - self.alphabet.removeSubrange(range) - } - } - - // MARK: public api - - open func encode(_ value: Int64...) -> String? { - return encode(value) + public typealias Char = T + + fileprivate var minHashLength: UInt + + fileprivate var alphabet: [Char] + + fileprivate var seps: [Char] + + fileprivate var salt: [Char] + + fileprivate var guards: [Char] + + public init(salt: String!, minHashLength: UInt = 0, alphabet: String? = nil) { + var _alphabet = (alphabet != nil) ? alphabet! : HashidsOptions.ALPHABET + var _seps = HashidsOptions.SEPARATORS + + self.minHashLength = minHashLength + self.guards = [Char]() + self.salt = salt.unicodeScalars.map() { + numericCast($0.value) } - - open func encode(_ values: [Int64]) -> String? { - return encode(values.map { Int($0) }) + self.seps = _seps.unicodeScalars.map() { + numericCast($0.value) } - - open func encode(_ value: Int...) -> String? { - return encode(value) + self.alphabet = unique(_alphabet.unicodeScalars.map() { + numericCast($0.value) + }) + + self.seps = intersection(self.seps, self.alphabet) + self.alphabet = difference(self.alphabet, self.seps) + shuffle(&self.seps, self.salt) + + + let sepsLength = self.seps.count + let alphabetLength = self.alphabet.count + + if (0 == sepsLength) || (Double(alphabetLength) / Double(sepsLength) > HashidsOptions.SEP_DIV) { + + var newSepsLength = Int(ceil(Double(alphabetLength) / HashidsOptions.SEP_DIV)) + + if 1 == newSepsLength { + newSepsLength += 1 + } + + if newSepsLength > sepsLength { + let diff = self.alphabet.startIndex.advanced(by: newSepsLength - sepsLength) + let range = 0 ..< diff + self.seps += self.alphabet[range] + self.alphabet.removeSubrange(range) + } else { + let pos = self.seps.startIndex.advanced(by: newSepsLength) + self.seps.removeSubrange(pos + 1 ..< self.seps.count) + } } - - open func encode(_ values: [Int]) -> String? { - let ret = _encode(values) - return ret.reduce(String(), { ( so, i) in - var so = so - let scalar: UInt32 = numericCast(i) - if let uniscalar = UnicodeScalar(scalar) { - so.append(String(describing: uniscalar)) - } - return so - }) + + shuffle(&self.alphabet, self.salt) + + let guard_i = Int(ceil(Double(alphabetLength) / HashidsOptions.GUARD_DIV)) + if alphabetLength < 3 { + let seps_guard = self.seps.startIndex.advanced(by: guard_i) + let range = 0 ..< seps_guard + self.guards += self.seps[range] + self.seps.removeSubrange(range) + } else { + let alphabet_guard = self.alphabet.startIndex.advanced(by: guard_i) + let range = 0 ..< alphabet_guard + self.guards += self.alphabet[range] + self.alphabet.removeSubrange(range) } - - open func decode(_ value: String!) -> [Int] { - let trimmed = value.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) - let hash: [Char] = trimmed.unicodeScalars.map() { - numericCast($0.value) - } - return self.decode(hash) + } + + // MARK: public api + + open func encode(_ value: Int64...) -> String? { + return encode(value) + } + + open func encode(_ values: [Int64]) -> String? { + return encode(values.map { Int($0) }) + } + + open func encode(_ value: Int...) -> String? { + return encode(value) + } + + open func encode(_ values: [Int]) -> String? { + let ret = _encode(values) + return ret.reduce(String(), { ( so, i) in + var so = so + let scalar: UInt32 = numericCast(i) + if let uniscalar = UnicodeScalar(scalar) { + so.append(String(describing: uniscalar)) + } + return so + }) + } + + open func decode(_ value: String!) -> [Int] { + let trimmed = value.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) + let hash: [Char] = trimmed.unicodeScalars.map() { + numericCast($0.value) } - - open func decode(_ value: [Char]) -> [Int] { - return self._decode(value) + return self.decode(hash) + } + + open func decode(_ value: [Char]) -> [Int] { + return self._decode(value) + } + + open func decode64(_ value: String) -> [Int64] { + return self.decode(value).map { Int64($0) } + } + + open func decode64(_ value: [Char]) -> [Int64] { + return self.decode(value).map { Int64($0) } + } + + // MARK: private funcitons + fileprivate func _encode(_ numbers: [Int]) -> [Char] { + var alphabet = self.alphabet + var numbers_hash_int = 0 + + for (index, value) in numbers.enumerated() { + numbers_hash_int += (value % (index + 100)) } - - open func decode64(_ value: String) -> [Int64] { - return self.decode(value).map { Int64($0) } + + let lottery = alphabet[numbers_hash_int % alphabet.count] + var hash = [lottery] + + var lsalt = [Char]() + let (lsaltARange, lsaltRange) = _saltify(&lsalt, lottery, alphabet) + + for (index, value) in numbers.enumerated() { + shuffle(&alphabet, lsalt, lsaltRange) + let lastIndex = hash.endIndex + _hash(&hash, value, alphabet) + + if index + 1 < numbers.count { + let number = value % (numericCast(hash[lastIndex]) + index) + let seps_index = number % self.seps.count + hash.append(self.seps[seps_index]) + } + + lsalt.replaceSubrange(lsaltARange, with: alphabet) } - - open func decode64(_ value: [Char]) -> [Int64] { - return self.decode(value).map { Int64($0) } + + let minLength: Int = numericCast(self.minHashLength) + + if hash.count < minLength { + let guard_index = (numbers_hash_int + numericCast(hash[0])) % self.guards.count + let guard_t = self.guards[guard_index] + hash.insert(guard_t, at: 0) + + if hash.count < minLength { + let guard_index = (numbers_hash_int + numericCast(hash[2])) % self.guards.count + let guard_t = self.guards[guard_index] + hash.append(guard_t) + } } - - // MARK: private funcitons - fileprivate func _encode(_ numbers: [Int]) -> [Char] { - var alphabet = self.alphabet - var numbers_hash_int = 0 - - for (index, value) in numbers.enumerated() { - numbers_hash_int += (value % (index + 100)) - } - - let lottery = alphabet[numbers_hash_int % alphabet.count] - var hash = [lottery] - - var lsalt = [Char]() - let (lsaltARange, lsaltRange) = _saltify(&lsalt, lottery, alphabet) - - for (index, value) in numbers.enumerated() { - shuffle(&alphabet, lsalt, lsaltRange) - let lastIndex = hash.endIndex - _hash(&hash, value, alphabet) - - if index + 1 < numbers.count { - let number = value % (numericCast(hash[lastIndex]) + index) - let seps_index = number % self.seps.count - hash.append(self.seps[seps_index]) - } - - lsalt.replaceSubrange(lsaltARange, with: alphabet) - } - - let minLength: Int = numericCast(self.minHashLength) - - if hash.count < minLength { - let guard_index = (numbers_hash_int + numericCast(hash[0])) % self.guards.count - let guard_t = self.guards[guard_index] - hash.insert(guard_t, at: 0) - - if hash.count < minLength { - let guard_index = (numbers_hash_int + numericCast(hash[2])) % self.guards.count - let guard_t = self.guards[guard_index] - hash.append(guard_t) - } - } - - let half_length = alphabet.count >> 1 - while hash.count < minLength { - shuffle(&alphabet, alphabet) - let lrange = Range(0 ..< half_length) - let rrange = Range(half_length ..< (alphabet.count)) - let alphabet_right = alphabet[rrange] - let alphabet_left = alphabet[lrange] - hash = Array(alphabet_right) + hash + Array(alphabet_left) - - let excess = hash.count - minLength - if excess > 0 { - let start = excess >> 1 - hash = [Char](hash[start ..< (start + minLength)]) - } - } - - return hash + + let half_length = alphabet.count >> 1 + while hash.count < minLength { + shuffle(&alphabet, alphabet) + let lrange = 0 ..< half_length + let rrange = half_length ..< (alphabet.count) + let alphabet_right = alphabet[rrange] + let alphabet_left = alphabet[lrange] + hash = Array(alphabet_right) + hash + Array(alphabet_left) + + let excess = hash.count - minLength + if excess > 0 { + let start = excess >> 1 + hash = [Char](hash[start ..< (start + minLength)]) + } } - - fileprivate func _decode(_ hash: [Char]) -> [Int] { - var ret = [Int]() - - var alphabet = self.alphabet - - var hashes = hash.split(maxSplits: hash.count, omittingEmptySubsequences: false) { - contains(self.guards, $0) - } - let hashesCount = hashes.count, i = ((hashesCount == 2) || (hashesCount == 3)) ? 1 : 0 - let hash = hashes[i] - let hashStartIndex = hash.startIndex - - if hash.count > 0 { - let lottery = hash[hashStartIndex] - let valuesHashes = hash[(hashStartIndex + 1) ..< (hashStartIndex + hash.count)] - - let valueHashes = valuesHashes.split(maxSplits: valuesHashes.count, omittingEmptySubsequences: false) { - contains(self.seps, $0) - } - var lsalt = [Char]() - let (lsaltARange, lsaltRange) = _saltify(&lsalt, lottery, alphabet) - - for subHash in valueHashes { - shuffle(&alphabet, lsalt, lsaltRange) - ret.append(self._unhash(subHash, alphabet)) - lsalt.replaceSubrange(lsaltARange, with: alphabet) - } - } - - return ret + + return hash + } + + fileprivate func _decode(_ hash: [Char]) -> [Int] { + var ret = [Int]() + + var alphabet = self.alphabet + + var hashes = hash.split(maxSplits: hash.count, omittingEmptySubsequences: false) { + contains(self.guards, $0) } - - fileprivate func _hash(_ hash: inout [Char], _ number: Int, _ alphabet: [Char]) { - var number = number - let length = alphabet.count, index = hash.count - repeat { - hash.insert(alphabet[number % length], at: index) - number = number / length - } while (number != 0) + let hashesCount = hashes.count, i = ((hashesCount == 2) || (hashesCount == 3)) ? 1 : 0 + let hash = hashes[i] + let hashStartIndex = hash.startIndex + + if hash.count > 0 { + let lottery = hash[hashStartIndex] + let valuesHashes = hash[(hashStartIndex + 1) ..< (hashStartIndex + hash.count)] + + let valueHashes = valuesHashes.split(maxSplits: valuesHashes.count, omittingEmptySubsequences: false) { + contains(self.seps, $0) + } + var lsalt = [Char]() + let (lsaltARange, lsaltRange) = _saltify(&lsalt, lottery, alphabet) + + for subHash in valueHashes { + shuffle(&alphabet, lsalt, lsaltRange) + ret.append(self._unhash(subHash, alphabet)) + lsalt.replaceSubrange(lsaltARange, with: alphabet) + } } - - fileprivate func _unhash(_ hash: U, _ alphabet: [Char]) -> Int where U.Index == Int, U.Iterator.Element == Char { - var value: Double = 0 - - var hashLength: Int = numericCast(hash.count) - if hashLength > 0 { - let alphabetLength = alphabet.count - value = hash.reduce(0) { - value, token in - var tokenValue = 0.0 - if let token_index = alphabet.index(of: token as Char) { - hashLength = hashLength - 1 - let mul = pow(Double(alphabetLength), Double(hashLength)) - tokenValue = Double(token_index) * mul - } - return value + tokenValue - } + + return ret + } + + fileprivate func _hash(_ hash: inout [Char], _ number: Int, _ alphabet: [Char]) { + var number = number + let length = alphabet.count, index = hash.count + repeat { + hash.insert(alphabet[number % length], at: index) + number = number / length + } while (number != 0) + } + + fileprivate func _unhash(_ hash: U, _ alphabet: [Char]) -> Int where U.Index == Int, U.Iterator.Element == Char { + var value: Double = 0 + + var hashLength: Int = numericCast(hash.count) + if hashLength > 0 { + let alphabetLength = alphabet.count + value = hash.reduce(0) { + value, token in + var tokenValue = 0.0 + if let token_index = alphabet.firstIndex(of: token as Char) { + hashLength = hashLength - 1 + let mul = pow(Double(alphabetLength), Double(hashLength)) + tokenValue = Double(token_index) * mul } - - return Int(trunc(value)) + return value + tokenValue + } } - - fileprivate func _saltify(_ salt: inout [Char], _ lottery: Char, _ alphabet: [Char]) -> (Range, Range) { - salt.append(lottery) - salt = salt + self.salt - salt = salt + alphabet - let lsaltARange = (self.salt.count + 1) ..< salt.count - let lsaltRange = 0 ..< alphabet.count - return (Range(lsaltARange), Range(lsaltRange)) - } - + + return Int(trunc(value)) + } + + fileprivate func _saltify(_ salt: inout [Char], _ lottery: Char, _ alphabet: [Char]) -> (Range, Range) { + salt.append(lottery) + salt = salt + self.salt + salt = salt + alphabet + let lsaltARange = (self.salt.count + 1) ..< salt.count + let lsaltRange = 0 ..< alphabet.count + return (lsaltARange, lsaltRange) + } + } // MARK: Internal functions internal func contains(_ a: T, _ e: T.Iterator.Element) -> Bool where T.Iterator.Element:Equatable { - return (a.index(of: e) != nil) + return (a.firstIndex(of: e) != nil) } internal func transform(_ a: T, _ b: T, _ cmpr: (inout Array, T, T, T.Iterator.Element) -> Void) -> [T.Iterator.Element] where T.Iterator.Element:Equatable { - typealias U = T.Iterator.Element - var c = [U]() - for i in a { - cmpr(&c, a, b, i) - } - return c + typealias U = T.Iterator.Element + var c = [U]() + for i in a { + cmpr(&c, a, b, i) + } + return c } internal func unique(_ a: T) -> [T.Iterator.Element] where T.Iterator.Element:Equatable { - return transform(a, a) { - ( c, a, b, e) in - if !contains(c, e) { - c.append(e) - } + return transform(a, a) { + ( c, a, b, e) in + if !contains(c, e) { + c.append(e) } + } } internal func intersection(_ a: T, _ b: T) -> [T.Iterator.Element] where T.Iterator.Element:Equatable { - return transform(a, b) { - ( c, a, b, e) in - if contains(b, e) { - c.append(e) - } + return transform(a, b) { + ( c, a, b, e) in + if contains(b, e) { + c.append(e) } + } } internal func difference(_ a: T, _ b: T) -> [T.Iterator.Element] where T.Iterator.Element:Equatable { - return transform(a, b) { - ( c, a, b, e) in - if !contains(b, e) { - c.append(e) - } + return transform(a, b) { + ( c, a, b, e) in + if !contains(b, e) { + c.append(e) } + } } internal func shuffle(_ source: inout T, _ salt: U) where T.Index == Int, T.Iterator.Element:UnsignedInteger, T.Iterator.Element == U.Iterator.Element, T.Index == U.Index { - let saltCount: Int = numericCast(salt.count) - shuffle(&source, salt, 0 ..< saltCount) + let saltCount: Int = numericCast(salt.count) + shuffle(&source, salt, 0 ..< saltCount) } internal func shuffle(_ source: inout T, _ salt: U, _ saltRange: Range) where T.Index == Int, T.Iterator.Element:UnsignedInteger, T.Iterator.Element == U.Iterator.Element, T.Index == U.Index { - let sidx0 = saltRange.lowerBound, scnt = (saltRange.upperBound - saltRange.lowerBound) - var sidx: Int = numericCast(source.count) - 1, v = 0, _p = 0 - while sidx > 0 { - v = v % scnt - let _i: Int = numericCast(salt[sidx0 + v]) - _p += _i - let _j: Int = (_i + v + _p) % sidx - let tmp = source[sidx] - source[sidx] = source[_j] - source[_j] = tmp - v += 1 - sidx = sidx - 1 - } + let sidx0 = saltRange.lowerBound, scnt = (saltRange.upperBound - saltRange.lowerBound) + guard scnt != 0 else { return } + + var sidx: Int = numericCast(source.count) - 1, v = 0, _p = 0 + while sidx > 0 { + v = v % scnt + let _i: Int = numericCast(salt[sidx0 + v]) + _p += _i + let _j: Int = (_i + v + _p) % sidx + let tmp = source[sidx] + source[sidx] = source[_j] + source[_j] = tmp + v += 1 + sidx = sidx - 1 + } } diff --git a/templates/SwiftProject/Swift5/Package.swift b/templates/SwiftProject/Swift5/Package.swift new file mode 100644 index 0000000..94ecfad --- /dev/null +++ b/templates/SwiftProject/Swift5/Package.swift @@ -0,0 +1,14 @@ +// swift-tools-version:5.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "{{appName}}", + dependencies: [ + .package(url: "https://github.com/noppoMan/HexavilleFramework.git", .upToNextMajor(from: "1.0.0-rc.4")), + ], + targets: [ + .target(name: "{{appName}}", dependencies: ["HexavilleFramework"]), + ] +) From 7cb89f2545d69a6bf9b5ef8d934c9dc6f63782b6 Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 02:32:28 +0900 Subject: [PATCH 02/10] remove URLSession part --- templates/SwiftProject/Sources/main.swift | 37 ----------------------- 1 file changed, 37 deletions(-) diff --git a/templates/SwiftProject/Sources/main.swift b/templates/SwiftProject/Sources/main.swift index d4f6418..da56276 100644 --- a/templates/SwiftProject/Sources/main.swift +++ b/templates/SwiftProject/Sources/main.swift @@ -15,38 +15,6 @@ func requestDetail(for request: Request) throws -> Data { return try JSONSerialization.data(withJSONObject: json, options: []) } - -#if os(Linux) -let _urlSessionShared = URLSession(configuration: URLSessionConfiguration(), delegate: nil, delegateQueue: nil) -extension URLSession { - static var shared: URLSession { - return _urlSessionShared - } -} -#endif - -extension URLSession { - func resumeSync(with url: URL) throws -> Data { - let semaphore = DispatchSemaphore(value: 0) - var error: Error? - var data: Data? - - let task = self.dataTask(with: url) { _data, response, _error in - error = _error - data = _data - semaphore.signal() - } - - task.resume() - semaphore.wait() - - if let error = error { - throw error - } - return data! - } -} - let app = HexavilleFramework() var router = Router() @@ -83,11 +51,6 @@ router.use(.POST, "/hello/{id}") { request, context in return try Response(status: .created, headers: ["Content-Type": "application/json"], body: requestDetail(for: request)) } -router.use(.GET, "/random_img") { request, context in - let data = try URLSession.shared.resumeSync(with: URL(string: "http://lorempixel.com/400/200/")!) - return Response(headers: ["Content-Type": "image/png"], body: data.base64EncodedData()) -} - app.use(router) app.catch { error in From 8c6f0fcbfbf2fe9e2209fcd655cd72ec1671bc95 Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 14:55:13 +0900 Subject: [PATCH 03/10] tmp --- Scripts/build-swift.sh | 20 ++++++++++++++++---- Scripts/zip.sh | 3 +++ Sources/Hexaville/main.swift | 2 +- templates/.dockerignore | 1 + 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Scripts/build-swift.sh b/Scripts/build-swift.sh index 0efe45a..faee29c 100755 --- a/Scripts/build-swift.sh +++ b/Scripts/build-swift.sh @@ -5,13 +5,25 @@ set -e DEST=${DEST}/${BUILD_CONFIGURATION} swift package update swift build -c ${BUILD_CONFIGURATION} -cp -r /${SWIFTFILE}/usr/lib/swift/linux/*.so $DEST -cp /usr/lib/x86_64-linux-gnu/libicudata.so $DEST/libicudata.so.52 + +# swift libraries +rm $DEST/libicudataswift.so.61 $DEST/libicui18nswift.so.61 $DEST/libicuucswift.so.61 +cp -rL /${SWIFTFILE}/usr/lib/swift/linux/*.so $DEST +mv $DEST/libicudataswift.so $DEST/libicudataswift.so.61 +mv $DEST/libicui18nswift.so $DEST/libicui18nswift.so.61 +mv $DEST/libicuucswift.so $DEST/libicuucswift.so.61 + +# other sysytem libraries cp /usr/lib/x86_64-linux-gnu/libicui18n.so $DEST/libicui18n.so.52 cp /usr/lib/x86_64-linux-gnu/libicuuc.so $DEST/libicuuc.so.52 cp /usr/lib/x86_64-linux-gnu/libbsd.so $DEST/libbsd.so.0 cp /lib/x86_64-linux-gnu/libssl.so.1.0.0 $DEST/libssl.so.1.0.0 cp /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 $DEST/libcrypto.so.1.0.0 -id -u $VOLUME_USER &>/dev/null || useradd -ms /bin/bash $VOLUME_USER -chown -R $VOLUME_USER:$VOLUME_GROUP $DEST +if [ -z "${VOLUME_USER}" ] && [ -z "${VOLUME_GROUP}" ]; then + echo "swift build is finished." +else + id -u $VOLUME_USER &>/dev/null || useradd -ms /bin/bash $VOLUME_USER + chown -R $VOLUME_USER:$VOLUME_GROUP $DEST + echo "swift build is finished." +fi diff --git a/Scripts/zip.sh b/Scripts/zip.sh index 537da33..230cec2 100755 --- a/Scripts/zip.sh +++ b/Scripts/zip.sh @@ -7,6 +7,9 @@ DEST=.build/${BUILD_CONFIGURATION} swift package update swift build -c ${BUILD_CONFIGURATION} cp -r /${SWIFTFILE}/usr/lib/swift/linux/*.so $DEST +mv $DEST/libicudataswift.so $DEST/libicudataswift.so.61 +mv $DEST/libicui18nswift.so $DEST/libicui18nswift.so.61 +mv $DEST/libicuucswift.so $DEST/libicuucswift.so.61 cp /usr/lib/x86_64-linux-gnu/libicudata.so $DEST/libicudata.so.52 cp /usr/lib/x86_64-linux-gnu/libicui18n.so $DEST/libicui18n.so.52 cp /usr/lib/x86_64-linux-gnu/libicuuc.so $DEST/libicuuc.so.52 diff --git a/Sources/Hexaville/main.swift b/Sources/Hexaville/main.swift index 2eddb88..793c30b 100644 --- a/Sources/Hexaville/main.swift +++ b/Sources/Hexaville/main.swift @@ -133,7 +133,7 @@ class BuildCommand: Command { print("Your application package was successfully created at \(package.destination)") print("next step.") print("") - print(" serverless deploy --stage staging or production") + print(" serverless deploy --stage your-stage-name") print("") print("guide: https://serverless.com/framework/docs/providers/aws/guide/deploying/") print("###########################################################################") diff --git a/templates/.dockerignore b/templates/.dockerignore index 4e05543..f809d20 100644 --- a/templates/.dockerignore +++ b/templates/.dockerignore @@ -1,2 +1,3 @@ .build .git +__docker_shared \ No newline at end of file From 28b7c381743d9128f7be9cce0176462a18b4a21f Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 15:25:02 +0900 Subject: [PATCH 04/10] update default HexavilleFramework version to 1.0.0 --- templates/SwiftProject/Swift5/Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/SwiftProject/Swift5/Package.swift b/templates/SwiftProject/Swift5/Package.swift index 94ecfad..8d0bb0e 100644 --- a/templates/SwiftProject/Swift5/Package.swift +++ b/templates/SwiftProject/Swift5/Package.swift @@ -6,7 +6,7 @@ import PackageDescription let package = Package( name: "{{appName}}", dependencies: [ - .package(url: "https://github.com/noppoMan/HexavilleFramework.git", .upToNextMajor(from: "1.0.0-rc.4")), + .package(url: "https://github.com/noppoMan/HexavilleFramework.git", .upToNextMajor(from: "1.0.0")), ], targets: [ .target(name: "{{appName}}", dependencies: ["HexavilleFramework"]), From c08388f54454aabedbad36e1495c6a4e97e745da Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 15:54:18 +0900 Subject: [PATCH 05/10] check file exists before rm --- Scripts/build-swift.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Scripts/build-swift.sh b/Scripts/build-swift.sh index faee29c..6a35870 100755 --- a/Scripts/build-swift.sh +++ b/Scripts/build-swift.sh @@ -7,7 +7,15 @@ swift package update swift build -c ${BUILD_CONFIGURATION} # swift libraries -rm $DEST/libicudataswift.so.61 $DEST/libicui18nswift.so.61 $DEST/libicuucswift.so.61 +if [ -f "$DEST/libicudataswift.so.61" ]; then + rm $DEST/libicudataswift.so.61 +fi +if [ -f "$DEST/libicui18nswift.so.61" ]; then + rm $DEST/libicui18nswift.so.61 +fi +if [ -f "$DEST/libicuucswift.so.61" ]; then + rm $DEST/libicuucswift.so.61 +fi cp -rL /${SWIFTFILE}/usr/lib/swift/linux/*.so $DEST mv $DEST/libicudataswift.so $DEST/libicudataswift.so.61 mv $DEST/libicui18nswift.so $DEST/libicui18nswift.so.61 From f519add6d192dc29a81cd26433b6bc8c976eb6fa Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 15:56:16 +0900 Subject: [PATCH 06/10] retry swift build when get the rename error from CNIOBoringSSL --- .../DockerBuildEnvironmentProvider.swift | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Sources/HexavilleCore/SwiftBuilder/SwiftBuildEnvironmentProvider/DockerBuildEnvironmentProvider.swift b/Sources/HexavilleCore/SwiftBuilder/SwiftBuildEnvironmentProvider/DockerBuildEnvironmentProvider.swift index c152cb3..701f0a7 100644 --- a/Sources/HexavilleCore/SwiftBuilder/SwiftBuildEnvironmentProvider/DockerBuildEnvironmentProvider.swift +++ b/Sources/HexavilleCore/SwiftBuilder/SwiftBuildEnvironmentProvider/DockerBuildEnvironmentProvider.swift @@ -130,10 +130,26 @@ struct DockerBuildEnvironmentProvider: SwiftBuildEnvironmentProvider { ] #endif - _ = try Spawn(args: ["/usr/bin/env", "docker", "run"] + dockerRunOpts) { - print($0, separator: "", terminator: "") + do { + try self.spawnDocker(dockerRunOpts) + } catch SpawnError.terminatedWithStatus(let errorCode) { + switch errorCode { + case 256: + // retry swift build when get the rename error from CNIOBoringSSL + try self.spawnDocker(dockerRunOpts) + default: + throw SpawnError.terminatedWithStatus(errorCode) + } + } catch { + throw error } return BuildResult(destination: sharedDir+"/\(config.swift.buildMode)", dockerTag: tag) } + + private func spawnDocker(_ dockerRunOpts: [String]) throws { + _ = try Spawn(args: ["/usr/bin/env", "docker", "run"] + dockerRunOpts) { + print($0, separator: "", terminator: "") + } + } } From 597101b4140c492760e948fc1500108cfc73b1d2 Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 16:12:02 +0900 Subject: [PATCH 07/10] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1964b64..6a81a72 100644 --- a/README.md +++ b/README.md @@ -78,17 +78,17 @@ hexaville generate Hello --dest /path/to/your/app ### swift-tools-version You can specify swift-tools-version for the new project with `--swift-tools-version` option. -Current default tool version is `4.0` +Current default tool version is `5.1` If the tool version is higher than 3.1, layouts and definiations of `Package.swift` are refined. **e.g.** ```sh -# swift.version will be 4.2 +# swift.version will be 5.1 hexaville generate Hello -# swift.version will be 3.1 -hexaville generate Hello --swift-tools-version 3.1 +# swift.version will be 5.0 +hexaville generate Hello --swift-tools-version 5.0 # swift.version will be swift-4.0-DEVELOPMENT-SNAPSHOT-2017-08-04-a hexaville generate Hello --swift-tools-version swift-4.0-DEVELOPMENT-SNAPSHOT-2017-08-04-a @@ -240,12 +240,12 @@ See: https://serverless.com/framework/docs/providers/aws/guide/functions#vpc-con You can configure swift versioning and build configuration in `swift` directive -* default swift version is `4.2` +* default swift version is `5.1` * default build configuration is `debug` ```yaml swift: - version: 4.2 #format should be major.minor.[patch] or valid SWIFT DEVELOPMENT-SNAPSHOT name + version: 5.1 #format should be major.minor.[patch] or valid SWIFT DEVELOPMENT-SNAPSHOT name buildOptions: configuration: release ``` From bf9cd1b5f3ebaa9c6ab9f109a040a864749065eb Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 16:13:50 +0900 Subject: [PATCH 08/10] CI with swift 5.1 --- Scripts/install-swift.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/install-swift.sh b/Scripts/install-swift.sh index 5352e2f..79a41cb 100644 --- a/Scripts/install-swift.sh +++ b/Scripts/install-swift.sh @@ -2,7 +2,7 @@ set -e -VERSION="4.2" +VERSION="5.1" # Determine OS UNAME=`uname`; From 0208a740f074e41b776f6e66bbe21f69a730066c Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 16:20:32 +0900 Subject: [PATCH 09/10] xcode11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3bf7dca..2750765 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ os: language: generic sudo: required dist: trusty -osx_image: xcode10.1 +osx_image: xcode11 install: - source Scripts/install-swift.sh From 62892d80d7634441d972417920bd7584cdcf4368 Mon Sep 17 00:00:00 2001 From: noppoman Date: Fri, 27 Sep 2019 16:29:03 +0900 Subject: [PATCH 10/10] remove SwiftyJSON from dependencies --- Package.resolved | 9 --------- Package.swift | 2 -- Sources/Hexaville/main.swift | 1 - 3 files changed, 12 deletions(-) diff --git a/Package.resolved b/Package.resolved index eb8de9f..d25abd9 100644 --- a/Package.resolved +++ b/Package.resolved @@ -10,15 +10,6 @@ "version": "5.3.2" } }, - { - "package": "SwiftyJSON", - "repositoryURL": "https://github.com/SwiftyJSON/SwiftyJSON.git", - "state": { - "branch": null, - "revision": "2b6054efa051565954e1d2b9da831680026cd768", - "version": "5.0.0" - } - }, { "package": "Yams", "repositoryURL": "https://github.com/jpsim/Yams.git", diff --git a/Package.swift b/Package.swift index 3263df8..b7f05f8 100644 --- a/Package.swift +++ b/Package.swift @@ -8,13 +8,11 @@ let package = Package( .executable(name: "hexaville", targets: ["Hexaville"]) ], dependencies: [ - .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", .upToNextMajor(from: "5.0.0")), .package(url: "https://github.com/jakeheis/SwiftCLI.git", .upToNextMajor(from: "5.0.0")), .package(url: "https://github.com/jpsim/Yams.git", .upToNextMajor(from: "2.0.0")) ], targets: [ .target(name: "HexavilleCore", dependencies: [ - "SwiftyJSON", "SwiftCLI", "Yams" ]), diff --git a/Sources/Hexaville/main.swift b/Sources/Hexaville/main.swift index 793c30b..6fe34d5 100644 --- a/Sources/Hexaville/main.swift +++ b/Sources/Hexaville/main.swift @@ -5,7 +5,6 @@ import Darwin.C #endif import Foundation -import SwiftyJSON import SwiftCLI import Yams import HexavilleCore