Skip to content

Commit 574157f

Browse files
committed
Properly compute hashes on Linux by using swift-crypto.
Remove `JSONPointer` and `toJSON`. Remove CryptoSwift dependency. Increase minimum macOS version requirement to 10.15 (Catalina). Increase version number in `main.swift` to 3.0.0. Update README.
1 parent f90e5a1 commit 574157f

File tree

6 files changed

+48
-36
lines changed

6 files changed

+48
-36
lines changed

Package.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,27 @@ import PackageDescription
55

66
let package = Package(
77
name: "LFSPointers",
8-
platforms: [.macOS(.v10_13)],
8+
platforms: [.macOS(.v10_15)],
99
products: [
1010
.executable(name: "LFSPointers", targets: ["LFSPointersExecutable"]),
1111
.library(name: "LFSPointersKit", targets: ["LFSPointersKit"])
1212
],
1313
dependencies: [
1414
// Dependencies declare other packages that this package depends on.
15-
.package(url: "https://github.com/krzyzanowskim/CryptoSwift", .exact("1.3.2")),
1615
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "0.3.1"),
1716
.package(url: "https://github.com/onevcat/Rainbow", from: "3.1.5"),
18-
.package(url: "https://github.com/JohnSundell/Files", from: "4.1.1")
17+
.package(url: "https://github.com/JohnSundell/Files", from: "4.1.1"),
18+
.package(url: "https://github.com/apple/swift-crypto.git", from: "1.1.2")
1919
],
2020
targets: [
2121
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
2222
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
2323
.target(
2424
name: "LFSPointersKit",
25-
dependencies: ["Files", "CryptoSwift"]
25+
dependencies: [
26+
"Files",
27+
.product(name: "Crypto", package: "swift-crypto")
28+
]
2629
),
2730
.target(
2831
name: "LFSPointersExecutable",

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ $ LFSPointers --generate-completion-script bash > ~/.bash_completions/LFSPointer
153153
Add this to the `dependencies` array in `Package.swift`:
154154
155155
```swift
156-
.package(url: "https://github.com/LebJe/LFSPointers.git", from: “2.0.0”)
156+
.package(url: "https://github.com/LebJe/LFSPointers.git", from: “3.0.0”)
157157
```
158158
. Also add this to the `targets` array in the aforementioned file:
159159
@@ -241,7 +241,7 @@ let pointer = try LFSPointer(...)
241241
try JSONEncoder().encode(pointer)
242242
```
243243
244-
and to convert an array of tuples consisting of filename, file path, and pointer:
244+
and to convert an array of `LFSPointer`s:
245245
246246
```swift
247247
let pointers = try LFSPointer.pointers(...)

Sources/LFSPointersExecutable/main.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct LFSPointersCommand: ParsableCommand {
3232
commandName: "LFSPointers",
3333
abstract: "Replaces large files in a Git repository directory with Git LFS pointers.",
3434
discussion: "JSON STRUCTURE:\n\(jsonStructure)",
35-
version: "2.0.0"
35+
version: "3.0.0"
3636
)
3737

3838
@Flag(name: .shortAndLong, help: "Whether to display verbose output.")

Sources/LFSPointersKit/Extensions.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,22 @@ public extension NSRegularExpression {
1414
firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)) != nil
1515
}
1616
}
17+
18+
// From: https://github.com/apple/swift-crypto/blob/8f4bfa5bc1951440c15710e9e893721aa4b2765c/Sources/crypto-shasum/main.swift#L73
19+
public extension String {
20+
init(hexEncoding data: Data) {
21+
self = data.map { byte in
22+
let s = String(byte, radix: 16)
23+
switch s.count {
24+
case 0:
25+
return "00"
26+
case 1:
27+
return "0" + s
28+
case 2:
29+
return s
30+
default:
31+
fatalError("Weirdly hex encoded byte")
32+
}
33+
}.joined()
34+
}
35+
}

Sources/LFSPointersKit/Pointers.swift

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99
import Files
10-
import CryptoSwift
10+
import Crypto
1111

1212
/// Represents a Git LFS pointer for a file.
1313
///
@@ -68,11 +68,25 @@ public struct LFSPointer: Codable, Equatable, Hashable {
6868
let file = try File(path: path.path)
6969

7070
self.version = "https://git-lfs.github.com/spec/v1"
71-
72-
self.oid = try FileHandle(forReadingFrom: file.url).availableData.sha256().toHexString()
71+
72+
let handle = try FileHandle(forReadingFrom: file.url)
73+
74+
let readSize = 8192
75+
var hasher = SHA256()
76+
77+
while true {
78+
let data = handle.readData(ofLength: readSize)
79+
if data.count == 0 {
80+
break
81+
}
82+
83+
hasher.update(data: data)
84+
}
85+
86+
self.oid = String(hexEncoding: Data(hasher.finalize()))
7387

7488
let attr = try FileManager.default.attributesOfItem(atPath: file.path)
75-
89+
7690
self.size = (attr[.size] as? Int) ?? 0
7791

7892
self.filename = file.name
@@ -259,28 +273,6 @@ extension LFSPointer: CustomDebugStringConvertible {
259273
}
260274
}
261275

262-
public struct JSONPointer: Codable {
263-
public let filename: String
264-
public let filePath: String
265-
public let pointer: LFSPointer
266-
}
267-
268-
/// Generates a string containing `JSON`.
269-
/// - Parameter array: No description.
270-
/// - Returns: A `String` containing `JSON`.
271-
public func toJSON(array: [JSONPointer], jsonFormat: JSONEncoder.OutputFormatting = .init()) -> String {
272-
273-
let encoder = JSONEncoder()
274-
275-
encoder.outputFormatting = jsonFormat
276-
277-
let jsonBytes = (try? encoder.encode(array)) ?? Data()
278-
279-
let jsonString = String(data: jsonBytes, encoding: .utf8) ?? ""
280-
281-
return jsonString
282-
}
283-
284276
public extension Array where Self.Element == LFSPointer {
285277
/// Converts and `Array` of `LFSPointer`s to `JSON`.
286278
/// - Parameter jsonFormat: The format of the generated `JSON`.

Tests/LFSPointersTests/LFSPointersTests.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ final class LFSPointersTests: XCTestCase {
88

99
func testConvertFileToPointer() throws {
1010
let pointer = try LFSPointer(fromFile: resources.file(named: "foo.txt").url)
11-
12-
#if os(macOS)
11+
1312
XCTAssertEqual(667684, pointer.size)
1413
XCTAssertEqual("802cd848ada6f6f7177bc4bd0952e2c3a5c7378757899b1ed16c0f1a243eb930", pointer.oid)
15-
#endif
1614
}
1715

1816
func testRecursivelyGeneratePointersForFilesInSubdirectories() throws {

0 commit comments

Comments
 (0)