Skip to content

Commit ddf73c2

Browse files
Add ability to remove items from a section (#75)
1 parent 2cca5c7 commit ddf73c2

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

Sources/Publish/API/PublishingStep.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,26 @@ public extension PublishingStep {
134134
try MarkdownFileHandler().addMarkdownFiles(in: folder, to: &context)
135135
}
136136
}
137+
138+
/// Remove all items matching a predicate, optionally within a specific section.
139+
/// - parameter section: Any specific section to remove all items within.
140+
/// - parameter predicate: Any predicate to filter the items using.
141+
static func removeAllItems(
142+
in section: Site.SectionID? = nil,
143+
matching predicate: Predicate<Item<Site>> = .any
144+
) -> Self {
145+
let nameSuffix = section.map { " in '\($0)'" } ?? ""
146+
147+
return step(named: "Remove items" + nameSuffix) { context in
148+
if let section = section {
149+
context.sections[section].removeItems(matching: predicate)
150+
} else {
151+
for section in context.sections.ids {
152+
context.sections[section].removeItems(matching: predicate)
153+
}
154+
}
155+
}
156+
}
137157

138158
/// Mutate all items matching a predicate, optionally within a specific section.
139159
/// - parameter section: Any specific section to mutate all items within.

Sources/Publish/API/Section.swift

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,21 +94,19 @@ public extension Section {
9494
return item
9595
}
9696
}
97+
98+
/// Remove all items within this section matching a given predicate.
99+
/// - Parameter predicate: Any predicate to filter the items based on.
100+
mutating func removeItems(matching predicate: Predicate<Item<Site>> = .any) {
101+
items.removeAll(where: predicate.matches)
102+
rebuildIndexes()
103+
}
97104

98105
/// Sort all items within this section using a closure.
99106
/// - Parameter sorter: The closure to use to sort the items.
100107
mutating func sortItems(by sorter: (Item<Site>, Item<Site>) throws -> Bool) rethrows {
101108
try items.sort(by: sorter)
102-
itemIndexesByPath = [:]
103-
itemIndexesByTag = [:]
104-
105-
for (index, item) in items.enumerated() {
106-
itemIndexesByPath[item.relativePath] = index
107-
108-
for tag in item.tags {
109-
itemIndexesByTag[tag, default: []].insert(index)
110-
}
111-
}
109+
rebuildIndexes()
112110
}
113111
}
114112

@@ -169,4 +167,17 @@ private extension Section {
169167

170168
lastItemModificationDate = newDate
171169
}
170+
171+
mutating func rebuildIndexes() {
172+
itemIndexesByPath = [:]
173+
itemIndexesByTag = [:]
174+
175+
for (index, item) in items.enumerated() {
176+
itemIndexesByPath[item.relativePath] = index
177+
178+
for tag in item.tags {
179+
itemIndexesByTag[tag, default: []].insert(index)
180+
}
181+
}
182+
}
172183
}

Tests/PublishTests/Tests/ContentMutationTests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ final class ContentMutationTests: PublishTestCase {
3232
XCTAssertEqual(site.sections[.one].items.first?.body.html, "<div>Plot!</div>")
3333
}
3434

35+
func testRemovingItemsMatchingPredicate() throws {
36+
let items = [
37+
Item.stub(withPath: "a").setting(\.tags, to: ["one"]),
38+
Item.stub(withPath: "b").setting(\.tags, to: ["one", "two"])
39+
]
40+
41+
let site = try publishWebsite(using: [
42+
.addItems(in: items),
43+
.removeAllItems(matching: \.tags ~= "two")
44+
])
45+
46+
XCTAssertEqual(site.sections[.one].items, [items[0]])
47+
XCTAssertNil(site.sections[.one].item(at: "b"), "Item indexes not updated")
48+
}
49+
3550
func testMutatingAllSections() throws {
3651
let site = try publishWebsite(using: [
3752
.step(named: "Set section titles") { context in
@@ -280,6 +295,7 @@ extension ContentMutationTests {
280295
[
281296
("testAddingItemUsingClosureAPI", testAddingItemUsingClosureAPI),
282297
("testAddingItemUsingPlotHierarchy", testAddingItemUsingPlotHierarchy),
298+
("testRemovingItemsMatchingPredicate", testRemovingItemsMatchingPredicate),
283299
("testMutatingAllSections", testMutatingAllSections),
284300
("testMutatingAllItems", testMutatingAllItems),
285301
("testMutatingItemsInSection", testMutatingItemsInSection),

0 commit comments

Comments
 (0)