reckon 0.9.4 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 648b51c8481100983f8d8eff4d9b86ea2ad1962e0908268a6450f618d90f3267
4
- data.tar.gz: fb19e70b53da00299caa495e24d8fa01ac20686306e383f598a8888f5118dae3
3
+ metadata.gz: 2f1e02a1c5dde18325b138afa66518fc2516ea30e8c39eae5cdff2808f5f8bb4
4
+ data.tar.gz: 3d70362d3b8c8a3e6e147f4ca3466e35db7905e2bfe60571de9d219c330e23db
5
5
  SHA512:
6
- metadata.gz: 56a4558fe3aadfbf9a0a9f4399f8e70b549b90a08057235fafe5839203390c462b502511fc60b748490398c75f46b5a4d8ccbb4ac9b07b4e6058d72bf615f4ac
7
- data.tar.gz: dc3acb9fdae98efc8cd4a8891037cc5bfff716b2c5db74f8b1f86edaa2da0e60843ffbcb0eeeef49358738e0a63bded19e2fa3f9955cce40566a3241cbc86aff
6
+ metadata.gz: 707f23ee5da2df3837f0ae5c520e8b62d802d812dd9ab3acef72853c5e7d27d51b7aeaa269f89c66de1b73ab0e6891fb9ced9d3f59fb11c49d7679fa84c0e4f5
7
+ data.tar.gz: 73bbdf6dec9a09c23735695d8c192fde6b94df1d4931e7e79a256bed20a736e46d1503985dc29689f7f4fbaefd5c11413f4a41eb58516691b77daef99c2c8c75
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.9.5](https://github.com/cantino/reckon/tree/v0.9.5) (2024-01-08)
4
+
5
+ [Full Changelog](https://github.com/cantino/reckon/compare/v0.9.4...v0.9.5)
6
+
7
+ **Closed issues:**
8
+
9
+ - Ruby Readline error [\#127](https://github.com/cantino/reckon/issues/127)
10
+ - Date formats [\#126](https://github.com/cantino/reckon/issues/126)
11
+
12
+ **Merged pull requests:**
13
+
14
+ - Pin highline to 2.x branch. Fixes \#127 [\#128](https://github.com/cantino/reckon/pull/128) ([benprew](https://github.com/benprew))
15
+
16
+ ## [v0.9.4](https://github.com/cantino/reckon/tree/v0.9.4) (2023-11-24)
17
+
18
+ [Full Changelog](https://github.com/cantino/reckon/compare/v0.9.3...v0.9.4)
19
+
3
20
  ## [v0.9.3](https://github.com/cantino/reckon/tree/v0.9.3) (2023-08-25)
4
21
 
5
22
  [Full Changelog](https://github.com/cantino/reckon/compare/v0.9.2...v0.9.3)
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reckon (0.9.4)
4
+ reckon (0.9.6)
5
5
  chronic (>= 0.3.0)
6
- highline (>= 1.5.2)
6
+ highline (~> 2.0)
7
7
  matrix (>= 0.4.2)
8
8
  rchardet (>= 1.8.0)
9
9
 
data/Rakefile CHANGED
@@ -8,6 +8,7 @@ RSpec::Core::RakeTask.new(:spec)
8
8
 
9
9
  task default: :spec
10
10
 
11
+ desc "Run specs and integration tests"
11
12
  task :test_all do
12
13
  puts "#{`ledger --version |head -n1`}"
13
14
  puts "Running unit tests"
@@ -16,6 +17,7 @@ task :test_all do
16
17
  Rake::Task["test_integration"].invoke
17
18
  end
18
19
 
20
+ desc "Run integration tests"
19
21
  task :test_integration do
20
22
  cmd = 'prove -v ./spec/integration/test.sh'
21
23
  raise 'Integration tests failed' unless system(cmd)
@@ -28,5 +28,6 @@ gem build reckon.gemspec
28
28
  echo "Push changes and tags"
29
29
  echo "git push && git push --tags"
30
30
  echo "Push new gem"
31
- echo "gem push reckon-$VERSION.gem"
31
+ echo "gem push reckon-$VERSION.gem --otp (ykman oath accounts code -s rubygems.org)"
32
+ echo "Publish draft github release"
32
33
  gh release create "v$VERSION" "reckon-$VERSION.gem" --draft --generate-notes
@@ -107,8 +107,8 @@
107
107
  require 'rubygems'
108
108
 
109
109
  module Reckon
110
+ # Parses ledger files
110
111
  class LedgerParser
111
-
112
112
  # ledger is an object that response to #each_line,
113
113
  # (i.e. a StringIO or an IO object)
114
114
  def initialize(options = {})
@@ -130,7 +130,7 @@ module Reckon
130
130
  next if entry =~ /^\s*[#{comment_chars}]/
131
131
 
132
132
  # (date, type, code, description), type and code are optional
133
- if (m = entry.match(%r{^(\d+[\d/-]+)\s+([*!])?\s*(\([^)]+\))?\s*(.*)$}))
133
+ if (m = entry.match(%r{^(\d+[^\s]+)\s+([*!])?\s*(\([^)]+\))?\s*(.*)$}))
134
134
  add_entry(entries, new_entry)
135
135
  new_entry = {
136
136
  date: try_parse_date(m[1]),
@@ -140,7 +140,7 @@ module Reckon
140
140
  accounts: []
141
141
  }
142
142
  elsif entry =~ /^\s*$/ && new_entry[:date]
143
- add_entry(entries,new_entry)
143
+ add_entry(entries, new_entry)
144
144
  new_entry = {}
145
145
  elsif new_entry[:date] && entry =~ /^\s+/
146
146
  LOGGER.info("Adding new account #{entry}")
@@ -175,13 +175,13 @@ module Reckon
175
175
  end
176
176
 
177
177
  def format_row(row, line1, line2)
178
- out = "#{row[:pretty_date]}\t#{row[:description]}#{row[:note] ? "\t; " + row[:note]: ""}\n"
178
+ note = row[:note] ? "\t; row[:note]" : ""
179
+ out = "#{row[:pretty_date]}\t#{row[:description]}#{note}\n"
179
180
  out += "\t#{line1.first}\t\t\t#{line1.last}\n"
180
181
  out += "\t#{line2.first}\t\t\t#{line2.last}\n\n"
181
182
  out
182
183
  end
183
184
 
184
-
185
185
  private
186
186
 
187
187
  def add_entry(entries, entry)
@@ -1,3 +1,3 @@
1
1
  module Reckon
2
- VERSION = "0.9.4"
2
+ VERSION = "0.9.6"
3
3
  end
data/reckon.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_development_dependency "pry", ">= 0.12.2"
21
21
  s.add_development_dependency "rantly", "= 1.2.0"
22
22
  s.add_runtime_dependency "chronic", ">= 0.3.0"
23
- s.add_runtime_dependency "highline", ">= 1.5.2"
23
+ s.add_runtime_dependency "highline", "~> 2.0" # 3.0 replaces readline with reline and breaks reckon
24
24
  s.add_runtime_dependency "rchardet", ">= 1.8.0"
25
25
  s.add_runtime_dependency "matrix", ">= 0.4.2"
26
26
  end
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- #encoding: utf-8
2
+ # encoding: utf-8
3
3
 
4
4
  require_relative "../spec_helper"
5
5
  require 'rubygems'
@@ -28,27 +28,31 @@ describe Reckon::LedgerParser do
28
28
  property_of do
29
29
  Rantly do
30
30
  description = Proc.new do
31
- sized(15){string}.tr(%q{'`:*\\},'').gsub(/\s+/, ' ').gsub(/^[!;<\[( #{comment_chars}]+/, '')
31
+ sized(15) {
32
+ string
33
+ }.tr(%q{'`:*\\}, '').gsub(/\s+/, ' ').gsub(/^[!;<\[( #{comment_chars}]+/, '')
32
34
  end
33
35
  currency = choose(*currencies) # to be consistent within the transaction
34
- single_line_comments = ";#|%*".split('').map { |n| "#{n} #{call(description)}" }
36
+ single_line_comments = ";#|%*".split('').map { |n|
37
+ "#{n} #{call(description)}"
38
+ }
35
39
  comments = ['', '; ', "\t;#{call(description)}", " ; #{call(description)}"]
36
40
  date = Time.at(range(0, 1_581_389_644)).strftime(choose(*formats))
37
41
  codes = [' ', " (#{string(:alnum).tr('()', '')}) "]
38
42
  account = Proc.new { choose(*delimiters) + call(description) }
39
43
  account_money = Proc.new do
40
- sprintf("%.02f", (float * range(5,10) + 1) * choose(1, -1))
44
+ sprintf("%.02f", (float * range(5, 10) + 1) * choose(1, -1))
41
45
  end
42
46
  account_line = Proc.new do
43
47
  call(account) + \
44
- choose(*delimiters) + \
45
- currency + \
46
- choose(*currency_delimiters) + \
47
- call(account_money) + \
48
- choose(*comments)
48
+ choose(*delimiters) + \
49
+ currency + \
50
+ choose(*currency_delimiters) + \
51
+ call(account_money) + \
52
+ choose(*comments)
49
53
  end
50
54
  ledger = "#{date}#{choose(*types)}#{choose(*codes)}#{call(description)}\n"
51
- range(1,5).times do
55
+ range(1, 5).times do
52
56
  ledger += "#{call(account_line)}\n"
53
57
  end
54
58
  ledger += "#{call(account)}\n"
@@ -56,7 +60,10 @@ describe Reckon::LedgerParser do
56
60
  ledger
57
61
  end
58
62
  end.check(1000) do |s|
59
- filter_format = lambda { |n| [n['date'], n['desc'], n['name'], sprintf("%.02f", n['amount'])] }
63
+ filter_format = lambda { |n|
64
+ [n['date'], n['desc'], n['name'],
65
+ sprintf("%.02f", n['amount'])]
66
+ }
60
67
  headers = %w[date code desc name currency amount type commend]
61
68
  safe_s = Shellwords.escape(s)
62
69
 
@@ -64,7 +71,8 @@ describe Reckon::LedgerParser do
64
71
  actual = CSV.parse(lp_csv, headers: headers).map(&filter_format)
65
72
 
66
73
  ledger_csv = `echo #{safe_s} | ledger csv --date-format '%Y/%m/%d' -f - `
67
- expected = CSV.parse(ledger_csv.gsub('\"', '""'), headers: headers).map(&filter_format)
74
+ expected = CSV.parse(ledger_csv.gsub('\"', '""'),
75
+ headers: headers).map(&filter_format)
68
76
  expected.length.times do |i|
69
77
  expect(actual[i]).to eq(expected[i])
70
78
  end
@@ -72,34 +80,35 @@ describe Reckon::LedgerParser do
72
80
  end
73
81
 
74
82
  it 'should filter block comments' do
75
- ledger = <<HERE
76
- 1970/11/01 Dinner should show up
77
- Assets:Checking -123.00
78
- Expenses:Restaurants
83
+ ledger = <<~HERE
84
+ 1970/11/01 Dinner should show up
85
+ Assets:Checking -123.00
86
+ Expenses:Restaurants
79
87
 
80
- comment
88
+ comment
81
89
 
82
- 1970/11/01 Lunch should NOT show up
83
- Assets:Checking -12.00
84
- Expenses:Restaurants
90
+ 1970/11/01 Lunch should NOT show up
91
+ Assets:Checking -12.00
92
+ Expenses:Restaurants
85
93
 
86
- end comment
87
- HERE
94
+ end comment
95
+ HERE
88
96
  entries = Reckon::LedgerParser.new.parse(StringIO.new(ledger))
89
97
  expect(entries.length).to eq(1)
90
98
  expect(entries.first[:desc]).to eq('Dinner should show up')
91
-
92
99
  end
93
100
 
94
101
  it 'should transaction comments' do
95
- ledger = <<HERE
96
- 2020-03-27 AMZN Mktp USX999H3203; Shopping; Sale
97
- Expenses:Household $82.77
98
- Liabilities:ChaseSapphire -$81.77
99
- # END FINANCE SCRIPT OUTPUT Thu 02 Apr 2020 12:05:54 PM EDT
100
- HERE
102
+ ledger = <<~HERE
103
+ 2020-03-27 AMZN Mktp USX999H3203; Shopping; Sale
104
+ Expenses:Household $82.77
105
+ Liabilities:ChaseSapphire -$81.77
106
+ # END FINANCE SCRIPT OUTPUT Thu 02 Apr 2020 12:05:54 PM EDT
107
+ HERE
101
108
  entries = Reckon::LedgerParser.new.parse(StringIO.new(ledger))
102
- expect(entries.first[:accounts].map { |n| n[:name] }).to eq(['Expenses:Household', 'Liabilities:ChaseSapphire'])
109
+ expect(entries.first[:accounts].map { |n|
110
+ n[:name]
111
+ }).to eq(['Expenses:Household', 'Liabilities:ChaseSapphire'])
103
112
  expect(entries.first[:accounts].size).to eq(2)
104
113
  expect(entries.length).to eq(1)
105
114
  end
@@ -123,80 +132,99 @@ HERE
123
132
  @entries.last[:accounts].last[:name].should == "Assets:Bank:Checking"
124
133
  @entries.last[:accounts].last[:amount].should == -20.24
125
134
  end
135
+
136
+ it "should parse dot-separated dates" do
137
+ ledger = <<~HERE
138
+ 2024.03.12 groceries; 11223344556; 32095205940
139
+ assets:bank:spending 530.00 NOK
140
+ assets:bank:co:groceries
141
+
142
+ 2024.03.13 autosave; 11223344555; 11223344556
143
+ assets:bank:savings
144
+ assets:bank:spending -10.00 NOK
145
+ HERE
146
+ options = { ledger_date_format: '%Y.%m.%d' }
147
+ entries = Reckon::LedgerParser.new(options).parse(StringIO.new(ledger))
148
+ expect(entries.first[:date]).to eq(Date.new(2024, 3, 12))
149
+ expect(entries.last[:date]).to eq(Date.new(2024, 3, 13))
150
+ expect(entries.length).to eq(2)
151
+ end
126
152
  end
127
153
 
128
154
  describe "balance" do
129
155
  it "it should balance out missing account values" do
130
156
  @ledger.send(:balance, [
131
- { :name => "Account1", :amount => 1000 },
132
- { :name => "Account2", :amount => nil }
133
- ]).should == [ { :name => "Account1", :amount => 1000 }, { :name => "Account2", :amount => -1000 } ]
157
+ { :name => "Account1", :amount => 1000 },
158
+ { :name => "Account2", :amount => nil }
159
+ ]).should == [{ :name => "Account1", :amount => 1000 },
160
+ { :name => "Account2", :amount => -1000 }]
134
161
  end
135
162
 
136
163
  it "it should balance out missing account values" do
137
164
  @ledger.send(:balance, [
138
- { :name => "Account1", :amount => 1000 },
139
- { :name => "Account2", :amount => 100 },
140
- { :name => "Account3", :amount => -200 },
141
- { :name => "Account4", :amount => nil }
142
- ]).should == [
143
- { :name => "Account1", :amount => 1000 },
144
- { :name => "Account2", :amount => 100 },
145
- { :name => "Account3", :amount => -200 },
146
- { :name => "Account4", :amount => -900 }
147
- ]
165
+ { :name => "Account1", :amount => 1000 },
166
+ { :name => "Account2", :amount => 100 },
167
+ { :name => "Account3", :amount => -200 },
168
+ { :name => "Account4", :amount => nil }
169
+ ]).should == [
170
+ { :name => "Account1", :amount => 1000 },
171
+ { :name => "Account2", :amount => 100 },
172
+ { :name => "Account3", :amount => -200 },
173
+ { :name => "Account4", :amount => -900 }
174
+ ]
148
175
  end
149
176
 
150
177
  it "it should work on normal values too" do
151
178
  @ledger.send(:balance, [
152
- { :name => "Account1", :amount => 1000 },
153
- { :name => "Account2", :amount => -1000 }
154
- ]).should == [ { :name => "Account1", :amount => 1000 }, { :name => "Account2", :amount => -1000 } ]
179
+ { :name => "Account1", :amount => 1000 },
180
+ { :name => "Account2", :amount => -1000 }
181
+ ]).should == [{ :name => "Account1", :amount => 1000 },
182
+ { :name => "Account2", :amount => -1000 }]
155
183
  end
156
184
  end
157
185
 
158
186
  # Data
159
187
 
160
- EXAMPLE_LEDGER = (<<-LEDGER).strip
161
- = /^Expenses:Books/
162
- (Liabilities:Taxes) -0.10
188
+ EXAMPLE_LEDGER = (<<~LEDGER).strip
189
+ = /^Expenses:Books/
190
+ (Liabilities:Taxes) -0.10
163
191
 
164
- ~ Monthly
165
- Assets:Bank:Checking $500.00
166
- Income:Salary
192
+ ~ Monthly
193
+ Assets:Bank:Checking $500.00
194
+ Income:Salary
167
195
 
168
- 2004-05-01 * Checking balance
169
- Assets:Bank:Checking $1,000.00
170
- Equity:Opening Balances
196
+ 2004-05-01 * Checking balance
197
+ Assets:Bank:Checking $1,000.00
198
+ Equity:Opening Balances
171
199
 
172
- 2004-05-01 * Checking balance
173
- Assets:Bank:Checking €1,000.00
174
- Equity:Opening Balances
200
+ 2004-05-01 * Checking balance
201
+ Assets:Bank:Checking €1,000.00
202
+ Equity:Opening Balances
175
203
 
176
- 2004-05-01 * Checking balance
177
- Assets:Bank:Checking 1,000.00 SEK
178
- Equity:Opening Balances
204
+ 2004-05-01 * Checking balance
205
+ Assets:Bank:Checking 1,000.00 SEK
206
+ Equity:Opening Balances
179
207
 
180
- 2004/05/01 * Investment balance
181
- Assets:Brokerage 50 AAPL @ $30.00
182
- Equity:Opening Balances
208
+ 2004/05/01 * Investment balance
209
+ Assets:Brokerage 50 AAPL @ $30.00
210
+ Equity:Opening Balances
183
211
 
184
- ; blah
185
- !account blah
212
+ ; blah
213
+ !account blah
186
214
 
187
- !end
215
+ !end
188
216
 
189
- D $1,000
217
+ D $1,000
190
218
 
191
- 2004/05/14 * Pay day
192
- Assets:Bank:Checking $500.00
193
- Income:Salary
219
+ 2004/05/14 * Pay day
220
+ Assets:Bank:Checking $500.00
221
+ Income:Salary
194
222
 
195
- 2004/05/27 Book Store
196
- Expenses:Books $20.00
197
- Liabilities:MasterCard
198
- 2004/05/27 (100) Credit card company
199
- Liabilities:MasterCard $20.24
200
- Assets:Bank:Checking
223
+ 2004/05/27 Book Store
224
+ Expenses:Books $20.00
225
+ Liabilities:MasterCard
226
+ 2004/05/27 (100) Credit card company
227
+ Liabilities:MasterCard $20.24
228
+ Assets:Bank:Checking
201
229
  LEDGER
202
230
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reckon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Cantino
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-11-24 00:00:00.000000000 Z
13
+ date: 2024-03-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -72,16 +72,16 @@ dependencies:
72
72
  name: highline
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - ">="
75
+ - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: 1.5.2
77
+ version: '2.0'
78
78
  type: :runtime
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - ">="
82
+ - - "~>"
83
83
  - !ruby/object:Gem::Version
84
- version: 1.5.2
84
+ version: '2.0'
85
85
  - !ruby/object:Gem::Dependency
86
86
  name: rchardet
87
87
  requirement: !ruby/object:Gem::Requirement