Skip to content

Commit 287c5d4

Browse files
committed
✨ Hours command
1 parent 32bfe29 commit 287c5d4

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

Sources/Cli.swift

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ struct Cli: ParsableCommand {
1212
subcommands: [
1313
Add.self,
1414
Calendars.self,
15+
Hours.self,
1516
Next.self,
1617
On.self,
1718
ShowConfig.self,

Sources/Cli/Hours.swift

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import ArgumentParser
2+
import Foundation
3+
import when
4+
5+
/// `plan hours "..."`
6+
///
7+
/// List spent/planned hours
8+
struct Hours: ParsableCommand {
9+
static var configuration = CommandConfiguration(
10+
abstract: "List spent/planned hours"
11+
)
12+
13+
@OptionGroup
14+
var opts: SharedOptions
15+
16+
@Argument(help: "Date expression")
17+
var expression: String
18+
19+
mutating func run() throws {
20+
let parser = DateParser(rules: EN.all + Common.all)
21+
var userDate: Date
22+
do {
23+
let result = try parser.parse(text: expression, base: Date())
24+
userDate = result.date
25+
} catch {
26+
StdErr.print("Can't parse date")
27+
throw ExitCode.failure
28+
}
29+
30+
let today = FCalendar.current.startOfDay(for: userDate)
31+
let start = FCalendar.current.date(byAdding: .day, value: 0, to: today)!
32+
let end = FCalendar.current.date(byAdding: .day, value: 1, to: today)!
33+
34+
let orders = opts.sortBy.isEmpty ? [Order.Default] : opts.sortBy
35+
36+
let eventSelector = EventSelector.Combined(selectors: [
37+
// first sort
38+
EventSelector.Sorted(orders: orders),
39+
// then choose all
40+
EventSelector.All(),
41+
]
42+
)
43+
44+
let events = Plan().events(
45+
start: start, end: end, opts: opts,
46+
selector: eventSelector,
47+
transformer: EventTransformer(rules: Loader.readConfig()?.iconize ?? [])
48+
)
49+
let groups = Dictionary(grouping: events, by: { $0.title.full })
50+
.mapValues { $0.reduce(into: 0) { $0 += $1.schedule.duration } }
51+
.mapValues { String(format: "%.2f", Double($0) / 60) }
52+
for group in groups {
53+
StdOut.print(group.key + ": " + group.value)
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)