io-like 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.yardopts +1 -0
  2. data/LICENSE +22 -57
  3. data/{LICENSE.rubyspec → LICENSE-rubyspec} +0 -0
  4. data/{NEWS → NEWS.md} +10 -5
  5. data/README.md +269 -0
  6. data/Rakefile +228 -0
  7. data/ruby.1.8.mspec +7 -0
  8. data/spec/binmode_spec.rb +29 -0
  9. data/spec/close_read_spec.rb +64 -0
  10. data/spec/close_spec.rb +36 -0
  11. data/spec/close_write_spec.rb +61 -0
  12. data/spec/closed_spec.rb +16 -0
  13. data/spec/each_byte_spec.rb +38 -0
  14. data/spec/each_line_spec.rb +11 -0
  15. data/spec/each_spec.rb +11 -0
  16. data/spec/eof_spec.rb +11 -0
  17. data/spec/fixtures/classes.rb +96 -0
  18. data/spec/fixtures/gets.txt +9 -0
  19. data/spec/fixtures/numbered_lines.txt +5 -0
  20. data/spec/fixtures/one_byte.txt +1 -0
  21. data/spec/fixtures/paragraphs.txt +7 -0
  22. data/spec/fixtures/readlines.txt +6 -0
  23. data/spec/flush_spec.rb +8 -0
  24. data/spec/getc_spec.rb +44 -0
  25. data/spec/gets_spec.rb +212 -0
  26. data/spec/isatty_spec.rb +6 -0
  27. data/spec/lineno_spec.rb +84 -0
  28. data/spec/output_spec.rb +47 -0
  29. data/spec/pos_spec.rb +53 -0
  30. data/spec/print_spec.rb +97 -0
  31. data/spec/printf_spec.rb +24 -0
  32. data/spec/putc_spec.rb +57 -0
  33. data/spec/puts_spec.rb +99 -0
  34. data/spec/read_spec.rb +162 -0
  35. data/spec/readchar_spec.rb +49 -0
  36. data/spec/readline_spec.rb +60 -0
  37. data/spec/readlines_spec.rb +140 -0
  38. data/spec/readpartial_spec.rb +92 -0
  39. data/spec/rewind_spec.rb +56 -0
  40. data/spec/seek_spec.rb +72 -0
  41. data/spec/shared/each.rb +204 -0
  42. data/spec/shared/eof.rb +116 -0
  43. data/spec/shared/pos.rb +39 -0
  44. data/spec/shared/tty.rb +12 -0
  45. data/spec/shared/write.rb +53 -0
  46. data/spec/sync_spec.rb +56 -0
  47. data/spec/sysread_spec.rb +87 -0
  48. data/spec/sysseek_spec.rb +68 -0
  49. data/spec/syswrite_spec.rb +60 -0
  50. data/spec/tell_spec.rb +7 -0
  51. data/spec/to_io_spec.rb +19 -0
  52. data/spec/tty_spec.rb +6 -0
  53. data/spec/ungetc_spec.rb +118 -0
  54. data/spec/write_spec.rb +61 -0
  55. data/spec_helper.rb +49 -0
  56. metadata +223 -32
  57. data/CONTRIBUTORS +0 -15
  58. data/GPL +0 -676
  59. data/HACKING +0 -123
  60. data/LEGAL +0 -56
  61. data/MANIFEST +0 -10
  62. data/README +0 -150
