instance_accountant 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 659797969092d787410c4789f8379c33b9b10ccb
4
- data.tar.gz: 0c858e6a0c0a6ae6f7bec5877cbbf450f6de665c
3
+ metadata.gz: 19a81626ec5302f9c0ae2bdd455c7aa70c2384f3
4
+ data.tar.gz: 611a5db14d5b5284b16d5935e72df9df4148381d
5
5
  SHA512:
6
- metadata.gz: a442d471310a881effe735f4b7d6ff5118af02e238e20e908178e5e845409cc51a4c123e08e9f0acebac655badec7cc0fbd4278a7e8a21d20c95d03132015af6
7
- data.tar.gz: cb5df07e2c58e9905134bf3d1683846f1ddeaa41cffb503b68e6dc6c99d5fb36a7119693c31e86553cf64a0e2b71ac3093636bf527a796528a68c17e0141f872
6
+ metadata.gz: 948d6d0a669a3fa5ed8e6543cb93063e3ced2e46e875ab06c85169c034cfe196be66598cbe28cc0504d436951923299091cb380c6810f03d8708b8c3312690e5
7
+ data.tar.gz: ff0797c01fb181fe887300fd8740a29ac0196882c51fc7f3c6a51cc96118585c11782afb742151cb97141eb60b476773473448ac72b688b7a26eb941a4917d06
data/README.md CHANGED
@@ -10,13 +10,12 @@ Gemfile:
10
10
 
11
11
  The gem provides an executable that can be invoked two ways:
12
12
 
13
- If you want to account for the hourly cost of instances, use this form:
13
+ 1) you want to account for the hourly cost of instances:
14
+
15
+ #!/bin/bash
14
16
 
15
17
  instance_accountant account \
16
- --description 'instance usage for: %s' \
17
- --reference 'http://test.com/journal_entry' \
18
18
  --cost 0.1 \
19
- --cost_description 'cost for: %s' \
20
19
  --cost_reference 'http://test.com/cost' \
21
20
  --expense_acct subledger_account_id \
22
21
  --payable_acct subledger_account_id \
@@ -24,30 +23,24 @@ If you want to account for the hourly cost of instances, use this form:
24
23
  --secret subledger_secret \
25
24
  --org_id subledger_org_id \
26
25
  --book_id subledger_book_id \
27
- --daemon
26
+ --daemon 2>&1 >> instance_accountant.log
27
+
28
+ 2) you want to account for both the hourly cost and income:
28
29
 
29
- If you want to account for both the hourly cost of instances, and hourly income instances, use this form:
30
+ #!/bin/bash
30
31
 
31
32
  instance_accountant account \
32
- --description 'instance usage for: %s' \
33
- --reference 'http://test.com/journal_entry' \
34
33
  --cost 0.1 \
35
- --cost_description 'cost for: %s' \
36
- --cost_reference 'http://test.com/cost' \
37
34
  --expense_acct subledger_account_id \
38
35
  --payable_acct subledger_account_id \
39
36
  --price 0.2 \
40
- --price_description 'price for: %s' \
41
- --price_reference 'http://test.com/price' \
42
37
  --receivable_acct subledger_account_id \
43
38
  --income_acct subledger_account_id \
44
39
  --key_id subledger_key_id \
45
40
  --secret subledger_secret \
46
41
  --org_id subledger_org_id \
47
42
  --book_id subledger_book_id \
48
- --daemon
49
-
50
- Note: %s in descriptions will be replaced by the ISO 8601 of the hour in UTC
43
+ --daemon 2>&1 >> instance_accountant.log
51
44
 
52
45
  Here's a complete set of options:
53
46
 
@@ -55,17 +48,17 @@ Here's a complete set of options:
55
48
  f, [--filepath=FILEPATH]
56
49
  # Default: ~/.instance_accountant
57
50
  d, --description=DESCRIPTION
58
- # Default: instance usage for
51
+ # Default: instance usage for: %
59
52
  [--reference=REFERENCE]
60
53
  c, --cost=COST
61
54
  [--cost-description=COST_DESCRIPTION]
62
- # Default: cost for
55
+ # Default: instance cost for: %
63
56
  [--cost-reference=COST_REFERENCE]
64
57
  e, --expense-acct=EXPENSE_ACCT
65
58
  p, --payable-acct=PAYABLE_ACCT
66
59
  p, [--price=PRICE]
67
60
  [--price-description=PRICE_DESCRIPTION]
68
- # Default: price for
61
+ # Default: instance price for %
69
62
  [--price-reference=PRICE_REFERENCE]
70
63
  i, [--income-acct=INCOME_ACCT]
71
64
  r, [--receivable-acct=RECEIVABLE_ACCT]
@@ -74,3 +67,6 @@ Here's a complete set of options:
74
67
  o, --org-id=ORG_ID
75
68
  b, --book-id=BOOK_ID
76
69
  [--daemon], [--no-daemon]
70
+
71
+ Note: %s in descriptions will be replaced by the ISO 8601 of the hour in UTC
72
+ Note: instance_accountant captures errors and does its best to keep running
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = Dir.glob( 'spec/**/*.rb' )
18
18
 
