Skip to content

Commit

Permalink
fix: Sort file changes alphabetically (#43)
Browse files Browse the repository at this point in the history
This change also extracts `Item` and `Snapshot` models into separate
files.
  • Loading branch information
jbmorley authored Feb 24, 2025
1 parent 00e650e commit 6e971db
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 39 deletions.
31 changes: 31 additions & 0 deletions Sources/ReporterCore/Model/Item.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2024-2025 Jason Morley
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import Foundation

public struct Item: Codable, Hashable, Sendable {
public let path: String
public let checksum: Data?

public init(path: String, checksum: Data?) {
self.path = path
self.checksum = checksum
}
}
49 changes: 49 additions & 0 deletions Sources/ReporterCore/Model/Snapshot.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2024-2025 Jason Morley
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import Foundation

public struct Snapshot: Codable {

public var description: String {
return "\(items.count) files"
}

public let items: Set<Item>

public init(items: [Item] = []) {
self.items = Set(items)
}

public func changes(from initialState: Snapshot) -> Changes {
let additions = items.subtracting(initialState.items)
let deletions = initialState.items.subtracting(items)
return Changes(
additions: additions
.map { $0.path }
.sorted { $0.localizedStandardCompare($1) == .orderedAscending },
deletions: deletions
.map { $0.path }
.sorted { $0.localizedStandardCompare($1) == .orderedAscending }

)
}

}
33 changes: 0 additions & 33 deletions Sources/ReporterCore/Model/State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,6 @@ import Foundation

public struct State: Codable {

public struct Item: Codable, Hashable, Sendable {
public let path: String
public let checksum: Data?

public init(path: String, checksum: Data?) {
self.path = path
self.checksum = checksum
}
}

public struct Snapshot: Codable {

public var description: String {
return "\(items.count) files"
}

public let items: Set<Item>

public init(items: [Item] = []) {
self.items = Set(items)
}

public func changes(from initialState: Snapshot) -> Changes {
let additions = items.subtracting(initialState.items)
let deletions = initialState.items.subtracting(items)
return Changes(
additions: additions.map { $0.path },
deletions: deletions.map { $0.path }
)
}

}

public var snapshots: [URL: Snapshot]

public init() {
Expand Down
12 changes: 6 additions & 6 deletions Sources/ReporterCore/Reporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import SwiftSMTP

public class Reporter {

static func snapshot(path: URL, console: Console) async throws -> State.Snapshot {
static func snapshot(path: URL, console: Console) async throws -> Snapshot {

var files = [URL]()

Expand All @@ -52,27 +52,27 @@ public class Reporter {
}

// Generate the hashes for the files concurrently.
let items = try await withThrowingTaskGroup(of: State.Item.self) { group in
let items = try await withThrowingTaskGroup(of: Item.self) { group in
let progress = Progress(totalUnitCount: Int64(files.count))
for url in files {
group.addTask {
return try await Task {
let item = State.Item(path: url.path, checksum: try Self.checksum(url: url))
let item = Item(path: url.path, checksum: try Self.checksum(url: url))
progress.completedUnitCount += 1
console.progress(progress, message: path.lastPathComponent)
return item
}.value
}
}
var items: [State.Item] = []
var items: [Item] = []
for try await result in group {
items.append(result)
}
return items
}

// Create the snapshot
let snapshot = State.Snapshot(items: items)
let snapshot = Snapshot(items: items)

return snapshot
}
Expand Down Expand Up @@ -130,7 +130,7 @@ public class Reporter {
var folders: [KeyedChanges] = []
for (url, snapshot) in newState.snapshots {
console.log("Checking '\(url.path)'...")
let oldSnapshot = oldState.snapshots[url] ?? State.Snapshot()
let oldSnapshot = oldState.snapshots[url] ?? Snapshot()
let changes = snapshot.changes(from: oldSnapshot)
folders.append(KeyedChanges(url: url, changes: changes))
}
Expand Down

0 comments on commit 6e971db

Please sign in to comment.