@@ -0,0 +1 @@
1
+ --protected --private --plugin redcarpet-ext --main README.md lib/**/*.rb - NEWS.md LICENSE LICENSE-rubyspec
data/LICENSE CHANGED
@@ -1,57 +1,22 @@
1
- LICENSE text follows:
2
-
3
- IO::Like is copyrighted free software by Jeremy Bopp
4
- <jeremy at bopp dot net>. You can redistribute it and/or modify it under
5
- either the terms of the GPL (see the included GPL file), or the conditions
6
- below:
7
-
8
- 1. You may make and give away verbatim copies of the source form of the
9
- software without restriction, provided that you duplicate all of the
10
- original copyright notices and associated disclaimers.
11
-
12
- 2. You may modify your copy of the software in any way, provided that
13
- you do at least ONE of the following:
14
-
15
- a) place your modifications in the Public Domain or otherwise
16
- make them Freely Available, such as by posting said
17
- modifications to Usenet or an equivalent medium, or by allowing
18
- the author to include your modifications in the software.
19
-
20
- b) use the modified software only within your corporation or
21
- organization.
22
-
23
- c) rename any non-standard executables so the names do not conflict
24
- with standard executables, which must also be provided.
25
-
26
- d) make other distribution arrangements with the author.
27
-
28
- 3. You may distribute the software in object code or executable
29
- form, provided that you do at least ONE of the following:
30
-
31
- a) distribute the executables and library files of the software,
32
- together with instructions (in the manual page or equivalent)
33
- on where to get the original distribution.
34
-
35
- b) accompany the distribution with the machine-readable source of
36
- the software.
37
-
38
- c) give non-standard executables non-standard names, with
39
- instructions on where to get the original software distribution.
40
-
41
- d) make other distribution arrangements with the author.
42
-
43
- 4. You may modify and include the covered part of the software into any
44
- other software (possibly commercial). But some files in the
45
- distribution may not be written by the author, such that they are not
46
- under these terms. (See the file LEGAL for a listing and conditions)
47
-
48
- 5. The scripts and library files supplied as input to or produced as
49
- output from the software do not automatically fall under the
50
- copyright of the software, but belong to whomever generated them,
51
- and may be sold commercially, and may be aggregated with this
52
- software.
53
-
54
- 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
55
- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
56
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57
- PURPOSE.
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2020 Jeremy Bopp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File without changes
@@ -1,4 +1,4 @@
1
- = News and Notifications by Version
1
+ # News and Notifications by Version
2
2
 
3
3
  This file lists noteworthy changes which may affect users of this project. More
4
4
  detailed information is available in the rest of the documentation.
@@ -6,25 +6,30 @@ detailed information is available in the rest of the documentation.
6
6
  <b>NOTE:</b> Date stamps in the following entries are in YYYY/MM/DD format.
7
7
 
8
8
 
9
- == v0.3.0 (2009/04/29)
9
+ ## v0.3.1 (2020/02/09)
10
+
11
+ * Removed the rubyforge reference from the gemspec (Jordan Pickwell)
12
+
13
+
14
+ ## v0.3.0 (2009/04/29)
10
15
 
11
16
  * Fixed the rewind method to work with write-only streams
12
17
  * Fixed the read, gets, and readline methods to return partial data if they have
13
18
  such data but receive low level errors before reaching a stopping point
14
19
  * Renamed all private methods so that it is highly unlikely that they will be
15
- accidentally overridden.
20
+ accidentally overridden
16
21
  * Eliminated warnings caused by referencing uninitialized instance variables
17
22
  * Improved the documentation for the read, gets, and readline methods
18
23
 
19
24
 
20
- == v0.2.0 (2009/03/11)
25
+ ## v0.2.0 (2009/03/11)
21
26
 
22
27
  * Added mspec tests borrowed from the rubyspec project
23
28
  * Fixed many, many defects related to IO compatibility (Mostly obscure corner
24
29
  cases)
25
30
 
26
31
 
27
- == v0.1.0 (2008/07/03)
32
+ ## v0.1.0 (2008/07/03)
28
33
 
29
34
  * Initial release
30
35
  * All read, write, and seek functions implemented as defined in Ruby 1.8.6