19
19
  gem.name = 'instance_accountant'
20
- gem.description = 'account for hourly instance usage using Subledger'
20
+ gem.description = File.read 'README.md'
21
21
  gem.summary = 'account for hourly instance usage using Subledger'
22
22
  gem.version = InstanceAccountant::VERSION
23
23
  gem.email = 'admin@subledger.com'
@@ -14,7 +14,7 @@ module InstanceAccountant
14
14
  method_option :description,
15
15
  aliases: :d,
16
16
  required: true,
17
- default: 'instance usage for'
17
+ default: 'instance usage for: %'
18
18
 
19
19
  method_option :reference
20
20
 
@@ -22,7 +22,7 @@ module InstanceAccountant
22
22
  aliases: :c,
23
23
  required: true
24
24
  method_option :cost_description,
25
- default: 'cost for'
25
+ default: 'instance cost for: %'
26
26
 
27
27
  method_option :cost_reference
28
28
 
@@ -38,7 +38,7 @@ module InstanceAccountant
38
38
  aliases: :p
39
39
 
40
40
  method_option :price_description,
41
- default: 'price for'
41
+ default: 'instnace price for: %'
42
42
 
43
43
  method_option :price_reference
44
44
 
@@ -68,7 +68,7 @@ module InstanceAccountant
68
68
 
69
69
  SIGNALS = []
70
70
 
71
- TWENTY_MINUTES = 20 * 60
71
+ SECONDS_BETWEEN_ATTEMPTS = 10
72
72
 
73
73
  %w(ABRT ALRM HUP INT STOP TERM QUIT).each do |signal|
74
74
  Signal.trap signal do
@@ -96,10 +96,12 @@ module InstanceAccountant
96
96
 
97
97
  def consider_posting i, options
98
98
  Poster.new(options).post(Hour.new, Time.now) if posting_required? i
99
+ rescue Exception => e
100
+ STDERR.puts e
99
101
  end
100
102
 
101
103
  def posting_required? i
102
- (i % TWENTY_MINUTES).zero? or signal?
104
+ (i % SECONDS_BETWEEN_ATTEMPTS).zero? or signal?
103
105
  end
104
106
 
105
107
  def consider_exiting
@@ -10,24 +10,26 @@ module InstanceAccountant
10
10
  end
11
11
 
12
12
  def read
13
- @time_klass.parse @file_klass.open( @filepath,
14
- File::RDWR | File::CREAT,
15
- 0644 ) do |file|
13
+ hour_string = nil
14
+
15
+ @file_klass.open( @filepath, 'r' ) do |file|
16
16
  file.flock File::LOCK_EX
17
- file.read
17
+ hour_string = file.read
18
18
  end
19
+
20
+ @time_klass.parse hour_string
19
21
  rescue
20
22
  nil
21
23
  end
22
24
 
23
25
  def write hour
24
- hour_string = hour.to_s
26
+ hour_string = hour.hour_string
25
27
 
26
28
  @file_klass.open( @filepath,
27
29
  File::RDWR | File::CREAT,
28
30
  0644 ) do |file|
29
31
  file.flock File::LOCK_EX
30
- file.rewind
32
+ file.truncate 0
31
33
  file.write hour_string
32
34
  end
33
35
 
@@ -4,5 +4,5 @@ require 'instance_accountant/hour'
4
4
  require 'instance_accountant/poster'
5
5
 
6
6
  module InstanceAccountant
7
- VERSION = '0.0.1'
7
+ VERSION = '0.0.2'
8
8
  end
@@ -4,15 +4,15 @@ require 'helpers'
4
4
  require 'instance_accountant/filer'
5
5
 
6
6
  module InstanceAccountant
7
- Class File do
7
+ Class Filer do
8
8
  Instance do
9
9
  subject { Filer.new options }
10
10
 
11
11
  let(:options) do
12
12
  {
13
- filepath: filepath,
14
13
  file_klass: file_klass,
15
- time_klass: time_klass
14
+ time_klass: time_klass,
15
+ filepath: filepath
16
16
  }
17
17
  end
18
18
 
@@ -22,10 +22,28 @@ module InstanceAccountant
22
22
  let(:time_klass) { double 'time_klass' }
23
23
  let(:time_inst) { double 'time_inst' }
24
24
 
25
- let(:time_string) { double 'time_string' }
25
+ let(:hour_string) { double 'hour_string' }
26
26
  let(:hour) { double 'hour' }
27
27
 
28
+ let(:file) { double 'file' }
29
+
28
30
  RespondsTo :read do
31
+ When 'it has not been written before' do
32
+ ByReturning nil do
33
+ expect(file_klass)
34
+ .to receive(:expand_path)
35
+ .with(filepath)
36
+ .and_return(expanded_filepath)
37
+
38
+ expect(file_klass)
39
+ .to receive(:open)
40
+ .with(expanded_filepath, 'r')
41
+ .and_raise(Errno::ENOENT)
42
+
43
+ subject.read.must_be_nil
44
+ end
45
+ end
46
+
29
47
  When 'it has been written before' do
30
48
  ByReturning 'a Time' do
