omnibus-sonian 1.2.0.1

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 (70) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +5 -0
  5. data/.yardopts +6 -0
  6. data/CHANGELOG.md +96 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE +201 -0
  9. data/NOTICE +9 -0
  10. data/README.md +195 -0
  11. data/Rakefile +7 -0
  12. data/bin/makeself-header.sh +401 -0
  13. data/bin/makeself.sh +407 -0
  14. data/bin/omnibus +11 -0
  15. data/lib/omnibus.rb +304 -0
  16. data/lib/omnibus/artifact.rb +151 -0
  17. data/lib/omnibus/build_version.rb +285 -0
  18. data/lib/omnibus/builder.rb +328 -0
  19. data/lib/omnibus/clean_tasks.rb +30 -0
  20. data/lib/omnibus/cli.rb +35 -0
  21. data/lib/omnibus/cli/application.rb +140 -0
  22. data/lib/omnibus/cli/base.rb +118 -0
  23. data/lib/omnibus/cli/build.rb +62 -0
  24. data/lib/omnibus/cli/cache.rb +60 -0
  25. data/lib/omnibus/cli/release.rb +49 -0
  26. data/lib/omnibus/config.rb +224 -0
  27. data/lib/omnibus/exceptions.rb +143 -0
  28. data/lib/omnibus/fetcher.rb +184 -0
  29. data/lib/omnibus/fetchers.rb +22 -0
  30. data/lib/omnibus/fetchers/git_fetcher.rb +212 -0
  31. data/lib/omnibus/fetchers/net_fetcher.rb +193 -0
  32. data/lib/omnibus/fetchers/path_fetcher.rb +65 -0
  33. data/lib/omnibus/fetchers/s3_cache_fetcher.rb +42 -0
  34. data/lib/omnibus/health_check.rb +356 -0
  35. data/lib/omnibus/library.rb +62 -0
  36. data/lib/omnibus/overrides.rb +69 -0
  37. data/lib/omnibus/package_release.rb +163 -0
  38. data/lib/omnibus/project.rb +715 -0
  39. data/lib/omnibus/reports.rb +99 -0
  40. data/lib/omnibus/s3_cacher.rb +138 -0
  41. data/lib/omnibus/software.rb +441 -0
  42. data/lib/omnibus/templates/Berksfile.erb +3 -0
  43. data/lib/omnibus/templates/Gemfile.erb +4 -0
  44. data/lib/omnibus/templates/README.md.erb +102 -0
  45. data/lib/omnibus/templates/Vagrantfile.erb +95 -0
  46. data/lib/omnibus/templates/gitignore.erb +8 -0
  47. data/lib/omnibus/templates/omnibus.rb.example.erb +5 -0
  48. data/lib/omnibus/templates/package_scripts/makeselfinst.erb +27 -0
  49. data/lib/omnibus/templates/package_scripts/postinst.erb +17 -0
  50. data/lib/omnibus/templates/package_scripts/postrm.erb +9 -0
  51. data/lib/omnibus/templates/project.rb.erb +21 -0
  52. data/lib/omnibus/templates/software/c-example.rb.erb +42 -0
  53. data/lib/omnibus/templates/software/erlang-example.rb.erb +38 -0
  54. data/lib/omnibus/templates/software/ruby-example.rb.erb +24 -0
  55. data/lib/omnibus/util.rb +61 -0
  56. data/lib/omnibus/version.rb +20 -0
  57. data/omnibus.gemspec +34 -0
  58. data/spec/artifact_spec.rb +106 -0
  59. data/spec/build_version_spec.rb +266 -0
  60. data/spec/data/overrides/bad_line.overrides +3 -0
  61. data/spec/data/overrides/good.overrides +5 -0
  62. data/spec/data/overrides/with_dupes.overrides +4 -0
  63. data/spec/data/software/erchef.rb +40 -0
  64. data/spec/fetchers/net_fetcher_spec.rb +16 -0
  65. data/spec/overrides_spec.rb +114 -0
  66. data/spec/package_release_spec.rb +197 -0
  67. data/spec/s3_cacher_spec.rb +47 -0
  68. data/spec/software_spec.rb +85 -0
  69. data/spec/spec_helper.rb +28 -0
  70. metadata +252 -0
