Skip to content

Commit

Permalink
Properly compute hashes on Linux by using swift-crypto.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
LebJe committed Dec 4, 2020
1 parent f90e5a1 commit 574157f
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 36 deletions.
11 changes: 7 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,27 @@ import PackageDescription

let package = Package(
name: "LFSPointers",
platforms: [.macOS(.v10_13)],
platforms: [.macOS(.v10_15)],
products: [
.executable(name: "LFSPointers", targets: ["LFSPointersExecutable"]),
.library(name: "LFSPointersKit", targets: ["LFSPointersKit"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/krzyzanowskim/CryptoSwift", .exact("1.3.2")),
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "0.3.1"),
.package(url: "https://github.com/onevcat/Rainbow", from: "3.1.5"),
.package(url: "https://github.com/JohnSundell/Files", from: "4.1.1")
.package(url: "https://github.com/JohnSundell/Files", from: "4.1.1"),
.package(url: "https://github.com/apple/swift-crypto.git", from: "1.1.2")
],
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 which this package depends on.
.target(
name: "LFSPointersKit",
dependencies: ["Files", "CryptoSwift"]
dependencies: [
"Files",
.product(name: "Crypto", package: "swift-crypto")
]
),
.target(
name: "LFSPointersExecutable",
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ $ LFSPointers --generate-completion-script bash > ~/.bash_completions/LFSPointer
Add this to the `dependencies` array in `Package.swift`:
```swift
.package(url: "https://github.com/LebJe/LFSPointers.git", from: “2.0.0”)
.package(url: "https://github.com/LebJe/LFSPointers.git", from: “3.0.0”)
```
. Also add this to the `targets` array in the aforementioned file:
Expand Down Expand Up @@ -241,7 +241,7 @@ let pointer = try LFSPointer(...)
try JSONEncoder().encode(pointer)
```
and to convert an array of tuples consisting of filename, file path, and pointer:
and to convert an array of `LFSPointer`s:
```swift
let pointers = try LFSPointer.pointers(...)
Expand Down
2 changes: 1 addition & 1 deletion Sources/LFSPointersExecutable/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct LFSPointersCommand: ParsableCommand {
commandName: "LFSPointers",
abstract: "Replaces large files in a Git repository directory with Git LFS pointers.",
discussion: "JSON STRUCTURE:\n\(jsonStructure)",
version: "2.0.0"
version: "3.0.0"
)

@Flag(name: .shortAndLong, help: "Whether to display verbose output.")
Expand Down
19 changes: 19 additions & 0 deletions Sources/LFSPointersKit/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,22 @@ public extension NSRegularExpression {
firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)) != nil
}
}

// From: https://github.com/apple/swift-crypto/blob/8f4bfa5bc1951440c15710e9e893721aa4b2765c/Sources/crypto-shasum/main.swift#L73
public extension String {
init(hexEncoding data: Data) {
self = data.map { byte in
let s = String(byte, radix: 16)
switch s.count {
case 0:
return "00"
case 1:
return "0" + s
case 2:
return s
default:
fatalError("Weirdly hex encoded byte")
}
}.joined()
}
}
44 changes: 18 additions & 26 deletions Sources/LFSPointersKit/Pointers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation
import Files
import CryptoSwift
import Crypto

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

self.version = "https://git-lfs.github.com/spec/v1"

self.oid = try FileHandle(forReadingFrom: file.url).availableData.sha256().toHexString()

let handle = try FileHandle(forReadingFrom: file.url)

let readSize = 8192
var hasher = SHA256()

while true {
let data = handle.readData(ofLength: readSize)
if data.count == 0 {
break
}

hasher.update(data: data)
}

self.oid = String(hexEncoding: Data(hasher.finalize()))

let attr = try FileManager.default.attributesOfItem(atPath: file.path)

self.size = (attr[.size] as? Int) ?? 0

self.filename = file.name
Expand Down Expand Up @@ -259,28 +273,6 @@ extension LFSPointer: CustomDebugStringConvertible {
}
}

public struct JSONPointer: Codable {
public let filename: String
public let filePath: String
public let pointer: LFSPointer
}

/// Generates a string containing `JSON`.
/// - Parameter array: No description.
/// - Returns: A `String` containing `JSON`.
public func toJSON(array: [JSONPointer], jsonFormat: JSONEncoder.OutputFormatting = .init()) -> String {

let encoder = JSONEncoder()

encoder.outputFormatting = jsonFormat

let jsonBytes = (try? encoder.encode(array)) ?? Data()

let jsonString = String(data: jsonBytes, encoding: .utf8) ?? ""

return jsonString
}

public extension Array where Self.Element == LFSPointer {
/// Converts and `Array` of `LFSPointer`s to `JSON`.
/// - Parameter jsonFormat: The format of the generated `JSON`.
Expand Down
4 changes: 1 addition & 3 deletions Tests/LFSPointersTests/LFSPointersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ final class LFSPointersTests: XCTestCase {

func testConvertFileToPointer() throws {
let pointer = try LFSPointer(fromFile: resources.file(named: "foo.txt").url)

#if os(macOS)

XCTAssertEqual(667684, pointer.size)
XCTAssertEqual("802cd848ada6f6f7177bc4bd0952e2c3a5c7378757899b1ed16c0f1a243eb930", pointer.oid)
#endif
}

func testRecursivelyGeneratePointersForFilesInSubdirectories() throws {
Expand Down

0 comments on commit 574157f

Please sign in to comment.