hledger-forecast 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +28 -1
- data/CHANGELOG.md +15 -0
- data/README.md +34 -14
- data/Rakefile +6 -0
- data/example.csv +1 -1
- data/hledger-forecast.gemspec +2 -2
- data/lib/hledger_forecast/calculator.rb +13 -1
- data/lib/hledger_forecast/transaction.rb +10 -3
- data/lib/hledger_forecast/version.rb +1 -1
- data/spec/calculator_spec.rb +26 -0
- data/spec/tags_spec.rb +26 -0
- metadata +8 -6
- data/.github/workflows/publish_ruby_gem.yml +0 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5acfd1bbab287a58bfe5ce7237576535b6b927d034da9e3651a4c240653e0f33
|
|
4
|
+
data.tar.gz: 23eb8d2646996b422473440b8f90797215a7390f4d6e2862b470bd361b6d55d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 62a027f56e0faf7641769b13928ed61c91e3851fe6b1623df00efd233ec244be03c57d7b94ea2605f01580ba18e0a916807a59c6ef848118d9b80fa9a3e8be28
|
|
7
|
+
data.tar.gz: 470b89a138eff0a2f5da24d4a4fe31ffd7e9584646094665020d19a40a9303877073bfcbc95eb35eae1498149fbfa96b899bd44c5ee4eab4225f26acec9b2e11
|
|
@@ -13,9 +13,36 @@ jobs:
|
|
|
13
13
|
contents: write
|
|
14
14
|
pull-requests: write
|
|
15
15
|
|
|
16
|
+
outputs:
|
|
17
|
+
release_created: ${{ steps.release.outputs.release_created }}
|
|
18
|
+
|
|
16
19
|
steps:
|
|
17
|
-
- name: Release
|
|
20
|
+
- name: Release
|
|
21
|
+
id: release
|
|
18
22
|
uses: googleapis/release-please-action@v4
|
|
19
23
|
with:
|
|
20
24
|
release-type: ruby
|
|
21
25
|
|
|
26
|
+
publish:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
needs: release
|
|
29
|
+
if: needs.release.outputs.release_created == 'true'
|
|
30
|
+
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Set up Ruby
|
|
35
|
+
uses: ruby/setup-ruby@v1
|
|
36
|
+
with:
|
|
37
|
+
ruby-version: "3.3"
|
|
38
|
+
|
|
39
|
+
- name: Publish to RubyGems
|
|
40
|
+
run: |
|
|
41
|
+
mkdir -p $HOME/.gem
|
|
42
|
+
touch $HOME/.gem/credentials
|
|
43
|
+
chmod 0600 $HOME/.gem/credentials
|
|
44
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
45
|
+
gem build *.gemspec
|
|
46
|
+
gem push *.gem
|
|
47
|
+
env:
|
|
48
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.2.0](https://github.com/olimorris/hledger-forecast/compare/v3.1.0...v3.2.0) (2026-04-13)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* can exclude tags in summarizer ([#16](https://github.com/olimorris/hledger-forecast/issues/16)) ([faee83e](https://github.com/olimorris/hledger-forecast/commit/faee83ee8eb554d146177832c307b87f5ecd4616))
|
|
9
|
+
* from date can have calculations ([#18](https://github.com/olimorris/hledger-forecast/issues/18)) ([e62a693](https://github.com/olimorris/hledger-forecast/commit/e62a69385bf6c34f2d446593d5046fe22a1e7f5f))
|
|
10
|
+
|
|
11
|
+
## [3.1.0](https://github.com/olimorris/hledger-forecast/compare/v3.0.0...v3.1.0) (2026-04-02)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* dates now support `+` prefix ([#14](https://github.com/olimorris/hledger-forecast/issues/14)) ([16ee70e](https://github.com/olimorris/hledger-forecast/commit/16ee70ec6d3a717f679fddcbf22324f71010e93d))
|
|
17
|
+
|
|
3
18
|
## [3.0.0](https://github.com/olimorris/hledger-forecast/compare/v2.0.1...v3.0.0) (2026-03-27)
|
|
4
19
|
|
|
5
20
|
|
data/README.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
<a href="https://github.com/olimorris/hledger-forecast/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/olimorris/hledger-forecast/ci.yml?branch=main&label=tests&style=for-the-badge"></a>
|
|
10
10
|
<a href="https://github.com/olimorris/hledger-forecast/releases"><img src="https://img.shields.io/github/v/release/olimorris/hledger-forecast?style=for-the-badge"</a>
|
|
11
11
|
</p>
|
|
12
|
+
|
|
12
13
|
**"Improved", you say?** Using a _CSV_ file, forecasts can be quickly generated into a _journal_ file ready to be fed into [hledger](https://github.com/simonmichael/hledger). **A 16 line [CSV file](https://github.com/olimorris/hledger-forecast/blob/main/example.csv) can generate a 46 line hledger [forecast file](https://github.com/olimorris/hledger-forecast/blob/main/example.journal)!**
|
|
13
14
|
|
|
14
15
|
## :sparkles: Features
|
|
@@ -37,7 +38,7 @@ Except, you'd need to work out what 20 months from `2026-01-01` is and do $3000
|
|
|
37
38
|
In `hledger-forecast`, you add a single line to your CSV:
|
|
38
39
|
|
|
39
40
|
```csv
|
|
40
|
-
monthly,,Assets:Checking,01/01/2026
|
|
41
|
+
monthly,,Assets:Checking,01/01/2026,+20,New Laptop,Expenses:General Expenses,=3000/20,,,
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
The tool calculates the amount and the end date for you.
|
|
@@ -67,14 +68,14 @@ Assuming you have Ruby and [RubyGems](http://rubygems.org/pages/download) instal
|
|
|
67
68
|
## :rocket: Usage
|
|
68
69
|
|
|
69
70
|
hledger-forecast
|
|
70
|
-
|
|
71
|
+
|
|
71
72
|
Usage: hledger-forecast [command] [options]
|
|
72
|
-
|
|
73
|
+
|
|
73
74
|
Commands:
|
|
74
75
|
generate Generate a forecast from a CSV file
|
|
75
76
|
summarize Summarize the forecast file and output to the terminal
|
|
76
77
|
compare Compare and highlight the differences between two CSV files
|
|
77
|
-
|
|
78
|
+
|
|
78
79
|
Options:
|
|
79
80
|
-h, --help Show this help message
|
|
80
81
|
-v, --version Show version
|
|
@@ -84,9 +85,9 @@ Assuming you have Ruby and [RubyGems](http://rubygems.org/pages/download) instal
|
|
|
84
85
|
Reads your CSV file and creates a journal file ready to use with hledger. See [example.journal](https://github.com/olimorris/hledger-forecast/blob/main/example.journal) for an example of the output.
|
|
85
86
|
|
|
86
87
|
hledger-forecast generate -f my_forecast.csv -o forecast.journal
|
|
87
|
-
|
|
88
|
+
|
|
88
89
|
Usage: hledger-forecast generate [options]
|
|
89
|
-
|
|
90
|
+
|
|
90
91
|
-f, --forecast FILE The path to the FORECAST CSV file to generate from
|
|
91
92
|
-o, --output-file FILE The path to the OUTPUT file to create
|
|
92
93
|
-t, --tags TAGS Only include transactions with given tags (comma-separated)
|
|
@@ -111,9 +112,9 @@ This will generate a forecast up to the end of Feb 2027, showing asset balances
|
|
|
111
112
|
As your forecast grows, it's useful to see the totals at a glance. Think of this as your income statement, rolled up to whatever period makes sense.
|
|
112
113
|
|
|
113
114
|
hledger-forecast summarize -f my_forecast.csv
|
|
114
|
-
|
|
115
|
+
|
|
115
116
|
Usage: hledger-forecast summarize [options]
|
|
116
|
-
|
|
117
|
+
|
|
117
118
|
-f, --forecast FILE The path to the FORECAST CSV file to summarize
|
|
118
119
|
-r, --roll-up PERIOD The period to roll-up your forecasts into. One of:
|
|
119
120
|
[yearly], [half-yearly], [quarterly], [monthly], [weekly], [daily]
|
|
@@ -146,8 +147,8 @@ The CSV file should have a header row with these columns:
|
|
|
146
147
|
| `type` | string | yes | One of: `monthly`, `quarterly`, `half-yearly`, `yearly`, `once`, `custom` |
|
|
147
148
|
| `frequency` | string | `custom` only | Repeating frequency, using hledger's [periodic rule syntax](https://hledger.org/dev/hledger.html#periodic-transactions) |
|
|
148
149
|
| `account` | string | yes | The account the transaction applies to, e.g. `Assets:Bank` |
|
|
149
|
-
| `from` | date | yes | Start date, e.g. `01/03/2023` |
|
|
150
|
-
| `to` | date | no | End date, e.g. `01/01/2025` |
|
|
150
|
+
| `from` | date | yes | Start date, e.g. `01/03/2023`. Supports `=` prefix for calculated values, e.g. `=01/03/2023+(5*12)` |
|
|
151
|
+
| `to` | date | no | End date, e.g. `01/01/2025`. Supports `+` prefix for calculated values, e.g. `+12` for 12 months |
|
|
151
152
|
| `description` | string | yes | A description of the transaction |
|
|
152
153
|
| `category` | string | yes | The category account, e.g. `Expenses:Food` |
|
|
153
154
|
| `amount` | number | yes | The transaction amount. Supports `=` prefix for calculated values |
|
|
@@ -164,7 +165,7 @@ monthly,,Assets:Bank,01/03/2023,01/01/2025,Mortgage,Expenses:Mortgage,2000,,,fix
|
|
|
164
165
|
monthly,,Assets:Bank,01/03/2023,,Bills,Expenses:Bills,175,,,fixed|essential
|
|
165
166
|
monthly,,Assets:Bank,01/03/2023,,Food,Expenses:Food,500,,,living|essential
|
|
166
167
|
monthly,,Assets:Bank,01/03/2023,,New Kitchen,Expenses:House,=5000/24,,,living
|
|
167
|
-
monthly,,Assets:Bank,01/03/2023
|
|
168
|
+
monthly,,Assets:Bank,01/03/2023,+12,Holiday,Expenses:Holiday,125,,,living
|
|
168
169
|
monthly,,Assets:Bank,01/03/2023,01/03/2025,Rainy day fund,Assets:Savings,300,,,saving
|
|
169
170
|
monthly,,Assets:Pension,01/01/2024,,Pension draw down,Income:Pension,-500,,,fixed|essential
|
|
170
171
|
quarterly,,Assets:Bank,01/04/2023,,Quarterly bonus,Income:Bonus,-1000,,,fixed
|
|
@@ -188,13 +189,29 @@ monthly,,Assets:Bank,01/03/2023,,New Kitchen,Expenses:House,=5000/24,,
|
|
|
188
189
|
|
|
189
190
|
### Calculated dates
|
|
190
191
|
|
|
191
|
-
|
|
192
|
+
Both `from` and `to` support calculated values.
|
|
193
|
+
|
|
194
|
+
**`from` column** — prefix with `=` to compute a start date. The formula is `=BASE_DATE+OFFSET` where the offset is evaluated as months:
|
|
192
195
|
|
|
193
196
|
```csv
|
|
194
|
-
monthly,,Assets:Bank
|
|
197
|
+
monthly,,Assets:Bank,=01/09/2025+(5*12),,Salary,Income:Salary,-3500,,
|
|
195
198
|
```
|
|
196
199
|
|
|
197
|
-
That sets the
|
|
200
|
+
That sets the start date to 60 months (5 years) after `01/09/2025`, giving `01/09/2030`.
|
|
201
|
+
|
|
202
|
+
**`to` column** — use `+` followed by a number to mean "N months from the `from` date":
|
|
203
|
+
|
|
204
|
+
```csv
|
|
205
|
+
monthly,,Assets:Bank,01/03/2026,+12,Holiday,Expenses:Holiday,125,,
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
That sets the end date to 12 months after `01/03/2026`. The `=` prefix also supports formulas — useful for longer periods:
|
|
209
|
+
|
|
210
|
+
```csv
|
|
211
|
+
monthly,,Assets:Bank,01/03/2026,=12*5,Mortgage,Expenses:Mortgage,2000,,
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
That sets the end date to 5 years (60 months) after `01/03/2026`.
|
|
198
215
|
|
|
199
216
|
### Tags
|
|
200
217
|
|
|
@@ -228,6 +245,9 @@ hledger-forecast summarize -f forecast.csv --tags=essential
|
|
|
228
245
|
|
|
229
246
|
# Multiple tags use OR logic — matches any
|
|
230
247
|
hledger-forecast summarize -f forecast.csv --tags=fixed,living
|
|
248
|
+
|
|
249
|
+
# Can also exclude tags with a `-` prefix
|
|
250
|
+
hledger-forecast summarize -f forecast.csv --tags=fixed,-essential
|
|
231
251
|
```
|
|
232
252
|
|
|
233
253
|
**Querying in hledger** - because the tags are native hledger format, you can query them directly:
|
data/Rakefile
ADDED
data/example.csv
CHANGED
|
@@ -10,7 +10,7 @@ monthly,,Assets:Pension,01/01/2024,,Pension draw down,Income:Pension,-500,,,fixe
|
|
|
10
10
|
quarterly,,Assets:Bank,01/04/2023,,Quarterly bonus,Income:Bonus,-1000,,,fixed
|
|
11
11
|
half-yearly,,Assets:Bank,01/04/2023,,Top up holiday funds,Expenses:Holiday,500,,,living
|
|
12
12
|
yearly,,Assets:Bank,01/04/2023,,Annual bonus,Income:Bonus,-2000,,,fixed
|
|
13
|
-
once,,Assets:Bank,05/03/2023,,Refund for that damn laptop,Expenses:Shopping,-3000
|
|
13
|
+
once,,Assets:Bank,05/03/2023,,Refund for that damn laptop,Expenses:Shopping,-3000,,,
|
|
14
14
|
custom,every 2 weeks,Assets:Bank,01/03/2023,,Hair and beauty,Expenses:Personal Care,80,26,,living
|
|
15
15
|
custom,every 5 weeks,Assets:Bank,01/03/2023,,Misc expenses,Expenses:General Expenses,30,10.4,,living
|
|
16
16
|
settings,currency,USD,,,,,,,,
|
data/hledger-forecast.gemspec
CHANGED
|
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
|
|
|
8
8
|
s.name = "hledger-forecast"
|
|
9
9
|
s.version = HledgerForecast::VERSION
|
|
10
10
|
s.authors = ["Oli Morris"]
|
|
11
|
-
s.summary = "
|
|
12
|
-
s.description = "
|
|
11
|
+
s.summary = "Generate hledger journal entries and income statements from a CSV forecast"
|
|
12
|
+
s.description = "Define recurring transactions in a CSV file with support for formulas, calculated dates, and tags. Generates hledger periodic transaction journals and provides income statement summaries with savings rates."
|
|
13
13
|
s.email = "olimorris@users.noreply.github.com"
|
|
14
14
|
s.homepage = "https://github.com/olimorris/hledger-forecast"
|
|
15
15
|
s.license = "MIT"
|
|
@@ -8,8 +8,20 @@ module HledgerForecast
|
|
|
8
8
|
@calc.evaluate(amount.slice(1..-1))
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
def self.evaluate_from_date(value)
|
|
12
|
+
value = value.to_s
|
|
13
|
+
return Date.parse(value) unless value.start_with?("=")
|
|
14
|
+
|
|
15
|
+
date_str, offset_expr = value[1..].split("+", 2)
|
|
16
|
+
date = Date.parse(date_str)
|
|
17
|
+
return date unless offset_expr
|
|
18
|
+
|
|
19
|
+
date >> @calc.evaluate(offset_expr).to_i
|
|
20
|
+
end
|
|
21
|
+
|
|
11
22
|
def self.evaluate_date(from, to)
|
|
12
|
-
return
|
|
23
|
+
return (from >> to) - 1 if to.is_a?(Numeric)
|
|
24
|
+
return Date.parse(to) unless to.start_with?("=") || to.start_with?("+")
|
|
13
25
|
|
|
14
26
|
(from >> @calc.evaluate(to.slice(1..-1))) - 1
|
|
15
27
|
end
|
|
@@ -24,13 +24,13 @@ module HledgerForecast
|
|
|
24
24
|
keyword_init: true
|
|
25
25
|
) do
|
|
26
26
|
def self.from_row(row)
|
|
27
|
-
from =
|
|
27
|
+
from = Calculator.evaluate_from_date(row[:from])
|
|
28
28
|
new(
|
|
29
29
|
type: row[:type],
|
|
30
30
|
frequency: row[:frequency],
|
|
31
31
|
account: row[:account],
|
|
32
32
|
from: from,
|
|
33
|
-
to: row[:to] ? Calculator.evaluate_date(from, row[:to]
|
|
33
|
+
to: row[:to] ? Calculator.evaluate_date(from, row[:to]) : nil,
|
|
34
34
|
description: row[:description],
|
|
35
35
|
category: row[:category],
|
|
36
36
|
amount: Calculator.evaluate(row[:amount]),
|
|
@@ -42,7 +42,14 @@ module HledgerForecast
|
|
|
42
42
|
|
|
43
43
|
def matches_tags?(filter_tags)
|
|
44
44
|
return true if filter_tags.nil? || filter_tags.empty?
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
exclude_tags = filter_tags.select { |t| t.start_with?("-") }.map { |t| t[1..] }
|
|
47
|
+
include_tags = filter_tags.reject { |t| t.start_with?("-") }
|
|
48
|
+
|
|
49
|
+
return false if exclude_tags.any? && (tags & exclude_tags).any?
|
|
50
|
+
return (tags & include_tags).any? if include_tags.any?
|
|
51
|
+
|
|
52
|
+
true
|
|
46
53
|
end
|
|
47
54
|
|
|
48
55
|
def annualised_amount
|
data/spec/calculator_spec.rb
CHANGED
|
@@ -23,6 +23,24 @@ RSpec.describe HledgerForecast::Calculator do
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
describe ".evaluate_from_date" do
|
|
27
|
+
it "parses a plain date string" do
|
|
28
|
+
expect(described_class.evaluate_from_date("01/09/2022")).to(eq(Date.parse("2022-09-01")))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "evaluates a date with a month offset" do
|
|
32
|
+
expect(described_class.evaluate_from_date("=01/09/2022+6")).to(eq(Date.parse("2023-03-01")))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "evaluates a date with a multiplied offset" do
|
|
36
|
+
expect(described_class.evaluate_from_date("=01/09/2022+(5*12)")).to(eq(Date.parse("2027-09-01")))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "evaluates a formula with no offset" do
|
|
40
|
+
expect(described_class.evaluate_from_date("=01/09/2022")).to(eq(Date.parse("2022-09-01")))
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
26
44
|
describe ".evaluate_date" do
|
|
27
45
|
let(:from) { Date.parse("2023-03-01") }
|
|
28
46
|
|
|
@@ -41,5 +59,13 @@ RSpec.describe HledgerForecast::Calculator do
|
|
|
41
59
|
it "handles a 24-month offset" do
|
|
42
60
|
expect(described_class.evaluate_date(from, "=24")).to(eq(Date.parse("2025-02-28")))
|
|
43
61
|
end
|
|
62
|
+
|
|
63
|
+
it "handles dates with a +" do
|
|
64
|
+
expect(described_class.evaluate_date(from, "+24")).to(eq(Date.parse("2025-02-28")))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "handles a numeric offset (CSV numeric converter coerces +N to integer)" do
|
|
68
|
+
expect(described_class.evaluate_date(from, 24)).to(eq(Date.parse("2025-02-28")))
|
|
69
|
+
end
|
|
44
70
|
end
|
|
45
71
|
end
|
data/spec/tags_spec.rb
CHANGED
|
@@ -72,6 +72,32 @@ RSpec.describe "tags" do
|
|
|
72
72
|
expect(descriptions).to(eq(["Food", "Netflix"]))
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
it "excludes transactions by tag with - prefix" do
|
|
76
|
+
result = HledgerForecast::Summarizer.summarize(config, {tags: ["-fixed"]})
|
|
77
|
+
descriptions = result[:output].map { |r| r[:description] }
|
|
78
|
+
|
|
79
|
+
expect(descriptions).to(eq(["Food", "Netflix"]))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "excludes tags in generator output" do
|
|
83
|
+
expected = <<~JOURNAL
|
|
84
|
+
~ monthly from 2023-03-01 * Food, Netflix
|
|
85
|
+
Expenses:Food £500.00; living:, essential:
|
|
86
|
+
Expenses:Subscriptions £15.00 ; living:
|
|
87
|
+
Assets:Bank
|
|
88
|
+
|
|
89
|
+
JOURNAL
|
|
90
|
+
|
|
91
|
+
expect(HledgerForecast::Generator.generate(config, {tags: ["-fixed"]})).to(eq(expected))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "combines include and exclude tags" do
|
|
95
|
+
result = HledgerForecast::Summarizer.summarize(config, {tags: ["essential", "-fixed"]})
|
|
96
|
+
descriptions = result[:output].map { |r| r[:description] }
|
|
97
|
+
|
|
98
|
+
expect(descriptions).to(eq(["Food"]))
|
|
99
|
+
end
|
|
100
|
+
|
|
75
101
|
it "raises an error when --tags is used on a CSV without a tag column" do
|
|
76
102
|
csv_without_tag_column = <<~CSV
|
|
77
103
|
type,frequency,account,from,to,description,category,amount,roll-up,summary_exclude
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hledger-forecast
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Oli Morris
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: abbrev
|
|
@@ -122,7 +122,9 @@ dependencies:
|
|
|
122
122
|
- - "~>"
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: '3.12'
|
|
125
|
-
description:
|
|
125
|
+
description: Define recurring transactions in a CSV file with support for formulas,
|
|
126
|
+
calculated dates, and tags. Generates hledger periodic transaction journals and
|
|
127
|
+
provides income statement summaries with savings rates.
|
|
126
128
|
email: olimorris@users.noreply.github.com
|
|
127
129
|
executables:
|
|
128
130
|
- hledger-forecast
|
|
@@ -130,7 +132,6 @@ extensions: []
|
|
|
130
132
|
extra_rdoc_files: []
|
|
131
133
|
files:
|
|
132
134
|
- ".github/workflows/ci.yml"
|
|
133
|
-
- ".github/workflows/publish_ruby_gem.yml"
|
|
134
135
|
- ".github/workflows/release.yml"
|
|
135
136
|
- ".gitignore"
|
|
136
137
|
- ".mise.toml"
|
|
@@ -139,6 +140,7 @@ files:
|
|
|
139
140
|
- Gemfile
|
|
140
141
|
- LICENSE
|
|
141
142
|
- README.md
|
|
143
|
+
- Rakefile
|
|
142
144
|
- bin/hledger-forecast
|
|
143
145
|
- example.csv
|
|
144
146
|
- example.journal
|
|
@@ -198,10 +200,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
198
200
|
- !ruby/object:Gem::Version
|
|
199
201
|
version: '0'
|
|
200
202
|
requirements: []
|
|
201
|
-
rubygems_version: 3.
|
|
203
|
+
rubygems_version: 3.5.22
|
|
202
204
|
signing_key:
|
|
203
205
|
specification_version: 4
|
|
204
|
-
summary:
|
|
206
|
+
summary: Generate hledger journal entries and income statements from a CSV forecast
|
|
205
207
|
test_files:
|
|
206
208
|
- spec/calculator_spec.rb
|
|
207
209
|
- spec/cli_spec.rb
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
name: Publish Ruby Gem
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v*'
|
|
7
|
-
workflow_dispatch:
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
release:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v4
|
|
15
|
-
- name: Publish Gem 💎️
|
|
16
|
-
run: |
|
|
17
|
-
mkdir -p $HOME/.gem
|
|
18
|
-
touch $HOME/.gem/credentials
|
|
19
|
-
chmod 0600 $HOME/.gem/credentials
|
|
20
|
-
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
21
|
-
gem build *.gemspec
|
|
22
|
-
gem push *.gem
|
|
23
|
-
env:
|
|
24
|
-
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|