31
49
  expect(file_klass)
@@ -35,12 +53,20 @@ module InstanceAccountant
35
53
 
36
54
  expect(file_klass)
37
55
  .to receive(:open)
38
- .with(expanded_filepath, File::RDWR | File::CREAT, 0644)
39
- .and_return(time_string)
56
+ .with(expanded_filepath, 'r')
57
+ .and_yield(file)
58
+
59
+ expect(file)
60
+ .to receive(:flock)
61
+ .with(File::LOCK_EX)
62
+
63
+ expect(file)
64
+ .to receive(:read)
65
+ .and_return(hour_string)
40
66
 
41
67
  expect(time_klass)
42
68
  .to receive(:parse)
43
- .with(time_string)
69
+ .with(hour_string)
44
70
  .and_return(time_inst)
45
71
 
46
72
  subject.read.must_be_same_as time_inst
@@ -56,15 +82,27 @@ module InstanceAccountant
56
82
  .and_return(expanded_filepath)
57
83
 
58
84
  expect(hour)
59
- .to receive(:to_s)
60
- .and_return(time_string)
85
+ .to receive(:hour_string)
86
+ .and_return(hour_string)
61
87
 
62
88
  expect(file_klass)
63
89
  .to receive(:open)
64
90
  .with(expanded_filepath, File::RDWR | File::CREAT, 0644)
65
- .and_return(time_string)
91
+ .and_yield(file)
92
+
93
+ expect(file)
94
+ .to receive(:flock)
95
+ .with(File::LOCK_EX)
96
+
97
+ expect(file)
98
+ .to receive(:truncate)
99
+ .with(0)
100
+
101
+ expect(file)
102
+ .to receive(:write)
103
+ .with(hour_string)
66
104
 
67
- subject.write(hour).must_be_same_as time_string
105
+ subject.write(hour).must_be_same_as hour_string
68
106
  end
69
107
  end
70
108
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instance_accountant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Mornini
@@ -165,7 +165,79 @@ dependencies:
165
165
  - - "~>"
166
166
  - !ruby/object:Gem::Version
167
167
  version: '0.27'
168
- description: account for hourly instance usage using Subledger
168
+ description: |
169
+ Subledger instance accountant Ruby gem
170
+
171
+ Installation:
172
+
173
+ gem install instance_accountant
174
+
175
+ Gemfile:
176
+
177
+ gem 'instance_accountant'
178
+
179
+ The gem provides an executable that can be invoked two ways:
180
+
181
+ 1) you want to account for the hourly cost of instances:
182
+
183
+ #!/bin/bash
184
+
185
+ instance_accountant account \
186
+ --cost 0.1 \
187
+ --cost_reference 'http://test.com/cost' \
188
+ --expense_acct subledger_account_id \
189
+ --payable_acct subledger_account_id \
190
+ --key_id subledger_key_id \
191
+ --secret subledger_secret \
192
+ --org_id subledger_org_id \
193
+ --book_id subledger_book_id \
194
+ --daemon 2>&1 >> instance_accountant.log
195
+
196
+ 2) you want to account for both the hourly cost and income:
197
+
198
+ #!/bin/bash
199
+
200
+ instance_accountant account \
201
+ --cost 0.1 \
202
+ --expense_acct subledger_account_id \
203
+ --payable_acct subledger_account_id \
204
+ --price 0.2 \
205
+ --receivable_acct subledger_account_id \
206
+ --income_acct subledger_account_id \
207
+ --key_id subledger_key_id \
208
+ --secret subledger_secret \
209
+ --org_id subledger_org_id \
210
+ --book_id subledger_book_id \
211
+ --daemon 2>&1 >> instance_accountant.log
212
+
213
+ Here's a complete set of options:
214
+
215
+ Options:
216
+ f, [--filepath=FILEPATH]
217
+ # Default: ~/.instance_accountant
218
+ d, --description=DESCRIPTION
219
+ # Default: instance usage for: %
220
+ [--reference=REFERENCE]
221
+ c, --cost=COST
222
+ [--cost-description=COST_DESCRIPTION]
223
+ # Default: instance cost for: %
224
+ [--cost-reference=COST_REFERENCE]
225
+ e, --expense-acct=EXPENSE_ACCT
226
+ p, --payable-acct=PAYABLE_ACCT
227
+ p, [--price=PRICE]
228
+ [--price-description=PRICE_DESCRIPTION]
229
+ # Default: instance price for %
230
+ [--price-reference=PRICE_REFERENCE]
231
+ i, [--income-acct=INCOME_ACCT]
232
+ r, [--receivable-acct=RECEIVABLE_ACCT]
233
+ k, --key-id=KEY_ID
234
+ s, --secret=SECRET
235
+ o, --org-id=ORG_ID
236
+ b, --book-id=BOOK_ID
237
+ [--daemon], [--no-daemon]
238
+
239
+ Note: %s in descriptions will be replaced by the ISO 8601 of the hour in UTC
240
+ Note: instance_accountant captures errors and does its best to keep running
169
241
  email: admin@subledger.com
170
242
  executables:
171
243
  - instance_accountant