@@ -0,0 +1,49 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2013 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'omnibus/cli/base'
19
+ require 'omnibus/cli/application'
20
+ require 'omnibus/package_release'
21
+ require 'json'
22
+
23
+ module Omnibus
24
+ module CLI
25
+
26
+
27
+ class Release < Base
28
+
29
+ namespace :release
30
+
31
+ def initialize(args, options, config)
32
+ super(args, options, config)
33
+ end
34
+
35
+ desc "package PATH", "Upload a single package to S3"
36
+ option :public, :type => :boolean, :default => false, :desc => "Make S3 object publicly readable"
37
+ def package(path)
38
+ access_policy = options[:public] ? :public_read : :private
39
+
40
+ uploader = PackageRelease.new(path, :access => access_policy) do |uploaded_item|
41
+ say("Uploaded #{uploaded_item}", :green)
42
+ end
43
+ uploader.release
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+
@@ -0,0 +1,224 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'mixlib/config'
19
+ require 'omnibus/exceptions'
20
+ require 'json'
21
+
22
+ module Omnibus
23
+
24
+ # Global configuration object for Omnibus runs.
25
+ #
26
+ # @todo Write a {http://yardoc.org/guides/extending-yard/writing-handlers.html
27
+ # Yard handler} for Mixlib::Config-style DSL methods. I'd like
28
+ # the default value to show up in the docs without having to type
29
+ # it out twice, which I'm doing now for benefit of viewers of the Yard docs.
30
+ class Config
31
+ extend Mixlib::Config
32
+
33
+ # @!group Directory Configuration Parameters
34
+
35
+ # @!attribute [rw] cache_dir
36
+ # The absolute path to the directory on the virtual machine where
37
+ # code will be cached.
38
+ #
39
+ # Defaults to `"/var/cache/omnibus/cache"`.
40
+ #
41
+ # @return [String]
42
+ cache_dir "/var/cache/omnibus/cache"
43
+
44
+ # @!attribute [rw] source_dir
45
+ # The absolute path to the directory on the virtual machine where
46
+ # source code will be downloaded.
47
+ #
48
+ # Defaults to `"/var/cache/omnibus/src"`.
49
+ #
50
+ # @return [String]
51
+ source_dir "/var/cache/omnibus/src"
52
+
53
+ # @!attribute [rw] build_dir
54
+ # The absolute path to the directory on the virtual machine where
55
+ # software will be built.
56
+ #
57
+ # Defaults to `"/var/cache/omnibus/build"`.
58
+ #
59
+ # @return [String]
60
+ build_dir "/var/cache/omnibus/build"
61
+
62
+ # @!attribute [rw] package_dir
63
+ # The absolute path to the directory on the virtual machine where
64
+ # packages will be constructed.
65
+ #
66
+ # Defaults to `"/var/cache/omnibus/pkg"`.
67
+ #
68
+ # @return [String]
69
+ package_dir "/var/cache/omnibus/pkg"
70
+
71
+ # @!attribute [rw] project_dir
72
+ # The relative path of the directory containing {Omnibus::Project}
73
+ # DSL files. This is relative to {#project_root}.
74
+ #
75
+ # Defaults to `"config/projects"`.
76
+ #
77
+ # @return [String]
78
+ project_dir "config/projects"
79
+
80
+ # @!attribute [rw] software_dir
81
+ # The relative path of the directory containing {Omnibus::Software}
82
+ # DSL files. This is relative {#project_root}.
83
+ #
84
+ # Defaults to `"config/software"`.
85
+ #
86
+ # @return [String]
87
+ software_dir "config/software"
88
+
89
+ # @!attribute [rw] project_root
90
+ # The root directory in which to look for {Omnibus::Project} and
91
+ # {Omnibus::Software} DSL files.
92
+ #
93
+ # Defaults to the current working directory.
94
+ #
95
+ # @return [String]
96
+ project_root Dir.pwd
97
+
98
+ # @!attribute [rw] install_dir
99
+ # Installation directory
100
+ #
101
+ # Defaults to `"/opt/chef"`.
102
+ #
103
+ # @todo This appears to be unused, and actually conflated with
104
+ # {Omnibus::Project#install_path}
105
+ #
106
+ # @return [String]
107
+ install_dir "/opt/chef"
108
+
109
+ # @!endgroup
110
+
111
+ # @!group S3 Caching Configuration Parameters
112
+
113
+ # @!attribute [rw] use_s3_caching
114
+ # Indicate if you wish to cache software artifacts in S3 for
115
+ # quicker build times. Requires {#s3_bucket}, {#s3_access_key},
116
+ # and {#s3_secret_key} to be set if this is set to `true`.
117
+ #
118
+ # Defaults to `false`.
119
+ #
120
+ # @return [Boolean]
121
+ use_s3_caching false
122
+
123
+ # @!attribute [rw] s3_bucket
124
+ # The name of the S3 bucket you want to cache software artifacts in.
125
+ #
126
+ # Defaults to `nil`. Must be set if {#use_s3_caching} is `true`.
127
+ #
128
+ # @return [String, nil]
129
+ s3_bucket nil
130
+
131
+ # @!attribute [rw] s3_access_key
132
+ # The S3 access key to use with S3 caching.
133
+ #
134
+ # Defaults to `nil`. Must be set if {#use_s3_caching} is `true`.
135
+ #
136
+ # @return [String, nil]
137
+ s3_access_key nil
138
+
139
+ # @!attribute [rw] s3_secret_key
140
+ # The S3 secret key to use with S3 caching.
141
+ #
142
+ # Defaults to `nil`. Must be set if {#use_s3_caching} is `true.`
143
+ #
144
+ # @return [String, nil]
145
+ s3_secret_key nil
146
+
147
+ # @!endgroup
148
+
149
+ # @!group S3 Release Parameters
150
+
151
+ # @!attribute [rw] release_s3_bucket
152
+ # The name of the S3 bucket you want to release artifacts to.
153
+ #
154
+ # Defaults to `nil`. Must be set to use `release package` command.
155
+ #
156
+ # @return [String, nil]
157
+ release_s3_bucket nil
158
+
159
+ # @!attribute [rw] release_s3_access_key
160
+ # The S3 access key to use for S3 artifact release.
161
+ #
162
+ # Defaults to `nil`. Must be set to use `release package` command.
163
+ #
164
+ # @return [String, nil]
165
+ release_s3_access_key nil
166
+
167
+ # @!attribute [rw] release_s3_secret_key
168
+ # The S3 secret key to use for S3 artifact release
169
+ #
170
+ # Defaults to `nil`. Must be set to use `release package` command.
171
+ #
172
+ # @return [String, nil]
173
+ release_s3_secret_key nil
174
+
175
+ # @!endgroup
176
+
177
+ # @!group Miscellaneous Configuration Parameters
178
+
179
+ # @!attribute [rw] override_file
180
+ #
181
+ # @return [Boolean]
182
+ override_file nil
183
+
184
+ # @!attribute [rw] solaris_compiler
185
+ #
186
+ # @return [String, nil]
187
+ solaris_compiler nil
188
+
189
+ # @!endgroup
190
+
191
+ # @!group Build Version Parameters
192
+
193
+ # @!attribute [rw] append_timestamp
194
+ #
195
+ # @return [Boolean]
196
+ append_timestamp true
197
+
198
+ # # @!endgroup
199
+
200
+ # @!group Validation Methods
201
+
202
+ # Asserts that the Config object is in a valid state. If invalid
203
+ # for any reason, an exception will be thrown.
204
+ #
205
+ # @raise [RuntimeError]
206
+ # @return [void]
207
+ def self.validate
208
+ valid_s3_config?
209
+ # add other validation methods as needed
210
+ end
211
+
212
+ # @raise [InvalidS3Configuration]
213
+ def self.valid_s3_config?
214
+ if use_s3_caching
215
+ unless s3_bucket
216
+ raise InvalidS3Configuration.new(s3_bucket, s3_access_key, s3_secret_key)
217
+ end
218
+ end
219
+ end
220
+
221
+ # @!endgroup
222
+
223
+ end # Config
224
+ end # Omnibus
@@ -0,0 +1,143 @@
1
+ module Omnibus
2
+
3
+ class InvalidS3Configuration < RuntimeError
4
+ def initialize(s3_bucket, s3_access_key, s3_secret_key)
5
+ @s3_bucket, @s3_access_key, @s3_secret_key = s3_bucket, s3_access_key, s3_secret_key
6
+ end
7
+
8
+ def to_s
9
+ """
10
+ One or more required S3 configuration values is missing.
11
+
12
+ Your effective configuration was the following:
13
+
14
+ s3_bucket => #{@s3_bucket.inspect}
15
+ s3_access_key => #{@s3_access_key.inspect}
16
+ s3_secret_key => #{@s3_secret_key.inspect}
17
+
18
+ If you truly do want S3 caching, you should add values similar
19
+ to the following in your Omnibus config file:
20
+
21
+ s3_bucket ENV['S3_BUCKET_NAME']
22
+ s3_access_key ENV['S3_ACCESS_KEY']
23
+ s3_secret_key ENV['S3_SECRET_KEY']
24
+
25
+ Note that you are not required to use environment variables as
26
+ illustrated (and the ones listed have no special significance in
27
+ Omnibus), but it is encouraged to prevent spread of sensitive
28
+ information and inadvertent check-in of same to version control
29
+ systems.
30
+
31
+ """
32
+ end
33
+ end
34
+
35
+ class NoPackageFile < RuntimeError
36
+ def initialize(package_path)
37
+ @package_path = package_path
38
+ end
39
+
40
+ def to_s
41
+ """
42
+ Cannot locate or access the package at the given path:
43
+
44
+ #{@package_path}
45
+ """
46
+ end
47
+ end
48
+
49
+ class NoPackageMetadataFile < RuntimeError
50
+ def initialize(package_metadata_path)
51
+ @package_metadata_path = package_metadata_path
52
+ end
53
+
54
+ def to_s
55
+ """
56
+ Cannot locate or access the package metadata file at the given path:
57
+
58
+ #{@package_metadata_path}
59
+ """
60
+ end
61
+ end
62
+
63
+ class InvalidS3ReleaseConfiguration < RuntimeError
64
+ def initialize(s3_bucket, s3_access_key, s3_secret_key)
65
+ @s3_bucket, @s3_access_key, @s3_secret_key = s3_bucket, s3_access_key, s3_secret_key
66
+ end
67
+
68
+ def to_s
69
+ """
70
+ One or more required S3 configuration values is missing.
71
+
72
+ Your effective configuration was the following:
73
+
74
+ release_s3_bucket => #{@s3_bucket.inspect}
75
+ release_s3_access_key => #{@s3_access_key.inspect}
76
+ release_s3_secret_key => #{@s3_secret_key.inspect}
77
+
78
+ To release a package to S3, add the following values to your
79
+ config file:
80
+
81
+ release_s3_bucket ENV['S3_BUCKET_NAME']
82
+ release_s3_access_key ENV['S3_ACCESS_KEY']
83
+ release_s3_secret_key ENV['S3_SECRET_KEY']
84
+
85
+ Note that you are not required to use environment variables as
86
+ illustrated (and the ones listed have no special significance in
87
+ Omnibus), but it is encouraged to prevent spread of sensitive
88
+ information and inadvertent check-in of same to version control
89
+ systems.
90
+
91
+ """
92
+ end
93
+ end
94
+ # Raise this error if a needed Project configuration value has not
95
+ # been set.
96
+ class MissingProjectConfiguration < RuntimeError
97
+ def initialize(parameter_name, sample_value)
98
+ @parameter_name, @sample_value = parameter_name, sample_value
99
+ end
100
+
101
+ def to_s
102
+ """
103
+ You are attempting to build a project, but have not specified
104
+ a value for '#{@parameter_name}'!
105
+
106
+ Please add code similar to the following to your project DSL file:
107
+
108
+ #{@parameter_name} '#{@sample_value}'
109
+
110
+ """
111
+ end
112
+ end
113
+
114
+ class MissingPatch < RuntimeError
115
+ def initialize(patch_name, search_paths)
116
+ @patch_name, @search_paths = patch_name, search_paths
117
+ end
118
+
119
+ def to_s
120
+ """
121
+ Attempting to apply the patch #{@patch_name}, but it was not
122
+ found at any of the following locations:
123
+
124
+ #{@search_paths.join("\n ")}
125
+ """
126
+ end
127
+ end
128
+
129
+ class MissingProjectDependency < RuntimeError
130
+ def initialize(dep_name, search_paths)
131
+ @dep_name, @search_paths = dep_name, search_paths
132
+ end
133
+
134
+ def to_s
135
+ """
136
+ Attempting to load the project dependency '#{@dep_name}', but it was
137
+ not found at any of the following locations:
138
+
139
+ #{@search_paths.join("\n ")}
140
+ """
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,184 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'pp'
19
+
20
+ module Omnibus
21
+
22
+ # Base class for classes that fetch project sources from the internet.
23
+ #
24
+ # @abstract Subclass and override the {#clean}, {#description},
25
+ # {#fetch}, {#fetch_required?}, and {#version_guid} methods
26
+ #
27
+ # @todo Is this class supposed to be abstract or not? Pretty sure
28
+ # it's supposed to be abstract
29
+ class Fetcher
30
+
31
+ # Given an error and a fetcher that generated the error, print a
32
+ # formatted report of the error and stacktrace, along with fetcher
33
+ # details to stderr.
34
+ #
35
+ # @note Does not rethrow the error; that must currently be done manually.
36
+ #
37
+ # @todo Since this is always called from within a fetcher, and
38
+ # since the fetcher always passes itself in in the {#initialize}
39
+ # method, this really ought to be encapsulated in a method call on
40
+ # {Omnibus::Fetcher}.
41
+ # @todo Also, since we always 'raise' after calling {#explain}, we
42
+ # should just go ahead and exit from here. No need to raise,
43
+ # since we're already outputting the real error and stacktrace
44
+ # here.
45
+ class ErrorReporter
46
+
47
+ def initialize(error, fetcher)
48
+ @error, @fetcher = error, fetcher
49
+ end
50
+
51
+ # @todo Why not just make an attribute for error?
52
+ #
53
+ # @todo And for that matter, why not make an attribute for the
54
+ # fetcher as well? Or why not just use `@error` like we use
55
+ # `@fetcher`?
56
+ def e
57
+ @error
58
+ end
59
+
60
+ # @todo If {Omnibus::Fetcher#description} is meant to show
61
+ # parameters (presumably the kind of fetcher and the software it
62
+ # is fetching?),
63
+ def explain(why)
64
+ $stderr.puts "* " * 40
65
+ $stderr.puts why
66
+ $stderr.puts "Fetcher params:"
67
+ $stderr.puts indent(@fetcher.description, 2)
68
+ $stderr.puts "Exception:"
69
+ $stderr.puts indent("#{e.class}: #{e.message.strip}", 2)
70
+ Array(e.backtrace).each {|l| $stderr.puts indent(l, 4) }
71
+ $stderr.puts "* " * 40
72
+ end
73
+
74
+ private
75
+
76
+ # Indent each line of a string with `n` spaces.
77
+ #
78
+ # Splits the string at `\n` characters and then pads the left
79
+ # side with `n` spaces. Rejoins them all again with `\n`.
80
+ #
81
+ # @param string [String] the string to indent
82
+ # @param n [Fixnum] the number of " " characters to indent each line.
83
+ # @return [String]
84
+ def indent(string, n)
85
+ string.split("\n").map {|l| " ".rjust(n) << l }.join("\n")
86
+ end
87
+
88
+ end
89
+
90
+ class UnsupportedSourceLocation < ArgumentError
91
+ end
92
+
93
+ NULL_ARG = Object.new
94
+
95
+ # Returns an implementation of {Fetcher} that can retrieve the
96
+ # given software.
97
+ #
98
+ # @param software [Omnibus::Software] the software the Fetcher should fetch
99
+ # @return [Omnibus::Fetcher]
100
+ def self.for(software)
101
+ if software.source
102
+ if software.source[:url] && Omnibus.config.use_s3_caching
103
+ S3CacheFetcher.new(software)
104
+ else
105
+ without_caching_for(software)
106
+ end
107
+ else
108
+ Fetcher.new(software)
109
+ end
110
+ end
111
+
112
+ # @param software [Omnibus::Software] the software to fetch
113
+ # @raise [UnsupportedSourceLocation] if the software's source is not
114
+ # one of `:url`, `:git`, or `:path`
115
+ # @see Omnibus::Software#source
116
+ # @todo Define an enumeration of the acceptable software types
117
+ # @todo This probably ought to be folded into {#for} method above.
118
+ # It looks like this is called explicitly in
119
+ # {Omnibus::S3Cache#fetch}, but that could be handled by having a
120
+ # second optional parameter that always disables caching.
121
+ # @todo Since the software determines what fetcher must be used to
122
+ # fetch it, perhaps this should be a method on {Omnibus::Software}
123
+ # instead.
124
+ def self.without_caching_for(software)
125
+ if software.source[:url]
126
+ NetFetcher.new(software)
127
+ elsif software.source[:git]
128
+ GitFetcher.new(software)
129
+ elsif software.source[:path]
130
+ PathFetcher.new(software)
131
+ else
132
+ raise UnsupportedSourceLocation, "Don't know how to fetch software project #{software}"
133
+ end
134
+ end
135
+
136
+ def self.name(name=NULL_ARG)
137
+ @name = name unless name.equal?(NULL_ARG)
138
+ @name
139
+ end
140
+
141
+ attr_reader :name
142
+
143
+ # @todo What is this? It doesn't appear to be used anywhere
144
+ attr_reader :source_timefile
145
+
146
+ def initialize(software)
147
+ end
148
+
149
+ def log(message)
150
+ puts "[fetcher:#{self.class.name}::#{name}] #{message}"
151
+ end
152
+
153
+ # @!group Methods for Subclasses to Implement
154
+
155
+ # @todo All extenders of this class override this method. Since
156
+ # this class appears to be intended as an abstract one, this
157
+ # should raise a NotImplementedError
158
+ def description
159
+ # Not as pretty as we'd like, but it's a sane default:
160
+ inspect
161
+ end
162
+
163
+ # @todo All extenders of this class override this method. Since
164
+ # this class appears to be intended as an abstract one, this
165
+ # should raise a NotImplementedError
166
+ def fetch_required?
167
+ false
168
+ end
169
+
170
+ # @todo Empty method is very suspicious; raise NotImplementedError instead.
171
+ def clean
172
+ end
173
+
174
+ # @todo Empty method is very suspicious; raise NotImplementedError instead.
175
+ def fetch
176
+ end
177
+
178
+ # @todo Empty method is very suspicious; raise NotImplementedError instead.
179
+ def version_guid
180
+ end
181
+
182
+ # !@endgroup
183
+ end
184
+ end