clieop 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ clieop-*.gem
2
+ .svn/
3
+ .DS_Store
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2009 Willem van Bergen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,26 @@
1
+ = CLIEOP
2
+
3
+ This library is a pure Ruby implementation of the *CLIEOP03* format. Currently,
4
+ it only supports writing CLIEOP files with accounts receivable transactions.
5
+ Accounts payable transactions, and reading existing CLIEOP files is planned to be
6
+ supported
7
+
8
+ This library is licensed under the MIT license.
9
+
10
+ == CLIEOP format
11
+
12
+ CLIEOP03 is a file format that is used for communication about cash transaction
13
+ between bank accounts. It is used in the Netherlands and is supported by the
14
+ banking software packages of the main banks. CLIEOP supports transactions in both
15
+ directions: accounts payable and accounts receivable. For accounts receivable,
16
+ you need proper authorization from your bank.
17
+
18
+ For more information about the CLIEOP file format, see:
19
+ http://www.ingbank.nl/ing/downloadables/eclieop1.pdf
20
+
21
+ == Usage
22
+
23
+ Run <tt>gem install clieop -s http://gemcutter.org</tt> to install the gem.
24
+
25
+ See the project's wiki at http://wiki.github.com/wvanbergen/clieop for an example
26
+ creating and writing a direct debt batch file.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ Dir['tasks/*.rake'].each { |file| load(file) }
2
+
3
+ GithubGem::RakeTasks.new(:gem)
4
+ task :default => [:spec]
data/clieop.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'clieop'
3
+
4
+ # Do not set version and date yourself, this will be done automatically
5
+ # by the gem release script.
6
+ s.version = "0.1.1"
7
+ s.date = "2009-10-10"
8
+
9
+ s.summary = "A pure Ruby implementation to write CLIEOP files"
10
+ s.description = "This library is a pure Ruby, MIT licensed implementation of the CLIEOP03 transaction format. CLIEOP03 can be used to communicate direct debt transactions with your (Dutch) bank."
11
+
12
+ s.authors = ['Willem van Bergen']
13
+ s.email = ['willem@vanbergen.org']
14
+ s.homepage = 'http://github.com/wvanbergen/clieop/wikis'
15
+
16
+ # Do not set files and test_files yourself, this will be done automatically
17
+ # by the gem release script.
18
+ s.files = %w(.gitignore lib/clieop/record.rb lib/clieop/file.rb lib/clieop/batch.rb lib/clieop.rb Rakefile MIT-LICENSE test/clieop_writer_test.rb tasks/github-gem.rake clieop.gemspec README.rdoc)
19
+ s.test_files = %w(test/clieop_writer_test.rb)
20
+ end
@@ -0,0 +1,102 @@
1
+ module Clieop
2
+
3
+ class Batch
4
+
5
+ attr_accessor :transactions, :batch_info
6
+
7
+ def initialize(batch_info)
8
+ raise "Required: :description, :account_nr, :account_owner" unless ([:description, :account_nr, :account_owner] - batch_info.keys).empty?
9
+ @transactions = []
10
+ @batch_info = batch_info
11
+ end
12
+
13
+ # Adds a transaction to the batch
14
+ #
15
+ # :amount The amount involved with this transaction
16
+ # :account_nr The bank account from the other party
17
+ # :account_owner The name of the owner of the bank account
18
+ # :reference_number A reference number to identify this transaction
19
+ # :description A description for this transaction (4 lines max)
20
+ def add_transaction (transaction)
21
+ raise "No :account_nr given" if transaction[:account_nr].nil?
22
+ raise "No :amount given" if transaction[:amount].nil?
23
+ raise "No :account_owner given" if transaction[:account_owner].nil?
24
+ @transactions << transaction
25
+ end
26
+
27
+ alias_method :<<, :add_transaction
28
+
29
+ def to_clieop
30
+
31
+ # generate batch header records
32
+ batch_data = ""
33
+ batch_data << Clieop::Record.new(:batch_header,
34
+ :transaction_group => @batch_info[:transaction_group] || 0,
35
+ :acount_nr => @batch_info[:account_nr] || 0,
36
+ :serial_nr => @batch_info[:serial_nr] || 1,
37
+ :currency => @batch_info[:currency] || "EUR").to_clieop
38
+
39
+ batch_data << Clieop::Record.new(:batch_description, :description => @batch_info[:description]).to_clieop
40
+ batch_data << Clieop::Record.new(:batch_owner,
41
+ :process_date => @batch_info[:process_date] || 0,
42
+ :owner => @batch_info[:account_owner]).to_clieop
43
+
44
+ # initialize checksums
45
+ total_account = @batch_info[:account_nr].to_i * @transactions.length
46
+ total_amount = 0
47
+
48
+ # add transactions to batch
49
+ @transactions.each do |tr|
50
+
51
+ # update checksums
52
+ total_account += tr[:account_nr].to_i
53
+ total_amount += (tr[:amount].to_f * 100).truncate
54
+
55
+ # prepare data for this transaction's records
56
+ transaction_type = @batch_info[:transaction_group] == 10 ? 1002 : 0
57
+ to_account = @batch_info[:transaction_group] == 10 ? @batch_info[:account_nr] : tr[:account_nr]
58
+ from_account = @batch_info[:transaction_group] == 10 ? tr[:account_nr] : @batch_info[:account_nr]
59
+ amount_in_cents = (tr[:amount].to_f * 100).truncate
60
+ name_record = @batch_info[:transaction_group] == 10 ? :invoice_name : :payment_name
61
+
62
+ # generate transaction record
63
+ batch_data << Clieop::Record.new(:transaction_info,
64
+ :transaction_type => transaction_type, :amount => amount_in_cents,
65
+ :to_account => to_account, :from_account => from_account).to_clieop
66
+
67
+ # generate record with transaction information
68
+ batch_data << Clieop::Record.new(name_record, :name => tr[:account_owner]).to_clieop
69
+ batch_data << Clieop::Record.new(:transaction_reference, :reference_number => tr[:reference_number]).to_clieop unless tr[:reference_number].nil?
70
+
71
+ # split discription into lines and make a record for the first 4 lines
72
+ unless tr[:description].nil? || tr[:description] == ''
73
+ tr[:description].split(/\r?\n/)[0, 4].each do |line|
74
+ batch_data << Clieop::Record.new(:transaction_description, :description => line.strip).to_s unless line == ''
75
+ end
76
+ end
77
+ end
78
+
79
+ # generate batch footer record including some checks
80
+ batch_data << Clieop::Record.new(:batch_footer, :tranasction_count => @transactions.length,
81
+ :total_amount => total_amount, :account_checksum => total_account.to_s[0..10]).to_clieop
82
+
83
+ end
84
+
85
+ def to_s
86
+ self.to_clieop
87
+ end
88
+
89
+ # creates a batch for payments from a given account
90
+ def self.payment_batch(batch_info = {})
91
+ batch_info[:transaction_group] ||= 0
92
+ Clieop::Batch.new(batch_info)
93
+ end
94
+
95
+ # creates a batch for invoices to a given account
96
+ def self.invoice_batch(batch_info = {})
97
+ batch_info[:transaction_group] ||= 10
98
+ Clieop::Batch.new(batch_info)
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,43 @@
1
+ module Clieop
2
+
3
+ class File
4
+
5
+ attr_accessor :batches
6
+ attr_reader :file_info
7
+
8
+ def initialize(file_info = {})
9
+ file_info[:date] = Date.today unless file_info[:date]
10
+ file_info[:date] = file_info[:date].strftime('%d%m%y') if file_info[:date].respond_to?(:strftime)
11
+ @file_info = file_info
12
+ @batches = []
13
+ end
14
+
15
+ # renders this file as a CLIEOP03 formatted string
16
+ def to_clieop
17
+ clieop_data = Clieop::Record.new(:file_header, @file_info).to_clieop
18
+ @batches.each { |batch| clieop_data << batch.to_clieop }
19
+ clieop_data << Clieop::Record.new(:file_footer).to_clieop
20
+ end
21
+
22
+ # Alias for to_clieop
23
+ alias :to_s :to_clieop
24
+
25
+ def payment_batch(options)
26
+ @payment << Clieop::Batch.payment_batch(options, block)
27
+ yield(@batches.last) if block_given?
28
+ return @batches.last
29
+ end
30
+
31
+ def invoice_batch(options)
32
+ @batches << Clieop::Batch.invoice_batch(options)
33
+ yield(@batches.last) if block_given?
34
+ return @batches.last
35
+ end
36
+
37
+ def save(filename)
38
+ File.open(filename, 'w') do |f|
39
+ f.write(self.to_clieop)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,115 @@
1
+ module Clieop
2
+
3
+ class Record
4
+
5
+ TYPE_DEFINITIONS = {
6
+ :file_header => [
7
+ [:record_code, :numeric, 4, 1],
8
+ [:record_variant, :alpha, 1, 'A'],
9
+ [:date, :numeric, 6],
10
+ [:filename, :alpha, 8, 'CLIEOP03'],
11
+ [:sender_identification, :alpha, 5],
12
+ [:file_identification, :alpha, 4],
13
+ [:duplicate_code, :numeric, 1, 1]
14
+ ],
15
+ :file_footer => [
16
+ [:record_code, :numeric, 4, 9999],
17
+ [:record_variant, :alpha, 1, 'A'],
18
+ ],
19
+ :batch_header => [
20
+ [:record_code, :numeric, 4, 10],
21
+ [:record_variant, :alpha, 1, 'B'],
22
+ [:transaction_group, :alpha, 2],
23
+ [:acount_nr, :numeric, 10],
24
+ [:serial_nr, :numeric, 4],
25
+ [:currency, :alpha, 3, 'EUR']
26
+ ],
27
+ :batch_footer => [
28
+ [:record_code, :numeric, 4, 9990],
29
+ [:record_variant, :alpha, 1, 'A'],
30
+ [:total_amount, :numeric, 18],
31
+ [:account_checksum, :numeric, 10],
32
+ [:tranasction_count, :numeric, 7],
33
+ ],
34
+ :batch_description => [
35
+ [:record_code, :numeric, 4, 20],
36
+ [:record_variant, :alpha, 1, 'A'],
37
+ [:description, :alpha, 32]
38
+ ],
39
+ :batch_owner => [
40
+ [:record_code, :numeric, 4, 30],
41
+ [:record_variant, :alpha, 1, 'B'],
42
+ [:naw_code, :numeric, 1, 1],
43
+ [:process_date, :numeric, 6, 0],
44
+ [:owner, :alpha, 35],
45
+ [:test, :alpha, 1, 'P']
46
+ ],
47
+ :transaction_info => [
48
+ [:record_code, :numeric, 4, 100],
49
+ [:record_variant, :alpha, 1, 'A'],
50
+ [:transaction_type, :numeric, 4, 1002],
51
+ [:amount, :numeric, 12],
52
+ [:from_account, :numeric, 10],
53
+ [:to_account, :numeric, 10],
54
+ ],
55
+ :invoice_name => [
56
+ [:record_code, :numeric, 4, 110],
57
+ [:record_variant, :alpha, 1, 'B'],
58
+ [:name, :alpha, 35],
59
+ ],
60
+ :payment_name =>[
61
+ [:record_code, :numeric, 4, 170],
62
+ [:record_variant, :alpha, 1, 'B'],
63
+ [:name, :alpha, 35],
64
+ ],
65
+ :transaction_reference => [
66
+ [:record_code, :numeric, 4, 150],
67
+ [:record_variant, :alpha, 1, 'A'],
68
+ [:reference_number, :numeric, 16],
69
+ ],
70
+ :transaction_description => [
71
+ [:record_code, :numeric, 4, 160],
72
+ [:record_variant, :alpha, 1, 'A'],
73
+ [:description, :alpha, 32],
74
+ ],
75
+ }
76
+
77
+ attr_accessor :definition, :data
78
+
79
+ def initialize record_type, record_data = {}
80
+
81
+ # load record definition
82
+ raise "Unknown record type" unless Clieop::Record::TYPE_DEFINITIONS[record_type.to_sym]
83
+ @definition = Clieop::Record::TYPE_DEFINITIONS[record_type.to_sym]
84
+
85
+ # set default values according to definition
86
+ @data = {}
87
+ @definition.each { |field| @data[field[0]] = field[3] if field[3] }
88
+
89
+ # set values for all the provided data
90
+ record_data.each { |field, value| @data[field] = value }
91
+ end
92
+
93
+ def to_clieop
94
+ line = ""
95
+ #format each field
96
+ @definition.each do |field|
97
+ fmt = '%'
98
+ fmt << (field[1] == :numeric ? '0' : '-')
99
+ fmt << (field[2].to_s)
100
+ fmt << (field[1] == :numeric ? 'd' : 's')
101
+ raw_data = (field[1] == :numeric) ? @data[field[0]].to_i : @data[field[0]]
102
+ value = sprintf(fmt, raw_data)
103
+ line << (field[1] == :numeric ? value[0 - field[2], field[2]] : value[0, field[2]])
104
+ end
105
+ # fill each line with spaces up to 50 characters and close with a CR/LF
106
+ line.ljust(50) + "\r\n"
107
+ end
108
+
109
+ def to_s
110
+ self.to_clieop
111
+ end
112
+
113
+ end
114
+
115
+ end
data/lib/clieop.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'date'
2
+ require 'clieop/record.rb'
3
+ require 'clieop/file.rb'
4
+ require 'clieop/batch.rb'
@@ -0,0 +1,323 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/tasklib'
4
+ require 'date'
5
+ require 'git'
6
+
7
+ module GithubGem
8
+
9
+ # Detects the gemspc file of this project using heuristics.
10
+ def self.detect_gemspec_file
11
+ FileList['*.gemspec'].first
12
+ end
13
+
14
+ # Detects the main include file of this project using heuristics
15
+ def self.detect_main_include
16
+ if detect_gemspec_file =~ /^(\.*)\.gemspec$/ && File.exist?("lib/#{$1}.rb")
17
+ "lib/#{$1}.rb"
18
+ elsif FileList['lib/*.rb'].length == 1
19
+ FileList['lib/*.rb'].first
20
+ else
21
+ nil
22
+ end
23
+ end
24
+
25
+ class RakeTasks
26
+
27
+ attr_reader :gemspec, :modified_files, :git
28
+ attr_accessor :gemspec_file, :task_namespace, :main_include, :root_dir, :spec_pattern, :test_pattern, :remote, :remote_branch, :local_branch
29
+
30
+ # Initializes the settings, yields itself for configuration
31
+ # and defines the rake tasks based on the gemspec file.
32
+ def initialize(task_namespace = :gem)
33
+ @gemspec_file = GithubGem.detect_gemspec_file
34
+ @task_namespace = task_namespace
35
+ @main_include = GithubGem.detect_main_include
36
+ @modified_files = []
37
+ @root_dir = Dir.pwd
38
+ @test_pattern = 'test/**/*_test.rb'
39
+ @spec_pattern = 'spec/**/*_spec.rb'
40
+ @local_branch = 'master'
41
+ @remote = 'origin'
42
+ @remote_branch = 'master'
43
+
44
+ yield(self) if block_given?
45
+
46
+ @git = Git.open(@root_dir)
47
+ load_gemspec!
48
+ define_tasks!
49
+ end
50
+
51
+ protected
52
+
53
+ # Define Unit test tasks
54
+ def define_test_tasks!
55
+ require 'rake/testtask'
56
+
57
+ namespace(:test) do
58
+ Rake::TestTask.new(:basic) do |t|
59
+ t.pattern = test_pattern
60
+ t.verbose = true
61
+ t.libs << 'test'
62
+ end
63
+ end
64
+
65
+ desc "Run all unit tests for #{gemspec.name}"
66
+ task(:test => ['test:basic'])
67
+ end
68
+
69
+ # Defines RSpec tasks
70
+ def define_rspec_tasks!
71
+ require 'spec/rake/spectask'
72
+
73
+ namespace(:spec) do
74
+ desc "Verify all RSpec examples for #{gemspec.name}"
75
+ Spec::Rake::SpecTask.new(:basic) do |t|
76
+ t.spec_files = FileList[spec_pattern]
77
+ end
78
+
79
+ desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
80
+ Spec::Rake::SpecTask.new(:specdoc) do |t|
81
+ t.spec_files = FileList[spec_pattern]
82
+ t.spec_opts << '--format' << 'specdoc' << '--color'
83
+ end
84
+
85
+ desc "Run RCov on specs for #{gemspec.name}"
86
+ Spec::Rake::SpecTask.new(:rcov) do |t|
87
+ t.spec_files = FileList[spec_pattern]
88
+ t.rcov = true
89
+ t.rcov_opts = ['--exclude', '"spec/*,gems/*"', '--rails']
90
+ end
91
+ end
92
+
93
+ desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
94
+ task(:spec => ['spec:specdoc'])
95
+ end
96
+
97
+ # Defines the rake tasks
98
+ def define_tasks!
99
+
100
+ define_test_tasks! if has_tests?
101
+ define_rspec_tasks! if has_specs?
102
+
103
+ namespace(@task_namespace) do
104
+ desc "Updates the filelist in the gemspec file"
105
+ task(:manifest) { manifest_task }
106
+
107
+ desc "Builds the .gem package"
108
+ task(:build => :manifest) { build_task }
109
+
110
+ desc "Sets the version of the gem in the gemspec"
111
+ task(:set_version => [:check_version, :check_current_branch]) { version_task }
112
+ task(:check_version => :fetch_origin) { check_version_task }
113
+
114
+ task(:fetch_origin) { fetch_origin_task }
115
+ task(:check_current_branch) { check_current_branch_task }
116
+ task(:check_clean_status) { check_clean_status_task }
117
+ task(:check_not_diverged => :fetch_origin) { check_not_diverged_task }
118
+
119
+ checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
120
+ checks.unshift('spec:basic') if has_specs?
121
+ checks.unshift('test:basic') if has_tests?
122
+ checks.push << [:check_rubyforge] if gemspec.rubyforge_project
123
+
124
+ desc "Perform all checks that would occur before a release"
125
+ task(:release_checks => checks)
126
+
127
+ release_tasks = [:release_checks, :set_version, :build, :github_release]
128
+ release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
129
+
130
+ desc "Release a new verison of the gem"
131
+ task(:release => release_tasks) { release_task }
132
+
133
+ task(:check_rubyforge) { check_rubyforge_task }
134
+ task(:rubyforge_release) { rubyforge_release_task }
135
+ task(:github_release => [:commit_modified_files, :tag_version]) { github_release_task }
136
+ task(:tag_version) { tag_version_task }
137
+ task(:commit_modified_files) { commit_modified_files_task }
138
+
139
+ desc "Updates the gem release tasks with the latest version on Github"
140
+ task(:update_tasks) { update_tasks_task }
141
+ end
142
+ end
143
+
144
+ # Updates the files list and test_files list in the gemspec file using the list of files
145
+ # in the repository and the spec/test file pattern.
146
+ def manifest_task
147
+ # Load all the gem's files using "git ls-files"
148
+ repository_files = git.ls_files.keys
149
+ test_files = Dir[test_pattern] + Dir[spec_pattern]
150
+
151
+ update_gemspec(:files, repository_files)
152
+ update_gemspec(:test_files, repository_files & test_files)
153
+ end
154
+
155
+ # Builds the gem
156
+ def build_task
157
+ sh "gem build -q #{gemspec_file}"
158
+ Dir.mkdir('pkg') unless File.exist?('pkg')
159
+ sh "mv #{gemspec.name}-#{gemspec.version}.gem pkg/#{gemspec.name}-#{gemspec.version}.gem"
160
+ end
161
+
162
+ # Updates the version number in the gemspec file, the VERSION constant in the main
163
+ # include file and the contents of the VERSION file.
164
+ def version_task
165
+ update_gemspec(:version, ENV['VERSION']) if ENV['VERSION']
166
+ update_gemspec(:date, Date.today)
167
+
168
+ update_version_file(gemspec.version)
169
+ update_version_constant(gemspec.version)
170
+ end
171
+
172
+ def check_version_task
173
+ raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
174
+ proposed_version = Gem::Version.new(ENV['VERSION'] || gemspec.version)
175
+ # Loads the latest version number using the created tags
176
+ newest_version = git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max
177
+ raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version && newest_version >= proposed_version
178
+ end
179
+
180
+ # Checks whether the current branch is not diverged from the remote branch
181
+ def check_not_diverged_task
182
+ raise "The current branch is diverged from the remote branch!" if git.log.between('HEAD', git.remote(remote).branch(remote_branch).gcommit).any?
183
+ end
184
+
185
+ # Checks whether the repository status ic clean
186
+ def check_clean_status_task
187
+ raise "The current working copy contains modifications" if git.status.changed.any?
188
+ end
189
+
190
+ # Checks whether the current branch is correct
191
+ def check_current_branch_task
192
+ raise "Currently not on #{local_branch} branch!" unless git.branch.name == local_branch.to_s
193
+ end
194
+
195
+ # Fetches the latest updates from Github
196
+ def fetch_origin_task
197
+ git.fetch('origin')
198
+ end
199
+
200
+ # Commits every file that has been changed by the release task.
201
+ def commit_modified_files_task
202
+ if modified_files.any?
203
+ modified_files.each { |file| git.add(file) }
204
+ git.commit("Released #{gemspec.name} gem version #{gemspec.version}")
205
+ end
206
+ end
207
+
208
+ # Adds a tag for the released version
209
+ def tag_version_task
210
+ git.add_tag("#{gemspec.name}-#{gemspec.version}")
211
+ end
212
+
213
+ # Pushes the changes and tag to github
214
+ def github_release_task
215
+ git.push(remote, remote_branch, true)
216
+ end
217
+
218
+ # Checks whether Rubyforge is configured properly
219
+ def check_rubyforge_task
220
+ # Login no longer necessary when using rubyforge 2.0.0 gem
221
+ # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
222
+ output = `rubyforge names`.split("\n")
223
+ raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
224
+ raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
225
+ end
226
+
227
+ # Task to release the .gem file toRubyforge.
228
+ def rubyforge_release_task
229
+ sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
230
+ end
231
+
232
+ # Gem release task.
233
+ # All work is done by the task's dependencies, so just display a release completed message.
234
+ def release_task
235
+ puts
236
+ puts '------------------------------------------------------------'
237
+ puts "Released #{gemspec.name} version #{gemspec.version}"
238
+ end
239
+
240
+ private
241
+
242
+ # Checks whether this project has any RSpec files
243
+ def has_specs?
244
+ FileList[spec_pattern].any?
245
+ end
246
+
247
+ # Checks whether this project has any unit test files
248
+ def has_tests?
249
+ FileList[test_pattern].any?
250
+ end
251
+
252
+ # Loads the gemspec file
253
+ def load_gemspec!
254
+ @gemspec = eval(File.read(@gemspec_file))
255
+ end
256
+
257
+ # Updates the VERSION file with the new version
258
+ def update_version_file(version)
259
+ if File.exists?('VERSION')
260
+ File.open('VERSION', 'w') { |f| f << version.to_s }
261
+ modified_files << 'VERSION'
262
+ end
263
+ end
264
+
265
+ # Updates the VERSION constant in the main include file if it exists
266
+ def update_version_constant(version)
267
+ if main_include && File.exist?(main_include)
268
+ file_contents = File.read(main_include)
269
+ if file_contents.sub!(/^(\s+VERSION\s*=\s*)[^\s].*$/) { $1 + version.to_s.inspect }
270
+ File.open(main_include, 'w') { |f| f << file_contents }
271
+ modified_files << main_include
272
+ end
273
+ end
274
+ end
275
+
276
+ # Updates an attribute of the gemspec file.
277
+ # This function will open the file, and search/replace the attribute using a regular expression.
278
+ def update_gemspec(attribute, new_value, literal = false)
279
+
280
+ unless literal
281
+ new_value = case new_value
282
+ when Array then "%w(#{new_value.join(' ')})"
283
+ when Hash, String then new_value.inspect
284
+ when Date then new_value.strftime('%Y-%m-%d').inspect
285
+ else raise "Cannot write value #{new_value.inspect} to gemspec file!"
286
+ end
287
+ end
288
+
289
+ spec = File.read(gemspec_file)
290
+ regexp = Regexp.new('^(\s+\w+\.' + Regexp.quote(attribute.to_s) + '\s*=\s*)[^\s].*$')
291
+ if spec.sub!(regexp) { $1 + new_value }
292
+ File.open(gemspec_file, 'w') { |f| f << spec }
293
+ modified_files << gemspec_file
294
+
295
+ # Reload the gemspec so the changes are incorporated
296
+ load_gemspec!
297
+ end
298
+ end
299
+
300
+ # Updates the tasks file using the latest file found on Github
301
+ def update_tasks_task
302
+ require 'net/http'
303
+
304
+ server = 'github.com'
305
+ path = '/wvanbergen/github-gem/raw/master/tasks/github-gem.rake'
306
+
307
+ Net::HTTP.start(server) do |http|
308
+ response = http.get(path)
309
+ open(__FILE__, "w") { |file| file.write(response.body) }
310
+ end
311
+
312
+ relative_file = File.expand_path(__FILE__).sub(%r[^#{git.dir.path}/], '')
313
+ if git.status[relative_file] && git.status[relative_file].type == 'M'
314
+ git.add(relative_file)
315
+ git.commit("Updated to latest gem release management tasks.")
316
+ puts "Updated to latest version of gem release management tasks."
317
+ else
318
+ puts "Release managament tasks already are at the latest version."
319
+ end
320
+ end
321
+
322
+ end
323
+ end
@@ -0,0 +1,33 @@
1
+ $:.unshift("#{File.dirname(__FILE__)}/../lib")
2
+
3
+ require 'test/unit'
4
+ require 'clieop'
5
+
6
+ class ClieopWriterTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ end
10
+
11
+ def teardown
12
+ end
13
+
14
+ def test_basic_invoice_usage
15
+ file = Clieop::File.new
16
+ file.invoice_batch({:description => 'some description', :account_nr => 123, :account_owner => 'me'}) do |batch|
17
+
18
+ batch << { :account_nr => 123456, :account_owner => 'you', :amount => 133.0,
19
+ :description => "Testing a CLIEOP direct debt transaction\nCharging your bank account" }
20
+
21
+ batch << { :account_nr => 654321, :account_owner => 'somebody else', :amount => 233.0,
22
+ :description => 'Some description for the other guy' }
23
+
24
+ end
25
+
26
+ clieop_data = file.to_clieop
27
+
28
+ #TODO: more tests
29
+ assert_kind_of String, clieop_data
30
+
31
+ end
32
+
33
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clieop
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Willem van Bergen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-10 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: This library is a pure Ruby, MIT licensed implementation of the CLIEOP03 transaction format. CLIEOP03 can be used to communicate direct debt transactions with your (Dutch) bank.
17
+ email:
18
+ - willem@vanbergen.org
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - .gitignore
27
+ - lib/clieop/record.rb
28
+ - lib/clieop/file.rb
29
+ - lib/clieop/batch.rb
30
+ - lib/clieop.rb
31
+ - Rakefile
32
+ - MIT-LICENSE
33
+ - test/clieop_writer_test.rb
34
+ - tasks/github-gem.rake
35
+ - clieop.gemspec
36
+ - README.rdoc
37
+ has_rdoc: true
38
+ homepage: http://github.com/wvanbergen/clieop/wikis
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: A pure Ruby implementation to write CLIEOP files
65
+ test_files:
66
+ - test/clieop_writer_test.rb