ore-core 0.1.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.
Files changed (67) hide show
  1. data/.document +4 -0
  2. data/.rspec +1 -0
  3. data/.yardopts +1 -0
  4. data/ChangeLog.md +17 -0
  5. data/GemspecYML.md +284 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +68 -0
  8. data/Rakefile +25 -0
  9. data/gemspec.yml +18 -0
  10. data/lib/ore.rb +3 -0
  11. data/lib/ore/checks.rb +88 -0
  12. data/lib/ore/defaults.rb +140 -0
  13. data/lib/ore/dependency.rb +65 -0
  14. data/lib/ore/document_file.rb +118 -0
  15. data/lib/ore/exceptions.rb +3 -0
  16. data/lib/ore/exceptions/exception.rb +4 -0
  17. data/lib/ore/exceptions/invalid_metadata.rb +6 -0
  18. data/lib/ore/exceptions/project_not_found.rb +6 -0
  19. data/lib/ore/naming.rb +113 -0
  20. data/lib/ore/paths.rb +146 -0
  21. data/lib/ore/project.rb +599 -0
  22. data/lib/ore/settings.rb +274 -0
  23. data/lib/ore/specification.rb +29 -0
  24. data/lib/ore/versions.rb +3 -0
  25. data/lib/ore/versions/exceptions.rb +1 -0
  26. data/lib/ore/versions/exceptions/invalid_version.rb +8 -0
  27. data/lib/ore/versions/version.rb +75 -0
  28. data/lib/ore/versions/version_constant.rb +126 -0
  29. data/lib/ore/versions/version_file.rb +66 -0
  30. data/lib/rubygems_plugin.rb +40 -0
  31. data/ore-core.gemspec +6 -0
  32. data/spec/dependency_spec.rb +36 -0
  33. data/spec/document_file_spec.rb +29 -0
  34. data/spec/helpers/files.rb +7 -0
  35. data/spec/helpers/files/.document +5 -0
  36. data/spec/helpers/files/VERSION +1 -0
  37. data/spec/helpers/files/VERSION.yml +5 -0
  38. data/spec/helpers/projects.rb +13 -0
  39. data/spec/helpers/projects/dm-is-plugin/Gemfile +3 -0
  40. data/spec/helpers/projects/dm-is-plugin/VERSION +1 -0
  41. data/spec/helpers/projects/dm-is-plugin/dm-is-plugin.gemspec +10 -0
  42. data/spec/helpers/projects/dm-is-plugin/gemspec.yml +9 -0
  43. data/spec/helpers/projects/dm-is-plugin/lib/dm-is-plugin.rb +4 -0
  44. data/spec/helpers/projects/dm-is-plugin/lib/dm-is-plugin/is/plugin.rb +6 -0
  45. data/spec/helpers/projects/explicit/gemspec.yml +19 -0
  46. data/spec/helpers/projects/explicit/lib/explicit/version.rb +15 -0
  47. data/spec/helpers/projects/ffi-binding/gemspec.yml +11 -0
  48. data/spec/helpers/projects/ffi-binding/lib/ffi/binding/version.rb +5 -0
  49. data/spec/helpers/projects/jewelery/VERSION +1 -0
  50. data/spec/helpers/projects/jewelery/bin/jewelery +3 -0
  51. data/spec/helpers/projects/jewelery/gemspec.yml +6 -0
  52. data/spec/helpers/projects/jewelery/jewelery.gemspec +10 -0
  53. data/spec/helpers/projects/jewelery/lib/jewelery.rb +4 -0
  54. data/spec/helpers/projects/jewelery/lib/jewelery/rubies.rb +4 -0
  55. data/spec/helpers/projects/minimal/gemspec.yml +4 -0
  56. data/spec/helpers/projects/minimal/lib/minimal.rb +2 -0
  57. data/spec/naming_spec.rb +56 -0
  58. data/spec/projects/dm_plugin_project_spec.rb +29 -0
  59. data/spec/projects/explicit_project_spec.rb +37 -0
  60. data/spec/projects/ffi_binding_project_spec.rb +25 -0
  61. data/spec/projects/jeweler_project_spec.rb +17 -0
  62. data/spec/projects/minimal_project_spec.rb +17 -0
  63. data/spec/projects/project_examples.rb +40 -0
  64. data/spec/spec_helper.rb +4 -0
  65. data/spec/versions/version_file_spec.rb +28 -0
  66. data/spec/versions/version_spec.rb +53 -0
  67. metadata +170 -0
