transactions 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d1fb2dde0117abbbd982a133959573444cb4b0fd
4
+ data.tar.gz: 27fbf80ef838f35511f3a9337ac7746c159b811f
5
+ SHA512:
6
+ metadata.gz: dfc5cc11724b32935bfb1b63936404109f9d384a3936dd28ab899e32ac0e11d55e51ef58491dfe9312d83ba62fcf6eb921bbd2f4d7091655e83c4e2d8b80d33c
7
+ data.tar.gz: e7d1c09de955ccde03a27024783c3eb9e5bd3ea7e6e4a875712da422ad03cd9ef30724ae6aa934d8b2437318762e242d326b9aa39b832ebb55b809c03c3298dc
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ## version 0.1.0 (2013-06-27)
2
+ ---
3
+ * Initial Release
4
+ * Added additional unit tests
5
+ * Authored README.md
6
+
7
+
8
+ ## version 0.0.0 (2013-06-26)
9
+ ---
10
+ * Happy Birthday!
11
+
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2013 Randy Schneck
2
+
3
+ The MIT License (MIT)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,245 @@
1
+ # [transactions](http://computercrayons.com/transactions)
2
+
3
+ ## Description
4
+
5
+ transactions is a command line application for managing your finances using a
6
+ plain text format (yaml or json). All transactions are written to a text file
7
+ by hand similar to a checkbook register. This text file is your ledger and it
8
+ can handle most financial bookkeeping needs.
9
+
10
+
11
+ ## Installation
12
+
13
+ ### Requirements
14
+
15
+ Before you can get started with *transaction*, the following must be installed
16
+ on your system. Note that RubyGems is included with Ruby since version 1.9.
17
+
18
+ * [Ruby](http://www.ruby-lang.org/en/downloads/)
19
+ * [RubyGems](http://rubygems.org/pages/download)
20
+
21
+ The best way to install transactions is via RubyGems. At the terminal prompt, run
22
+ the following command:
23
+
24
+ `gem install transactions`
25
+
26
+
27
+ ## Additional Information
28
+
29
+ ### Using the program
30
+
31
+ 1. create a ledger file
32
+ * you can copy and paste the example ledger below into a text file named
33
+ "ledger.yaml" if you just want to try out the program. If this is your
34
+ style of bookkeeping, then just edit the file with your own info using
35
+ your favorite text editor.
36
+ * run this command `transactions bal` and see the output.
37
+ * by default, "transactions" looks in the current directory for a file
38
+ named "ledger.yaml".
39
+ * you can use the -f option to specify a different file (eg. `transactions
40
+ -f example.yaml bal`)
41
+ 2. run `transactions reg`
42
+ * this is a register for all transactions
43
+ * notice that every transaction prints multiple times
44
+ * this happens because each transaction affects multiple accounts
45
+ 3. to make the register more useful try `transactions reg assets:checking`
46
+ * this will limit the register to assets:checking (case is ignored)
47
+ * this would be equivalent to printing a checkbook register from
48
+ "ledger.yaml"
49
+ * more than one account can be included eg. assets:checking expenses:food
50
+ * this limit by string of text also works with the balance command.
51
+ 4. see keeping a ledger below for information about general accounting
52
+ principles to help you with your own ledger.
53
+
54
+
55
+ ### Sample Ledger File
56
+
57
+ # This is a sample ledger file
58
+ # this line and the one above are comments that will be ignored
59
+ # during processing! Comments can also be placed at the end of
60
+ # a line (see below for examples).
61
+
62
+ - date: 2013/01/01
63
+ transaction: Opening Balances
64
+ Assets:Checking: 251.0
65
+ Assets:Savings: 5005.3
66
+ Assets:IRA: 22510.92
67
+ Liabilities:CreditCard: -931.32
68
+ Liabilities:Salliemae: -10189.05
69
+ Equity:OpeningBalances: -16646.85
70
+
71
+ - date: 2013/01/07
72
+ transaction: Trader Joe's
73
+ Expenses:Food:Groceries: 58.77
74
+ Assets:Checking: -58.77
75
+
76
+ - date: 2013/01/09
77
+ transaction: Student Loan Payment
78
+ Liabilities:Salliemae: 103.3
79
+ Expenses:Interest:StudentLoan: 15.04
80
+ Assets:Checking: -118.34
81
+
82
+ - date: 2013/02/11
83
+ transaction: Deposit Paycheck
84
+ Assets:Checking: 1242.87
85
+ Income:JobName: -1242.87
86
+
87
+ - date: 2013/02/11
88
+ transaction: Visa Payment
89
+ Expenses:Interest:CreditCard: 10.0
90
+ Liabilities:CreditCard: 130.0
91
+ Assets:Checking: -140.0
92
+
93
+ - date: 2013/02/25
94
+ transaction: PG&E
95
+ Expenses:Utilities:Electric: 75
96
+ Assets:Checking: -75
97
+
98
+ - date: 2013/02/25
99
+ transaction: Verizon # Switch to Virgin Mobile
100
+ Expenses:Phone: 55.72
101
+ Assets:Checking: -55.72
102
+
103
+ - date: 2013/02/26
104
+ transaction: Ike's Lair # good sandwich
105
+ Expenses:Food:Dining: 22.31
106
+ Assets:Checking: -22.31
107
+
108
+ # a transaction requires only one space as a separator but can also be
109
+ # aligned as above. The choice is yours!
110
+
111
+ - date: 2013/02/26
112
+ transaction: Money Transfer
113
+ Assets:Savings: 494.7
114
+ Assets:Checking: -494.7
115
+
116
+
117
+
118
+ ### Keeping a Ledger
119
+
120
+ Although the program doesn't limit you on naming your accounts, it is highly
121
+ recommended to use some standard conventions in order to facilitate easier
122
+ understanding of your finances by your accountant. The five base accounts that
123
+ you should use are:
124
+
125
+ + Assets
126
+ * what you own
127
+ * a debit or withdrawal will be a negative number
128
+ * a deposit will be a positive number
129
+ + Liabilities
130
+ * what you owe
131
+ * a payment towards a liability will be a positive number
132
+ * borrowing on a liability will be a negative number
133
+ + Equity
134
+ * what you have accumulated over time
135
+ * Equity = Assets - Liabilities
136
+ + Income
137
+ * your earnings from society
138
+ * this will always be a negative number (seems weird but you'll get used to
139
+ it)
140
+ * think of Income as a withdrawal from society and that is why it is
141
+ negative
142
+ + Expenses
143
+ * things you spent your assets on or incurred liabilities for
144
+ * a purchase or expense will be a positive number
145
+ * a return or refund will be a negative number
146
+
147
+ Everything falls under one of these five categories but also belongs in a
148
+ sub-account. Sub-accounts are created by appending a colon and the name of the
149
+ sub-account after one of the main accounts. Some examples for account names
150
+ could then be `Assets:Savings`, `Income:My Job`, `Expenses:Food:Groceries`,
151
+ `Expenses:Food:Dining`, `Liabilities:Credit Card`.
152
+
153
+ See the example ledger above for the complete syntax.
154
+
155
+
156
+ ### Start your own ledger
157
+
158
+ 1. Create an empty text file named "ledger.yaml"
159
+ 2. Enter your opening balances as the first transaction using the Equity
160
+ account (see example ledger above)
161
+ * The accounting equation that makes this work is `Equity = Assets -
162
+ Liabilities`
163
+ * Your Assets are positive numbers (unless your checking account is in the
164
+ negative == BAD!)
165
+ * Your Liabilities are negative since they bring down your net worth
166
+ * The difference of your Assets and Liabilities is balanced to zero with
167
+ the equity account.
168
+ * A negative equity in our ledger means a positive net worth (your assets
169
+ are greater than your liabilities).
170
+ * A positive equity in our ledger means a negative net worth (your
171
+ liabilities are greater than your assets).
172
+ 3. Enter transactions (be consistent with your account naming).
173
+ 4. The best way to be consistent is to run `transactions bal` to see all your
174
+ accounts before creating your new entry.
175
+ 5. Transaction names can be whatever you want to help remind you of the
176
+ transaction.
177
+ 6. The date is formatted as `YYYY/MM/DD` (this is important for the date
178
+ limiting options to function)
179
+
180
+
181
+ ### Some (hopefully) Helpful Notes
182
+
183
+ * Assets, Liabilities, and Equity accounts are called "Real" accounts since
184
+ their balances are not zeroed out at the end of an accounting period.
185
+ * While this is unfortunate in the case of your Liabilities, it is
186
+ beneficial to your Assets.
187
+ * Income and Expense accounts are called "Nominal" accounts since they begin at
188
+ zero at the start of a new accounting period.
189
+ * Income is used for expenses, to pay liabilities, or put into an asset
190
+ account as it comes in from society and thus starts at zero every
191
+ accounting period
192
+ * Expenses start over every accounting period (you can't claim already
193
+ claimed Expenses
194
+
195
+
196
+ ### Examples
197
+
198
+ Trial Balance - list of all accounts in the ledger and their balances
199
+
200
+ transactions balance
201
+
202
+ Balance Sheet - What you own and owe
203
+
204
+ transactions balance assets liabilities
205
+
206
+ Income Statement - measures cash flow / profitability (income vs expenses)
207
+
208
+ transactions balance income expenses
209
+
210
+ Limit by date
211
+
212
+ transactions -b 2013/01/01 -e 2013/12/31 balance
213
+
214
+ * this will show the entire year of 2013 inclusive of the dates used as
215
+ arguments.
216
+ * the date limits work for balance, register, and print commands.
217
+ * the totals for income and expenses will be accurate with date limits since
218
+ they are nominal accounts that reset at the beginning of a new accounting
219
+ period.
220
+ * the totals for assets and liabilities are the amounts that the accounts
221
+ changed during the accounting period. To see the totals that you actually
222
+ have in your assets or liabilities the date limits must be left out.
223
+
224
+
225
+ ## Contributing
226
+
227
+ How to get your work merged into the project?
228
+
229
+ * Fork the project.
230
+ * Clone your fork ( git clone git@github.com:<username>/transactions.git ).
231
+ * Create a topic branch for your change ( git checkout -b my_new_feature ).
232
+ * Hack away, add tests. Not necessarily in that order.
233
+ * Make sure everything still passes by running rake.
234
+ * If necessary, rebase your commits into logical chunks, without errors.
235
+ * Push the branch up ( git push origin my_new_feature ).
236
+ * Create a pull request against randyschneck/transactions and describe what
237
+ your change does and the why you think it should be merged.
238
+
239
+
240
+ ## Credits
241
+
242
+ Written by Randy A. Schneck (rasch@computercrayons.com)
243
+
244
+ see [LICENSE.md](https://github.com/randyschneck/transactions/blob/master/LICENSE.md)
245
+
data/bin/transactions ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib") # For use/testing when not installed
4
+
5
+ require 'transactions'
6
+
7
+ t = Transaction::Parser.new
8
+
9
+ if ARGV[0]
10
+ command = ARGV[0]
11
+ unless %w(balance bal register reg print).include? command
12
+ puts "That's not an option. Type 'transactions --help' for more info."
13
+ end
14
+ t.send(:parse, "balance") if %w(balance bal).include? command
15
+ t.send(:parse, "register") if %w(register reg).include? command
16
+ t.send(:parse, "print") if 'print' == command
17
+ else
18
+ puts "At least one command is required. Type 'transactions --help' for more info."
19
+ end
20
+
@@ -0,0 +1,12 @@
1
+ $:.unshift File.dirname(__FILE__) # For use/testing when not installed
2
+
3
+ # stdlib
4
+ require 'yaml'
5
+ require 'optparse'
6
+
7
+ # internal requires
8
+ require 'transactions/version'
9
+ require 'transactions/options'
10
+ require 'transactions/main'
11
+ require 'transactions/parser'
12
+
@@ -0,0 +1,32 @@
1
+ module Transaction
2
+
3
+ class Parser
4
+
5
+ def initialize
6
+ @options = Options.new.options
7
+ @default_ledger = 'ledger.yaml'
8
+ if @options[:file]
9
+ ledger = File.read @options[:file]
10
+ else
11
+ if File.exists? File.expand_path(@default_ledger)
12
+ ledger = File.read(File.expand_path(@default_ledger))
13
+ else
14
+ abort "There is no 'ledger.yaml' file in the current directory."
15
+ end
16
+ end
17
+ @ledger = YAML::load ledger if ledger != ""
18
+ @ledger = [] if ledger == ""
19
+ @date = Time.now.strftime "%Y/%m/%d"
20
+ if @options[:sort] == 'tran' # sort by transaction
21
+ @ledger.sort_by! { |h| h['transaction'] }
22
+ elsif @options[:sort] == 'date' # sort by date
23
+ @ledger.sort_by! { |h| h['date'] }
24
+ end
25
+ end
26
+
27
+ include Transaction
28
+
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1,89 @@
1
+ module Transaction
2
+
3
+ class Options
4
+
5
+ def initialize
6
+ @options = {}
7
+ end
8
+
9
+ def options
10
+ OptionParser.new do |opts|
11
+
12
+ opts.banner = "Usage: transactions [options] COMMAND [ARGS] ..."
13
+
14
+ opts.on("-f", "--file PATH", "PATH to yaml file to parse") do |x|
15
+ @options[:file] = x
16
+ end
17
+
18
+ opts.on("-c", "--current",
19
+ "don't include entries with future dates") do |x|
20
+ @options[:current] = x
21
+ end
22
+
23
+ opts.on("-b", "--begin DATE", "set begin date, DATE: YYYY/MM/DD") do |x|
24
+ @options[:begin] = x
25
+ end
26
+
27
+ opts.on("-e", "--end DATE", "set end date, DATE: YYYY/MM/DD") do |x|
28
+ @options[:end] = x
29
+ end
30
+
31
+ opts.on("-s", "--subtotal", "show sub-totals for balance") do |x|
32
+ @options[:subtotal] = x
33
+ end
34
+
35
+ opts.on("-E", "--empty", "show accounts with zero balance") do |x|
36
+ @options[:empty] = x
37
+ end
38
+
39
+ opts.on("-S", "--sort ARG", "sort by field, ARG can be date or tran") do |x|
40
+ @options[:sort] = x
41
+ end
42
+
43
+ opts.on("-w", "--wide", "print 132 columns wide for register") do |x|
44
+ @options[:wide] = x
45
+ end
46
+
47
+ #opts.on("-C", "--cleared", "only include cleared transactions") do |x|
48
+ # @options[:cleared] = x
49
+ #end
50
+
51
+ #opts.on("-U", "--uncleared", "only include uncleared transactions") do |x|
52
+ # @options[:uncleared] = x
53
+ #end
54
+
55
+ opts.on_tail("-h", "--help", "show this help message") do
56
+ puts opts
57
+ abort self.commands_help
58
+ end
59
+
60
+ opts.on_tail("-v", "--version", "show version") do
61
+ abort "#{Transaction::VERSION}"
62
+ end
63
+
64
+ end.parse!
65
+
66
+ @options
67
+
68
+ end
69
+
70
+
71
+ def commands_help
72
+ <<-COMMANDHELP
73
+
74
+ COMMANDS
75
+ --------
76
+ balance [ACCOUNT].. Prints account balances, limited to ACCOUNTS.
77
+ 'bal' can be used as a shortcut.
78
+ register [ACCOUNT].. Prints account register, limited to ACCOUNTS.
79
+ 'reg' can be used as a shortcut.
80
+ print Prints transactions formatted for export to ledger.
81
+ Can be limited by date but not ACCOUNT.
82
+ COMMANDHELP
83
+ end
84
+
85
+
86
+ end
87
+
88
+ end
89
+
@@ -0,0 +1,162 @@
1
+ module Transaction
2
+
3
+ def parse(cmd)
4
+
5
+ @accounts = {}
6
+ @running_total = 0
7
+
8
+ def transaction_print(x)
9
+ puts "#{x['date']} #{x['transaction']}"
10
+ x.each do |k, v |
11
+ puts sprintf(" %-30.30s % .2f", k, v) if v.is_a? Numeric
12
+ end
13
+ puts ""
14
+ end
15
+
16
+ def transaction_balance(k, v)
17
+ @accounts[k] += v if v.is_a? Numeric
18
+ end
19
+
20
+ def transaction_register(x, k, v, running_total)
21
+ if v.is_a? Numeric
22
+ if @options[:wide] # for printing 132 columns wide
23
+ t = "%10s %-44s %-44s %15.2f %15.2f"
24
+ puts sprintf(t, x['date'], x['transaction'][0..42],
25
+ k[0..42], v, running_total)
26
+ else # for printing 78 columns wide (default)
27
+ t = "%10s %-20s %-24s %10.2f %10.2f"
28
+ puts sprintf(t, x['date'], x['transaction'][0..18],
29
+ k[0..22], v, running_total)
30
+ end
31
+ end
32
+ end
33
+
34
+ def transaction_command(cmd, x, k, v)
35
+ ARGV.map! { |z| z.downcase }
36
+ if ARGV[1..-1].any? { |arg| k.downcase.include? arg }
37
+ @running_total += v if v.is_a? Numeric
38
+ if cmd == 'print'
39
+ transaction_print(x)
40
+ elsif cmd == 'balance'
41
+ transaction_balance(k, v)
42
+ elsif cmd == 'register'
43
+ transaction_register(x, k, v, @running_total)
44
+ end
45
+ elsif !ARGV[1]
46
+ @running_total += v if v.is_a? Numeric
47
+ if cmd == 'print'
48
+ transaction_print(x)
49
+ elsif cmd == 'balance'
50
+ transaction_balance(k, v)
51
+ elsif cmd == 'register'
52
+ transaction_register(x, k, v, @running_total)
53
+ end
54
+ end
55
+ end
56
+
57
+ @ledger.each do |x|
58
+ total = 0
59
+ x.each do |k, v|
60
+ total += v if v.is_a? Numeric
61
+ @accounts[k] ||= 0 if v.is_a? Numeric
62
+
63
+ if @options[:current]
64
+ if @options[:begin]
65
+ if x['date'] <= @date && x['date'] >= @options[:begin]
66
+ transaction_command(cmd, x, k, v); break if cmd == 'print'
67
+ end
68
+ else
69
+ if x['date'] <= @date
70
+ transaction_command(cmd, x, k, v); break if cmd == 'print'
71
+ end
72
+ end
73
+ elsif @options[:begin] || @options[:end]
74
+ if @options[:begin] && @options[:end]
75
+ if @options[:begin] <= x['date'] and x['date'] <= @options[:end]
76
+ transaction_command(cmd, x, k, v); break if cmd == 'print'
77
+ end
78
+ elsif @options[:begin]
79
+ if x['date'] >= @options[:begin]
80
+ transaction_command(cmd, x, k, v); break if cmd == 'print'
81
+ end
82
+ elsif @options[:end]
83
+ if x['date'] <= @options[:end]
84
+ transaction_command(cmd, x, k, v); break if cmd == 'print'
85
+ end
86
+ end
87
+ else
88
+ transaction_command(cmd, x, k, v); break if cmd == 'print'
89
+ end
90
+ end
91
+ if total.round(2) != 0
92
+ abort <<-EOF
93
+ You have an UNBALANCED Transaction
94
+ #{x}
95
+ Your total is off by #{sprintf("%.2f", -total)}
96
+ EOF
97
+ end
98
+ end
99
+
100
+
101
+ if cmd == 'balance'
102
+ accounts_total = 0
103
+ main_accounts = {}
104
+
105
+ if ARGV[1] && !@options[:subtotal]
106
+ ARGV[1..-1].each do |arg|
107
+ @accounts.sort.each do |k, v|
108
+ if k.downcase.include? arg
109
+ accounts_total += v
110
+ v = v.round(2)
111
+ if @options[:empty]
112
+ puts sprintf("%16.2f %s", v, k)
113
+ else
114
+ puts sprintf("%16.2f %s", v, k) if v != 0
115
+ end
116
+ end
117
+ end
118
+ end
119
+ puts "#{'-' * 16}"
120
+ puts sprintf("%16.2f", accounts_total)
121
+
122
+ elsif @options[:subtotal]
123
+ summary_total = 0
124
+ @accounts.each do |k, v|
125
+ x = k.split(':')
126
+ main_accounts[x[0].to_sym] ||= 0
127
+ main_accounts[x[0].to_sym] += v
128
+ main_accounts.each do |account, value|
129
+ main_accounts[account] = value.round(2)
130
+ end
131
+ end
132
+ main_accounts.sort.each do |k, v|
133
+ if ARGV[1]
134
+ ARGV.map! { |x| x.downcase }
135
+ ARGV[1..-1].each do |arg|
136
+ puts "#{sprintf("%16.2f %s", v, k)}" if k.to_s.downcase.include? arg
137
+ summary_total += v if k.to_s.downcase.include? arg
138
+ end
139
+ else
140
+ puts "#{sprintf("%16.2f %s", v, k)}"
141
+ summary_total += v
142
+ end
143
+ end
144
+ puts "#{"-" * 16}"
145
+ puts "#{sprintf("%16.2f", summary_total.round(2))}"
146
+
147
+ else
148
+ @accounts.sort.each do |k, v|
149
+ v = v.round(2)
150
+ if @options[:empty]
151
+ puts sprintf("%16.2f %s", v, k)
152
+ else
153
+ puts sprintf("%16.2f %s", v, k) if v != 0
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+
160
+ end
161
+ end
162
+
@@ -0,0 +1,4 @@
1
+ module Transaction
2
+ VERSION = "0.1.0"
3
+ end
4
+
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: transactions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Randy Schneck
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |2
14
+ A small but powerful command line application to help manage finances.
15
+ Transactions are entered into a text file using yaml and reports are
16
+ generated by parsing this data.
17
+ email: rasch@computercrayons.com
18
+ executables:
19
+ - transactions
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - bin/transactions
24
+ - lib/transactions/main.rb
25
+ - lib/transactions/options.rb
26
+ - lib/transactions/parser.rb
27
+ - lib/transactions/version.rb
28
+ - lib/transactions.rb
29
+ - LICENSE.md
30
+ - README.md
31
+ - CHANGELOG.md
32
+ homepage: https://github.com/randyschneck/transactions
33
+ licenses:
34
+ - MIT
35
+ metadata: {}
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 2.0.2
53
+ signing_key:
54
+ specification_version: 4
55
+ summary: A bookkeeping application to help manage your finances.
56
+ test_files: []