@@ -0,0 +1,269 @@
1
+ # IO::Like - in the Likeness of IO
2
+
3
+ A module which provides the functionality of an IO object to any including class
4
+ which provides a couple of simple methods.
5
+
6
+ ## LINKS
7
+
8
+ * Homepage :: http://github.com/javanthropus/io-like
9
+ * Documentation :: http://rdoc.info/gems/io-like/frames
10
+ * Source :: http://github.com/javanthropus/io-like
11
+
12
+ ## DESCRIPTION
13
+
14
+ The IO::Like module provides all of the methods of typical IO implementations
15
+ such as File; most importantly the read, write, and seek series of methods. A
16
+ class which includes IO::Like needs to provide only a few methods in order to
17
+ enable the higher level methods. Buffering is automatically provided by default
18
+ for the methods which normally provide it in IO.
19
+
20
+ ## FEATURES
21
+
22
+ * All standard Ruby 1.8.6 IO operations.
23
+ * Buffered operations.
24
+ * Configurable buffer size.
25
+
26
+ ## KNOWN BUGS/LIMITATIONS
27
+
28
+ * Only up to version 1.8.6 of Ruby's IO interface is implemented.
29
+ * Ruby's finalization capabilities fall a bit short in a few respects, and as a
30
+ result, it is impossible to cause the close, close_read, or close_write
31
+ methods to be called automatically when an including class is garbage
32
+ collected. Define a class open method in the manner of File.open which
33
+ guarantees that an appropriate close method will be called after executing a
34
+ block. Other than that, be diligent about calling the close methods.
35
+
36
+ ## SYNOPSIS
37
+
38
+ More examples can be found in the `examples` directory of the source
39
+ distribution.
40
+
41
+ A simple ROT13 codec:
42
+
43
+ ```ruby
44
+ require 'io/like'
45
+
46
+ class ROT13Filter
47
+ include IO::Like
48
+
49
+ def self.open(delegate_io)
50
+ filter = new(delegate_io)
51
+ return filter unless block_given?
52
+
53
+ begin
54
+ yield(filter)
55
+ ensure
56
+ filter.close unless filter.closed?
57
+ end
58
+ end
59
+
60
+ def initialize(delegate_io)
61
+ @delegate_io = delegate_io
62
+ end
63
+
64
+ private
65
+
66
+ def encode_rot13(string)
67
+ result = string.dup
68
+ 0.upto(result.length) do |i|
69
+ case result[i]
70
+ when 65..90
71
+ result[i] = (result[i] - 52) % 26 + 65
72
+ when 97..122
73
+ result[i] = (result[i] - 84) % 26 + 97
74
+ end
75
+ end
76
+ result
77
+ end
78
+
79
+ def unbuffered_read(length)
80
+ encode_rot13(@delegate_io.sysread(length))
81
+ end
82
+
83
+ def unbuffered_seek(offset, whence = IO::SEEK_SET)
84
+ @delegate_io.sysseek(offset, whence)
85
+ end
86
+
87
+ def unbuffered_write(string)
88
+ @delegate_io.syswrite(encode_rot13(string))
89
+ end
90
+ end
91
+
92
+ File.open('normal_file.txt', 'w') do |f|
93
+ f.puts('This is a test')
94
+ end
95
+
96
+ File.open('rot13_file.txt', 'w') do |f|
97
+ ROT13Filter.open(f) do |rot13|
98
+ rot13.puts('This is a test')
99
+ end
100
+ end
101
+
102
+ File.open('normal_file.txt') do |f|
103
+ ROT13Filter.open(f) do |rot13|
104
+ puts(rot13.read) # -> Guvf vf n grfg
105
+ end
106
+ end
107
+
108
+ File.open('rot13_file.txt') do |f|
109
+ ROT13Filter.open(f) do |rot13|
110
+ puts(rot13.read) # -> This is a test
111
+ end
112
+ end
113
+
114
+ File.open('normal_file.txt') do |f|
115
+ ROT13Filter.open(f) do |rot13|
116
+ rot13.pos = 5
117
+ puts(rot13.read) # -> vf n grfg
118
+ end
119
+ end
120
+
121
+ File.open('rot13_file.txt') do |f|
122
+ ROT13Filter.open(f) do |rot13|
123
+ rot13.pos = 5
124
+ puts(rot13.read) # -> is a test
125
+ end
126
+ end
127
+
128
+ File.open('normal_file.txt') do |f|
129
+ ROT13Filter.open(f) do |rot13|
130
+ ROT13Filter.open(rot13) do |rot26| # ;-)
131
+ puts(rot26.read) # -> This is a test
132
+ end
133
+ end
134
+ end
135
+ ```
136
+
137
+ ## REQUIREMENTS
138
+
139
+ * None
140
+
141
+ ## INSTALL
142
+
143
+ Download the GEM file and install it with:
144
+
145
+ $ gem install io-like-VERSION.gem
146
+
147
+ or directly with:
148
+
149
+ $ gem install io-like
150
+
151
+ Removal is the same in either case:
152
+
153
+ $ gem uninstall io-like
154
+
155
+ ## DEVELOPERS
156
+
157
+ After checking out the source, run:
158
+
159
+ $ bundle install
160
+ $ bundle exec rake test yard
161
+
162
+ This will install all dependencies, run the tests/specs, and generate the
163
+ documentation.
164
+
165
+ ## AUTHORS and CONTRIBUTORS
166
+
167
+ Thanks to all contributors. Without your help this project would not exist.
168
+
169
+ * Jeremy Bopp :: jeremy@bopp.net
170
+ * Jarred Holman :: jarred.holman@gmail.com
171
+ * Grant Gardner :: grant@lastweekend.com.au
172
+ * Jordan Pickwell :: jpickwell@users.noreply.github.com
173
+
174
+ ## CONTRIBUTING
175
+
176
+ Contributions for bug fixes, documentation, extensions, tests, etc. are
177
+ encouraged.
178
+
179
+ 1. Clone the repository.
180
+ 2. Fix a bug or add a feature.
181
+ 3. Add tests for the fix or feature.
182
+ 4. Make a pull request.
183
+
184
+ ### CODING STYLE
185
+
186
+ The following points are not necessarily set in stone but should rather be used
187
+ as a good guideline. Consistency is the goal of coding style, and changes will
188
+ be more easily accepted if they are consistent with the rest of the code.
189
+
190
+ * **File Encoding**
191
+ * UTF-8
192
+ * **Indentation**
193
+ * Two spaces; no tabs
194
+ * **Line length**
195
+ * Limit lines to a maximum of 80 characters
196
+ * **Comments**
197
+ * Document classes, attributes, methods, and code
198
+ * **Method Calls with Arguments**
199
+ * Use `a_method(arg, arg, etc)`; **not** `a_method( arg, arg, etc )`,
200
+ `a_method arg, arg, etc`, or any other variation
201
+ * **Method Calls without Arguments**
202
+ * Use `a_method`; avoid parenthesis
203
+ * **String Literals**
204
+ * Use single quotes by default
205
+ * Use double quotes when interpolation is necessary
206
+ * Use `%{...}` and similar when embedding the quoting character is cumbersome
207
+ * **Blocks**
208
+ * `do ... end` for multi-line blocks and `{ ... }` for single-line blocks
209
+ * **Boolean Operators**
210
+ * Use `&&` and `||` for boolean tests; avoid `and` and `or`
211
+ * **In General**
212
+ * Try to follow the flow and style of the rest of the code
213
+
214
+ ## LICENSE
215
+
216
+ ```
217
+ (The MIT License)
218
+
219
+ Copyright (c) 2020 Jeremy Bopp
220
+
221
+ Permission is hereby granted, free of charge, to any person obtaining
222
+ a copy of this software and associated documentation files (the
223
+ 'Software'), to deal in the Software without restriction, including
224
+ without limitation the rights to use, copy, modify, merge, publish,
225
+ distribute, sublicense, and/or sell copies of the Software, and to
226
+ permit persons to whom the Software is furnished to do so, subject to
227
+ the following conditions:
228
+
229
+ The above copyright notice and this permission notice shall be
230
+ included in all copies or substantial portions of the Software.
231
+
232
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
233
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
234
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
235
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
236
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
237
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
238
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
239
+ ```
240
+
241
+ ## RUBYSPEC LICENSE
242
+
243
+ Files under the `rubyspec` directory are copied whole or in part from the
244
+ Rubyspec project.
245
+
246
+ ```
247
+ Copyright (c) 2008 Engine Yard, Inc. All rights reserved.
248
+
249
+ Permission is hereby granted, free of charge, to any person
250
+ obtaining a copy of this software and associated documentation
251
+ files (the "Software"), to deal in the Software without
252
+ restriction, including without limitation the rights to use,
253
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
254
+ copies of the Software, and to permit persons to whom the
255
+ Software is furnished to do so, subject to the following
256
+ conditions:
257
+
258
+ The above copyright notice and this permission notice shall be
259
+ included in all copies or substantial portions of the Software.
260
+
261
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
262
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
263
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
264
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
265
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
266
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
267
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
268
+ OTHER DEALINGS IN THE SOFTWARE.
269
+ ```
@@ -0,0 +1,228 @@
1
+ # encoding: UTF-8
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+
6
+ require 'erb'
7
+ require 'rake/testtask'
8
+ require 'rubygems/package_task'
9
+ require 'rake/clean'
10
+ require 'yard'
11
+
12
+ # Load the gemspec file for this project.
13
+ GEMSPEC = Dir['*.gemspec'].first
14
+ SPEC = eval(File.read(GEMSPEC), nil, GEMSPEC)
15
+
16
+ # A dynamically generated list of files that should match the manifest (the
17
+ # combined contents of SPEC.files and SPEC.test_files). The idea is for this
18
+ # list to contain all project files except for those that have been explicitly
19
+ # excluded. This list will be compared with the manifest from the SPEC in order
20
+ # to help catch the addition or removal of files to or from the project that
21
+ # have not been accounted for either by an exclusion here or an inclusion in the
22
+ # SPEC manifest.
23
+ #
24
+ # NOTE:
25
+ # It is critical that the manifest is *not* automatically generated via globbing
26
+ # and the like; otherwise, this will yield a simple comparison between
27
+ # redundantly generated lists of files that probably will not protect the
28
+ # project from the unintentional inclusion or exclusion of files in the
29
+ # distribution.
30
+ PKG_FILES = FileList.new(Dir.glob('**/*', File::FNM_DOTMATCH)) do |files|
31
+ # Exclude anything that doesn't exist as well as directories.
32
+ files.exclude {|file| ! File.exist?(file) || File.directory?(file)}
33
+ # Exclude Git administrative files.
34
+ files.exclude(%r{(^|[/\\])\.git(ignore|modules|keep)?([/\\]|$)})
35
+ # Exclude editor swap/temporary files.
36
+ files.exclude('**/.*.sw?')
37
+ # Exclude gemspec files.
38
+ files.exclude('*.gemspec')
39
+ # Exclude the README template file.
40
+ files.exclude('README.md.erb')
41
+ # Exclude resources for bundler.
42
+ files.exclude('Gemfile', 'Gemfile.lock')
43
+ files.exclude(%r{^.bundle([/\\]|$)})
44
+ files.exclude(%r{^vendor/bundle([/\\]|$)})
45
+ # Exclude generated content, except for the README file.
46
+ files.exclude(%r{^(pkg|doc|.yardoc)([/\\]|$)})
47
+ # Exclude examples.
48
+ files.exclude(%r{^examples([/\\]|$)})
49
+ # Exclude Rubinius compiled Ruby files.
50
+ files.exclude('**/*.rbc')
51
+ files.exclude('.rbx/**/*')
52
+ end
53
+
54
+ # Make sure that :clean and :clobber will not whack the repository files.
55
+ CLEAN.exclude('.git/**')
56
+ # Vim swap files are fair game for clean up.
57
+ CLEAN.include('**/.*.sw?')
58
+
59
+ # Returns the value of the VERSION environment variable as a Gem::Version object
60
+ # assuming it is set and a valid Gem version string. Otherwise, raises an
61
+ # exception.
62
+ def get_version_argument
63
+ version = ENV['VERSION']
64
+ if version.to_s.empty?
65
+ raise "No version specified: Add VERSION=X.Y.Z to the command line"
66
+ end
67
+ begin
68
+ Gem::Version.create(version.dup)
69
+ rescue ArgumentError
70
+ raise "Invalid version specified in `VERSION=#{version}'"
71
+ end
72
+ end
73
+
74
+ # Performs an in place, per line edit of the file indicated by _path_ by calling
75
+ # the sub method on each line and passing _pattern_, _replacement_, and _b_ as
76
+ # arguments.
77
+ def file_sub(path, pattern, replacement = nil, &b)
78
+ tmp_path = "#{path}.tmp"
79
+ File.open(path) do |infile|
80
+ File.open(tmp_path, 'w') do |outfile|
81
+ infile.each do |line|
82
+ outfile.write(line.sub(pattern, replacement, &b))
83
+ end
84
+ end
85
+ end
86
+ File.rename(tmp_path, path)
87
+ end
88
+
89
+ # Updates the version string in the gemspec file to the string in _version_.
90
+ def set_version(version)
91
+ file_sub(GEMSPEC, /(\.version\s*=\s*).*/, "\\1'#{version}'")
92
+ end
93
+
94
+ # Returns a string that is line wrapped at word boundaries, where each line is
95
+ # no longer than _line_width_ characters.
96
+ #
97
+ # This is mostly lifted directly from ActionView::Helpers::TextHelper.
98
+ def word_wrap(text, line_width = 80)
99
+ text.split("\n").collect do |line|
100
+ line.length > line_width ?
101
+ line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip :
102
+ line
103
+ end * "\n"
104
+ end
105
+
106
+ desc 'Alias for build:gem'
107
+ task :build => 'build:gem'
108
+
109
+ # Build related tasks.
110
+ namespace :build do
111
+ # Ensure that the manifest is consulted when building the gem. Any
112
+ # generated/compiled files should be available at that time.
113
+ task :gem => :check_manifest
114
+
115
+ # Create the gem and package tasks.
116
+ Gem::PackageTask.new(SPEC).define
117
+
118
+ desc 'Verify the manifest'
119
+ task :check_manifest do
120
+ manifest_files = (SPEC.files + SPEC.test_files).sort.uniq
121
+ pkg_files = PKG_FILES.sort.uniq
122
+ if manifest_files != pkg_files then
123
+ common_files = manifest_files & pkg_files
124
+ manifest_files -= common_files
125
+ pkg_files -= common_files
126
+ message = ["The manifest does not match the automatic file list."]
127
+ unless manifest_files.empty? then
128
+ message << " Extraneous files:\n " + manifest_files.join("\n ")
129
+ end
130
+ unless pkg_files.empty?
131
+ message << " Missing files:\n " + pkg_files.join("\n ")
132
+ end
133
+ raise message.join("\n")
134
+ end
135
+ end
136
+
137
+ # Creates the README.md file from a template, the license files, and the
138
+ # gemspec contents.
139
+ file 'README.md' => ['README.md.erb', 'LICENSE', 'LICENSE-rubyspec', GEMSPEC] do
140
+ spec = SPEC
141
+ File.open('README.md', 'w') do |readme|
142
+ readme.write(
143
+ ERB.new(File.read('README.md.erb'), nil, '-').result(binding)
144
+ )
145
+ end
146
+ end
147
+ end
148
+
149
+ # Ensure that the clobber task also clobbers package files.
150
+ task :clobber => 'build:clobber_package'
151
+
152
+ # Ensure that the README file is (re)generated before generating documentation.
153
+ task :yard => 'README.md'
154
+ # Create the documentation task.
155
+ YARD::Rake::YardocTask.new
156
+
157
+ # Gem related tasks.
158
+ namespace :gem do
159
+ desc 'Alias for build:gem'
160
+ task :build => 'build:gem'
161
+
162
+ desc 'Publish the gemfile'
163
+ task :publish => ['version:check', :test, 'repo:tag', :build] do
164
+ sh "gem push pkg/#{SPEC.name}-#{SPEC.version}*.gem"
165
+ end
166
+ end
167
+
168
+ # Create the test task.
169
+ desc 'Run tests'
170
+ task :test do
171
+ sh "mspec"
172
+ end
173
+
174
+ # Version string management tasks.
175
+ namespace :version do
176
+ desc 'Set the version for the project to a specified version'
177
+ task :set do
178
+ set_version(get_version_argument)
179
+ end
180
+
181
+ desc 'Set the version for the project back to 0.0.0'
182
+ task :reset do
183
+ set_version('0.0.0')
184
+ end
185
+
186
+ desc 'Check that all version strings are correctly set'
187
+ task :check => ['version:check:spec', 'version:check:news']
188
+
189
+ namespace :check do
190
+ desc 'Check that the version in the gemspec is correctly set'
191
+ task :spec do
192
+ version = get_version_argument
193
+ if version != SPEC.version
194
+ raise "The given version `#{version}' does not match the gemspec version `#{SPEC.version}'"
195
+ end
196
+ end
197
+
198
+ desc 'Check that the NEWS.md file mentions the version'
199
+ task :news do
200
+ version = get_version_argument
201
+ begin
202
+ File.open('NEWS.md') do |news|
203
+ unless news.each_line.any? {|l| l =~ /^## v#{Regexp.escape(version.to_s)} /}
204
+ raise "The NEWS.md file does not mention version `#{version}'"
205
+ end
206
+ end
207
+ rescue Errno::ENOENT
208
+ raise 'No NEWS.md file found'
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ # Repository and workspace management tasks.
215
+ namespace :repo do
216
+ desc 'Tag the current HEAD with the version string'
217
+ task :tag => :check_workspace do
218
+ version = get_version_argument
219
+ sh "git tag -s -m 'Release v#{version}' v#{version}"
220
+ end
221
+
222
+ desc 'Ensure the workspace is fully committed and clean'
223
+ task :check_workspace => ['README.md'] do
224
+ unless `git status --untracked-files=all --porcelain`.empty?
225
+ raise 'Workspace has been modified. Commit pending changes and try again.'
226
+ end
227
+ end
228
+ end