@@ -0,0 +1,146 @@
1
+ require 'ore/naming'
2
+
3
+ module Ore
4
+ #
5
+ # A mixin for {Project} which provides methods for working with paths.
6
+ #
7
+ module Paths
8
+ include Naming
9
+
10
+ #
11
+ # Builds a path relative to the project.
12
+ #
13
+ # @param [Array] names
14
+ # The directory names of the path.
15
+ #
16
+ # @return [Pathname]
17
+ # The new path.
18
+ #
19
+ def path(*names)
20
+ @root.join(*names)
21
+ end
22
+
23
+ #
24
+ # The `bin/` directory of the project.
25
+ #
26
+ # @return [Pathname]
27
+ # The path to the `bin/` directory.
28
+ #
29
+ def bin_dir
30
+ @root.join(@@lib_dir)
31
+ end
32
+
33
+ #
34
+ # The `lib/` directory of the project.
35
+ #
36
+ # @return [Pathname]
37
+ # The path to the `lib/` directory.
38
+ #
39
+ def lib_dir
40
+ @root.join(@@lib_dir)
41
+ end
42
+
43
+ #
44
+ # The `pkg/` directory of the project.
45
+ #
46
+ # @return [Pathname]
47
+ # The path to the `pkg/` directory.
48
+ #
49
+ def pkg_dir
50
+ @root.join(@@pkg_dir)
51
+ end
52
+
53
+ #
54
+ # Builds a path relative to the `lib/` directory.
55
+ #
56
+ # @param [Array] names
57
+ # The directory names of the path.
58
+ #
59
+ # @return [Pathname]
60
+ # The new path.
61
+ #
62
+ def lib_path(*names)
63
+ path(@@lib_dir,*names)
64
+ end
65
+
66
+ #
67
+ # Builds a relative path into the `pkg/` directory for the `.gem` file.
68
+ #
69
+ # @return [String]
70
+ # The path of a `.gem` file for the project.
71
+ #
72
+ def pkg_file
73
+ File.join(@@pkg_dir,"#{@name}-#{@version}.gem")
74
+ end
75
+
76
+ #
77
+ # Determines if a directory exists within the project.
78
+ #
79
+ # @param [String] path
80
+ # The path of the directory, relative to the project.
81
+ #
82
+ # @return [Boolean]
83
+ # Specifies whether the directory exists in the project.
84
+ #
85
+ def directory?(path)
86
+ @root.join(path).directory?
87
+ end
88
+
89
+ #
90
+ # Determines if a file exists within the project.
91
+ #
92
+ # @param [String] path
93
+ # The path of the file, relative to the project.
94
+ #
95
+ # @return [Boolean]
96
+ # Specifies whether the file exists in the project.
97
+ #
98
+ def file?(path)
99
+ @project_files.include?(path)
100
+ end
101
+
102
+ #
103
+ # Determines if a directory exists within the `lib/` directory of the
104
+ # project.
105
+ #
106
+ # @return [Boolean]
107
+ # Specifies that the directory exists within the `lib/` directory.
108
+ #
109
+ def lib_directory?(path)
110
+ directory?(File.join(@@lib_dir,path))
111
+ end
112
+
113
+ #
114
+ # Determines if a file exists within the `lib/` directory of the
115
+ # project.
116
+ #
117
+ # @return [Boolean]
118
+ # Specifies that the file exists within the `lib/` directory.
119
+ #
120
+ def lib_file?(path)
121
+ file?(File.join(@@lib_dir,path))
122
+ end
123
+
124
+ #
125
+ # Finds paths within the project that match a glob pattern.
126
+ #
127
+ # @param [String] pattern
128
+ # The glob pattern.
129
+ #
130
+ # @yield [path]
131
+ # The given block will be passed matching paths.
132
+ #
133
+ # @yieldparam [String] path
134
+ # A path relative to the root directory of the project.
135
+ #
136
+ def glob(pattern)
137
+ within do
138
+ Dir.glob(pattern) do |path|
139
+ if (@project_files.include?(path) || File.directory?(path))
140
+ yield path
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,599 @@
1
+ require 'ore/exceptions/project_not_found'
2
+ require 'ore/exceptions/invalid_metadata'
3
+ require 'ore/naming'
4
+ require 'ore/paths'
5
+ require 'ore/checks'
6
+ require 'ore/defaults'
7
+ require 'ore/settings'
8
+ require 'ore/document_file'
9
+
10
+ require 'pathname'
11
+ require 'yaml'
12
+ require 'find'
13
+ require 'fileutils'
14
+
15
+ module Ore
16
+ #
17
+ # Combinds the metadata from the `gemspec.yml` file and the inferred
18
+ # information from the project directory.
19
+ #
20
+ class Project
21
+
22
+ include Naming
23
+ include Paths
24
+ include Checks
25
+ include Defaults
26
+ include Settings
27
+
28
+ # The project metadata file
29
+ @@metadata_file = 'gemspec.yml'
30
+
31
+ # The root directory of the project
32
+ attr_reader :root
33
+
34
+ # The SCM which the project is currently under
35
+ attr_reader :scm
36
+
37
+ # The files of the project
38
+ attr_reader :project_files
39
+
40
+ # The fully-qualified namespace of the project
41
+ attr_reader :namespace
42
+
43
+ # The infered namespace modules of the project
44
+ attr_reader :namespace_modules
45
+
46
+ # The directory contain the project code.
47
+ attr_reader :namespace_dir
48
+
49
+ # The name of the project
50
+ attr_reader :name
51
+
52
+ # The version of the project
53
+ attr_reader :version
54
+
55
+ # The project summary
56
+ attr_reader :summary
57
+
58
+ # The project description
59
+ attr_reader :description
60
+
61
+ # The licenses of the project
62
+ attr_reader :licenses
63
+
64
+ # The authors of the project
65
+ attr_reader :authors
66
+
67
+ # The homepage for the project
68
+ attr_reader :homepage
69
+
70
+ # The email contact for the project
71
+ attr_reader :email
72
+
73
+ # The build date for any project gems
74
+ attr_reader :date
75
+
76
+ # The parsed `.document` file
77
+ attr_reader :document
78
+
79
+ # The directories to search within the project when requiring files
80
+ attr_reader :require_paths
81
+
82
+ # The names of the executable scripts
83
+ attr_reader :executables
84
+
85
+ # The default executable
86
+ attr_reader :default_executable
87
+
88
+ # The documentation of the project
89
+ attr_reader :documentation
90
+
91
+ # Any extra files to include in the project documentation
92
+ attr_reader :extra_doc_files
93
+
94
+ # The files of the project
95
+ attr_reader :files
96
+
97
+ # The test files for the project
98
+ attr_reader :test_files
99
+
100
+ # Any external requirements needed by the project
101
+ attr_reader :requirements
102
+
103
+ # The version of Ruby required by the project
104
+ attr_reader :required_ruby_version
105
+
106
+ # The version of RubyGems required by the project
107
+ attr_reader :required_rubygems_version
108
+
109
+ # The dependencies of the project
110
+ attr_reader :dependencies
111
+
112
+ # The runtime-dependencies of the project
113
+ attr_reader :runtime_dependencies
114
+
115
+ # The development-dependencies of the project
116
+ attr_reader :development_dependencies
117
+
118
+ # The post-installation message
119
+ attr_reader :post_install_message
120
+
121
+ #
122
+ # Creates a new {Project}.
123
+ #
124
+ # @param [String] root
125
+ # The root directory of the project.
126
+ #
127
+ def initialize(root)
128
+ @root = Pathname.new(root).expand_path
129
+
130
+ unless @root.directory?
131
+ raise(ProjectNotFound,"#{@root} is not a directory")
132
+ end
133
+
134
+ infer_scm!
135
+ infer_project_files!
136
+
137
+ metadata_file = @root.join(@@metadata_file)
138
+
139
+ unless metadata_file.file?
140
+ raise(ProjectNotFound,"#{@root} does not contain #{@@metadata_file}")
141
+ end
142
+
143
+ metadata = YAML.load_file(metadata_file)
144
+
145
+ unless metadata.kind_of?(Hash)
146
+ raise(InvalidMetadata,"#{metadata_file} did not contain valid metadata")
147
+ end
148
+
149
+ if metadata['name']
150
+ @name = metadata['name'].to_s
151
+ else
152
+ default_name!
153
+ end
154
+
155
+ # infer the namespace from the project name
156
+ infer_namespace!
157
+
158
+ if metadata['version']
159
+ set_version! metadata['version']
160
+ else
161
+ default_version!
162
+ end
163
+
164
+ @summary = (metadata['summary'] || metadata['description'])
165
+ @description = (metadata['description'] || metadata['summary'])
166
+
167
+ @licenses = []
168
+
169
+ if metadata['license']
170
+ set_license!(metadata['license'])
171
+ end
172
+
173
+ @authors = []
174
+
175
+ if metadata['authors']
176
+ set_authors! metadata['authors']
177
+ end
178
+
179
+ @homepage = metadata['homepage']
180
+ @email = metadata['email']
181
+
182
+ if metadata['date']
183
+ set_date! metadata['date']
184
+ else
185
+ default_date!
186
+ end
187
+
188
+ @document = DocumentFile.find(self)
189
+
190
+ @require_paths = []
191
+
192
+ if metadata['require_paths']
193
+ set_require_paths! metadata['require_paths']
194
+ else
195
+ default_require_paths!
196
+ end
197
+
198
+ @executables = []
199
+
200
+ if metadata['executables']
201
+ set_executables! metadata['executables']
202
+ else
203
+ default_executables!
204
+ end
205
+
206
+ @default_executable = nil
207
+
208
+ if metadata['default_executable']
209
+ set_default_executable! metadata['default_executable']
210
+ else
211
+ default_executable!
212
+ end
213
+
214
+ if metadata['has_yard']
215
+ @documentation = :yard
216
+ elsif metadata.has_key?('has_rdoc')
217
+ @documentation = if metadata['has_rdoc']
218
+ :rdoc
219
+ end
220
+ else
221
+ default_documentation!
222
+ end
223
+
224
+ @extra_doc_files = []
225
+
226
+ if metadata['extra_doc_files']
227
+ set_extra_doc_files! metadata['extra_doc_files']
228
+ else
229
+ default_extra_doc_files!
230
+ end
231
+
232
+ @files = []
233
+
234
+ if metadata['files']
235
+ set_files! metadata['files']
236
+ else
237
+ default_files!
238
+ end
239
+
240
+ @test_files = []
241
+
242
+ if metadata['test_files']
243
+ set_test_files! metadata['test_files']
244
+ else
245
+ default_test_files!
246
+ end
247
+
248
+ if metadata['post_install_message']
249
+ set_post_install_message! metadata['post_install_message']
250
+ end
251
+
252
+ @requirements = []
253
+
254
+ if metadata['requirements']
255
+ set_requirements! metadata['requirements']
256
+ end
257
+
258
+ if metadata['required_ruby_version']
259
+ set_required_ruby_version! metadata['required_ruby_version']
260
+ end
261
+
262
+ if metadata['required_rubygems_version']
263
+ set_required_rubygems_version! metadata['required_rubygems_version']
264
+ else
265
+ default_required_rubygems_version!
266
+ end
267
+
268
+ @dependencies = []
269
+
270
+ if metadata['dependencies']
271
+ set_dependencies! metadata['dependencies']
272
+ end
273
+
274
+ @runtime_dependencies = []
275
+
276
+ if metadata['runtime_dependencies']
277
+ set_runtime_dependencies! metadata['runtime_dependencies']
278
+ end
279
+
280
+ @development_dependencies = []
281
+
282
+ if metadata['development_dependencies']
283
+ set_development_dependencies! metadata['development_dependencies']
284
+ end
285
+ end
286
+
287
+ #
288
+ # Finds the project metadata file and creates a new {Project} object.
289
+ #
290
+ # @param [String] dir (Dir.pwd)
291
+ # The directory to start searching upward from.
292
+ #
293
+ # @return [Project]
294
+ # The found project.
295
+ #
296
+ # @raise [ProjectNotFound]
297
+ # No project metadata file could be found.
298
+ #
299
+ def self.find(dir=Dir.pwd)
300
+ Pathname.new(dir).ascend do |root|
301
+ return self.new(root) if root.join(@@metadata_file).file?
302
+ end
303
+
304
+ raise(ProjectNotFound,"could not find #{@@metadata_file}")
305
+ end
306
+
307
+ #
308
+ # Executes code within the project.
309
+ #
310
+ # @param [String] sub_dir
311
+ # An optional sub-directory within the project to execute from.
312
+ #
313
+ # @yield []
314
+ # The given block will be called once the current working-directory
315
+ # has been switched. Once the block finishes executing, the current
316
+ # working-directory will be switched back.
317
+ #
318
+ # @see http://ruby-doc.org/core/classes/Dir.html#M002314
319
+ #
320
+ def within(sub_dir=nil,&block)
321
+ dir = if sub_dir
322
+ @root.join(sub_dir)
323
+ else
324
+ @root
325
+ end
326
+
327
+ Dir.chdir(dir,&block)
328
+ end
329
+
330
+ #
331
+ # The primary license of the project.
332
+ #
333
+ # @return [String, nil]
334
+ # The primary license for the project.
335
+ #
336
+ def license
337
+ @licenses.first
338
+ end
339
+
340
+ #
341
+ # Determines whether the project uses Bundler.
342
+ #
343
+ # @return [Boolean]
344
+ # Specifies whether the project uses Bundler.
345
+ #
346
+ def bundler?
347
+ file?('Gemfile')
348
+ end
349
+
350
+ #
351
+ # Determines whether the project has been bundled using Bundler.
352
+ #
353
+ # @return [Boolean]
354
+ # Specifies whether the project has been bundled.
355
+ #
356
+ def bundled?
357
+ file?('Gemfile.lock')
358
+ end
359
+
360
+ #
361
+ # Determines if the project contains RDoc documentation.
362
+ #
363
+ # @return [Boolean]
364
+ # Specifies whether the project has RDoc documentation.
365
+ #
366
+ def has_rdoc
367
+ @documentation == :rdoc
368
+ end
369
+
370
+ #
371
+ # Determines if the project contains YARD documentation.
372
+ #
373
+ # @return [Boolean]
374
+ # Specifies whether the project has YARD documentation.
375
+ #
376
+ def has_yard
377
+ @documentation == :yard
378
+ end
379
+
380
+ #
381
+ # Populates a Gem Specification using the metadata of the project.
382
+ #
383
+ # @yield [gemspec]
384
+ # The given block will be passed the populated Gem Specification
385
+ # object.
386
+ #
387
+ # @yieldparam [Gem::Specification] gemspec
388
+ # The newly created Gem Specification.
389
+ #
390
+ # @return [Gem::Specification]
391
+ # The Gem Specification.
392
+ #
393
+ # @see http://rubygems.rubyforge.org/rdoc/Gem/Specification.html
394
+ #
395
+ def to_gemspec
396
+ Gem::Specification.new do |gemspec|
397
+ gemspec.name = @name.to_s
398
+ gemspec.version = @version.to_s
399
+ gemspec.summary = @summary.to_s
400
+ gemspec.description = @description.to_s
401
+ gemspec.licenses = @licenses
402
+ gemspec.authors = @authors
403
+ gemspec.homepage = @homepage
404
+ gemspec.email = @email
405
+ gemspec.date = @date
406
+
407
+ @require_paths.each do |path|
408
+ unless gemspec.require_paths.include?(path)
409
+ gemspec.require_paths << path
410
+ end
411
+ end
412
+
413
+ gemspec.executables = @executables
414
+ gemspec.default_executable = @default_executable
415
+
416
+ gemspec.has_rdoc = if has_yard
417
+ 'yard'
418
+ elsif has_rdoc
419
+ true
420
+ end
421
+
422
+ gemspec.extra_rdoc_files = @extra_doc_files
423
+ gemspec.files = @files
424
+ gemspec.test_files = @test_files
425
+ gemspec.post_install_message = @post_install_message
426
+
427
+ gemspec.requirements = @requirements
428
+
429
+ if gemspec.respond_to?(:required_ruby_version=)
430
+ gemspec.required_ruby_version = @required_ruby_version
431
+ end
432
+
433
+ if gemspec.respond_to?(:required_rubygems_version=)
434
+ gemspec.required_rubygems_version = @required_rubygems_version
435
+ end
436
+
437
+ @dependencies.each do |dep|
438
+ gemspec.add_dependency(dep.name,*dep.versions)
439
+ end
440
+
441
+ if gemspec.respond_to?(:add_runtime_dependency)
442
+ @runtime_dependencies.each do |dep|
443
+ gemspec.add_runtime_dependency(dep.name,*dep.versions)
444
+ end
445
+ else
446
+ @runtime_dependencies.each do |dep|
447
+ gemspec.add_dependency(dep.name,*dep.versions)
448
+ end
449
+ end
450
+
451
+ if gemspec.respond_to?(:add_development_dependency)
452
+ @development_dependencies.each do |dep|
453
+ gemspec.add_development_dependency(dep.name,*dep.versions)
454
+ end
455
+ else
456
+ @development_dependencies.each do |dep|
457
+ gemspec.add_dependency(dep.name,*dep.versions)
458
+ end
459
+ end
460
+
461
+ # legacy information
462
+ if gemspec.respond_to?(:rubyforge_project=)
463
+ gemspec.rubyforge_project = gemspec.name
464
+ end
465
+
466
+ yield gemspec if block_given?
467
+ end
468
+ end
469
+
470
+ #
471
+ # Builds a gem for the project.
472
+ #
473
+ # @return [Pathname]
474
+ # The path to the built gem file within the `pkg/` directory.
475
+ #
476
+ def build!
477
+ pkg_dir = @root.join(@@pkg_dir)
478
+ FileUtils.mkdir_p(pkg_dir)
479
+
480
+ gem_file = Gem::Builder.new(self.to_gemspec).build
481
+ pkg_path = @root.join(pkg_file)
482
+
483
+ FileUtils.mv(gem_file,pkg_path)
484
+ return pkg_path
485
+ end
486
+
487
+ protected
488
+
489
+ #
490
+ # Prints multiple warning messages.
491
+ #
492
+ # @param [Array] messages
493
+ # The messages to print.
494
+ #
495
+ def warn(*messages)
496
+ messages.each { |mesg| STDERR.puts("WARNING: #{mesg}") }
497
+ end
498
+
499
+ #
500
+ # Infers the Source Code Management used by the project.
501
+ #
502
+ def infer_scm!
503
+ if @root.join('.git').directory?
504
+ @scm = :git
505
+ else
506
+ @scm = nil
507
+ end
508
+ end
509
+
510
+ #
511
+ # Infers the project files.
512
+ #
513
+ def infer_project_files!
514
+ @project_files = Set[]
515
+
516
+ filter_path = lambda { |path|
517
+ check_readable(path) { |file| @project_files << file }
518
+ }
519
+
520
+ within do
521
+ case @scm
522
+ when :git
523
+ `git ls-files -z`.split("\0").each(&filter_path)
524
+ else
525
+ within { Dir.glob('{**/}*',&filter_path) }
526
+ end
527
+ end
528
+ end
529
+
530
+ #
531
+ # Infers the namespace of the project based on the project name.
532
+ #
533
+ def infer_namespace!
534
+ @namespace_modules = modules_of(@name)
535
+ @namespace = namespace_of(@name)
536
+
537
+ dir = namespace_path_of(@name)
538
+
539
+ @namespace_dir = if lib_directory?(dir)
540
+ dir
541
+ elsif lib_directory?(@name)
542
+ @name
543
+ end
544
+ end
545
+
546
+ #
547
+ # Adds a require-path to the project.
548
+ #
549
+ # @param [String] path
550
+ # A directory path relative to the project.
551
+ #
552
+ def add_require_path(path)
553
+ check_directory(path) { |dir| @require_paths << dir }
554
+ end
555
+
556
+ #
557
+ # Adds an executable to the project.
558
+ #
559
+ # @param [String] name
560
+ # The name of the executable.
561
+ #
562
+ def add_executable(name)
563
+ path = File.join(@@bin_dir,name)
564
+
565
+ check_executable(path) { |exe| @executables << exe }
566
+ end
567
+
568
+ #
569
+ # Adds an extra documentation file to the project.
570
+ #
571
+ # @param [String] path
572
+ # The path to the file, relative to the project.
573
+ #
574
+ def add_extra_doc_file(path)
575
+ check_file(path) { |file| @extra_doc_files << file }
576
+ end
577
+
578
+ #
579
+ # Adds a file to the project.
580
+ #
581
+ # @param [String] path
582
+ # The path to the file, relative to the project.
583
+ #
584
+ def add_file(path)
585
+ check_file(path) { |file| @files << file }
586
+ end
587
+
588
+ #
589
+ # Adds a testing-file to the project.
590
+ #
591
+ # @param [String] path
592
+ # The path to the testing-file, relative to the project.
593
+ #
594
+ def add_test_file(path)
595
+ check_file(path) { |file| @test_files << file }
596
+ end
597
+
598
+ end
599
+ end