grizzled-ruby 0.1.4 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a0cdd00724c34a9ac32b4aa3a23f79c81b33f598
4
+ data.tar.gz: 9fea80c84a9dc79725b34b3d83dfef66d5ba7285
5
+ SHA512:
6
+ metadata.gz: f283fa8cb1d56de3f906c91ed2836d47701e572a341faa15cd522d531f64a73668cbaf4f42a4d16412e4fc370020e739f4f7bd94e2b5ef49851ce9910d65d7b5
7
+ data.tar.gz: 8d9a0bce9dbb1facb69f5690d8f54689b66a7e294b31a999dbe7c928f02df686ee70775f073875d1f760ef4337962c78193502684f4d5bdca17d4e476fb4d35d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Change Log for Grizzled Ruby
2
2
 
3
+ Version 0.1.5 (...)
4
+
5
+ - Added `WrapMany` class.
6
+
3
7
  Version 0.1.4 (25 March, 2011)
4
8
 
5
9
  - Fixed some gem issues.
data/Rakefile CHANGED
@@ -1,9 +1,10 @@
1
- # -*- ruby -*-
1
+ #
2
2
  #
3
3
  # NOTE: Man pages use the 'ronn' gem. http://rtomayko.github.com/ronn/
4
4
 
5
5
  require 'rake/clean'
6
6
  require 'pathname'
7
+ require 'fileutils'
7
8
 
8
9
  PACKAGE = 'grizzled-ruby'
9
10
  GEMSPEC = "#{PACKAGE}.gemspec"
@@ -19,7 +20,8 @@ end
19
20
 
20
21
  def gem_name(spec)
21
22
  gem = load_gem(spec)
22
- "#{PACKAGE}-#{gem.version.to_s}.gem"
23
+ version = gem.version.to_s
24
+ "#{PACKAGE}-#{version}.gem"
23
25
  end
24
26
 
25
27
  GEM = gem_name(GEMSPEC)
@@ -45,13 +47,8 @@ desc "Build the gem (#{GEM})"
45
47
  task :gem => GEM
46
48
 
47
49
  file GEM => RUBY_FILES + ['Rakefile', GEMSPEC] do |t|
48
- require 'rubygems/builder'
49
- if !defined? Gem
50
- raise StandardError.new("Gem package not defined.")
51
- end
52
- spec = eval File.new(GEMSPEC).read
53
- Gem::Builder.new(spec).build
54
- end
50
+ sh "gem build #{GEMSPEC}"
51
+ end
55
52
 
56
53
  desc "Build the documentation, locally"
57
54
  task :doc => :rdoc
@@ -66,10 +63,9 @@ file 'rdoc' => RUBY_FILES do |t|
66
63
  end
67
64
 
68
65
  desc "Install the gem"
69
- task :install => :gem do |t|
70
- require 'rubygems/installer'
66
+ task :install => [:build, :gem] do |t|
71
67
  puts("Installing from #{GEM}")
72
- Gem::Installer.new(GEM).install
68
+ sh "gem install #{GEM}"
73
69
  end
74
70
 
75
71
  desc "Publish the gem"
@@ -3,14 +3,13 @@
3
3
  Gem::Specification.new do |s|
4
4
 
5
5
  s.name = 'grizzled-ruby'
6
- s.version = '0.1.4'
7
- s.date = '2011-03-25'
6
+ s.version = '0.1.7'
7
+ s.date = '2015-09-08'
8
8
  s.summary = 'Some general-purpose Ruby modules, classes, and tools'
9
9
  s.authors = ['Brian M. Clapper']
10
10
  s.license = 'BSD'
11
11
  s.email = 'bmc@clapper.org'
12
12
  s.homepage = 'http://software.clapper.org/grizzled-ruby'
13
- s.has_rdoc = true
14
13
 
15
14
  s.description = <<-ENDDESC
16
15
  Grizzled Ruby is a general purpose library of Ruby modules, classes and tools.
@@ -18,6 +17,8 @@ ENDDESC
18
17
 
19
18
  s.require_paths = ['lib']
20
19
 
20
+ s.add_runtime_dependency 'zip', '~> 2.0', '>= 2.0.2'
21
+
21
22
  # = MANIFEST =
22
23
  s.files = Dir.glob('[A-Z]*')
23
24
  s.files += Dir.glob('*.gemspec')
@@ -26,7 +27,7 @@ ENDDESC
26
27
 
27
28
 
28
29
  # = MANIFEST =
29
- s.test_files = FileList['test/**/tc_*.rb'].to_a
30
+ s.test_files = Dir.glob('test/**/tc_*.rb')
30
31
  end
31
32
 
32
33
 
@@ -122,10 +122,14 @@ module Grizzled
122
122
  make_directory_tree(entry, contents)
123
123
 
124
124
  elsif contents.kind_of? Enumerable
125
- f = File.open(File.join(entry), 'w')
126
- contents.each {|thing| f.write(thing.to_s)}
127
- f.close
125
+ File.open(File.join(entry), 'w') do |f|
126
+ contents.each {|thing| f.write(thing.to_s)}
127
+ end
128
128
 
129
+ elsif contents.kind_of? String
130
+ File.open(entry, "w") do |f|
131
+ f.write(contents)
132
+ end
129
133
  else
130
134
  raise BadDirectoryTreeValue.new(entry, contents)
131
135
  end
@@ -61,6 +61,39 @@ module Grizzled
61
61
  end
62
62
  end
63
63
 
64
+ # Internal wrapper for multiple files
65
+ class FileIterator
66
+ def initialize(paths)
67
+ @files = paths
68
+ end
69
+
70
+ def each_line(&block)
71
+ @files.each do |path|
72
+ File.open path do |f|
73
+ f.each_line do |line|
74
+ block.call(line)
75
+ end
76
+ end
77
+ end
78
+ nil
79
+ end
80
+ end
81
+
82
+ # Internal fake URI
83
+ class FakeURI < URI::Generic
84
+ def initialize(path)
85
+ super(scheme=nil,
86
+ userinfo=nil,
87
+ host=nil,
88
+ port=nil,
89
+ registry=nil,
90
+ path=path,
91
+ opaque=nil,
92
+ query=nil,
93
+ fragment=nil)
94
+ end
95
+ end
96
+
64
97
  # == Introduction
65
98
  #
66
99
  # An +Includer+ object preprocesses a text file, resolve _include_
@@ -136,10 +169,13 @@ module Grizzled
136
169
  # include_pattern:: String regex pattern to match include directives.
137
170
  # Must have a single regex group for the file name
138
171
  # or URL. Default: ^%include\s"([^"]+)"
172
+ # allow_glob:: For file names, allow and expand glob expressions.
173
+ # Doesn't apply to URLs.
139
174
  def initialize(source, options={})
140
175
  @max_nesting = options.fetch(:max_nesting, 100)
141
176
  inc_pattern = options.fetch(:include_pattern, '^%include\s"([^"]+)"')
142
177
  @include_re = /#{inc_pattern}/
178
+ @allow_glob = options.fetch(:allow_glob, false)
143
179
  includer_source = source_to_includer_source source
144
180
  @source_uri = includer_source.uri
145
181
  @temp = preprocess includer_source
@@ -206,14 +242,18 @@ module Grizzled
206
242
  # Handle an include reference.
207
243
  def process_include(source, parent_input)
208
244
  cur_uri = parent_input.uri
209
- uri = URI::parse(source)
245
+ begin
246
+ uri = URI::parse(source)
247
+ rescue URI::InvalidURIError
248
+ uri = FakeURI.new(source)
249
+ end
210
250
  if (cur_uri != nil) and (uri.scheme == nil)
211
251
  # Could be a relative path. Should be relative to the parent input.
212
252
  pathname = Pathname.new(source)
213
253
  if not pathname.absolute?
214
254
  # Not an absolute path, and the including source has a path
215
255
  # (i.e., wasn't a string). Make this one relative to the path.
216
- uri = cur_uri.clone
256
+ uri = cur_uri.clone
217
257
  uri.path = File.join(::File.dirname(cur_uri.path), source)
218
258
  end
219
259
  end
@@ -224,7 +264,7 @@ module Grizzled
224
264
  # Open an input source, based on a parsed URI.
225
265
  def open_source(uri)
226
266
  case uri.scheme
227
- when nil then f = open(uri.path) # assume file/path
267
+ when nil then f = open_path(uri.path) # assume file/path
228
268
  when 'file' then f = open(uri.path) # open path directly
229
269
  when 'http' then f = open(uri.to_s) # open-uri will handle it
230
270
  when 'https' then f = open(uri.to_s) # open-uri will handle it
@@ -235,6 +275,14 @@ module Grizzled
235
275
 
236
276
  IncludeSource.new(f, uri)
237
277
  end
278
+
279
+ def open_path(path)
280
+ if @allow_glob
281
+ FileIterator.new(Dir.glob(path))
282
+ else
283
+ File.open(path)
284
+ end
285
+ end
238
286
  end # class Includer
239
287
 
240
288
  end # module File
@@ -0,0 +1,86 @@
1
+ require 'ostruct'
2
+
3
+ # Adapted from https://gist.github.com/1120383
4
+ #
5
+ # Wraps multiple objects in a single object. Method calls are resolved by
6
+ # cycling through all wrapped objects, in the order they were specified on
7
+ # the constructor, looking for the appropriate named method. Useful for
8
+ # temporarily adding methods to an instance, without monkeypatching the
9
+ # class.
10
+ #
11
+ # WrapMany has special-case logic for OpenStruct objects, Hash objects and
12
+ # object fields. Hash keys, OpenStruct fields, and public instance
13
+ # variables will be resolved, but only for calls made with no parameters.
14
+ #
15
+ # Example 1: Add an "age" value to a User object using an OpenStruct
16
+ #
17
+ # require 'ostruct'
18
+ # require 'grizzled/wrapmany'
19
+ #
20
+ # age_holder = OpenStruct.new(:age => 43)
21
+ # u = User.find(...)
22
+ # user_with_age = WrapMany.new(u, age_holder)
23
+ #
24
+ # Example 2: Add an "age" value to a User object using a hash
25
+ #
26
+ # require 'grizzled/wrapmany'
27
+ #
28
+ # u = User.find(...)
29
+ # user_with_age = WrapMany.new(u, {:age => 43})
30
+ #
31
+ # Example 3: Add an "age" value to a User object using another class
32
+ #
33
+ # require 'grizzled/wrapmany'
34
+ #
35
+ # class AgeHolder
36
+ # def initialize(age)
37
+ # @age = age
38
+ # end
39
+ # end
40
+ #
41
+ # u = User.find(...)
42
+ # user_with_age = WrapMany.new(u, AgeHolder.new(43))
43
+ class WrapMany
44
+ def initialize(*args)
45
+ # Map any OpenStruct objects in the arguments to hashes, and add the
46
+ # current object (in case someone subclasses this class)
47
+ @objects = args.to_a.map {
48
+ |a| a.is_a?(OpenStruct) ? a.instance_variable_get("@table") : a
49
+ } + [self]
50
+ end
51
+
52
+ def method_missing(meth, *args, &block)
53
+ method_name = meth.to_s
54
+
55
+ # Loop through all objects, looking for something that satisfies the
56
+ # method name.
57
+ @objects.each do |o|
58
+
59
+ # First determine if the method exists as a public instance method.
60
+ # If so, call it.
61
+ if o.class.public_instance_methods.include? method_name.to_sym
62
+ return o.send(method_name, *args, &block)
63
+ end
64
+
65
+ # Otherwise, if there are no arguments, then check for fields and
66
+ # hash keys
67
+ if args.length == 0
68
+ if o.instance_variables.include? ":@#{method_name}"
69
+ return o.instance_variable_get method_name
70
+ end
71
+
72
+ # Special case for hash
73
+ if o.is_a? Hash
74
+ if o.has_key? meth
75
+ return o[meth]
76
+ elsif o.has_key? method_name
77
+ return o[method_name]
78
+ end
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ raise NoMethodError.new("Undefined method: '#{method_name}'", meth)
85
+ end
86
+ end
@@ -64,7 +64,32 @@ EOF
64
64
  assert_equal(contents, bytes)
65
65
  end
66
66
  end
67
-
67
+
68
+ def test_glob
69
+ temp1 = File.open("/tmp/foo1.txt", "w")
70
+ temp2 = File.open("/tmp/foo2.txt", "w")
71
+ main = Tempfile.new("inctest")
72
+
73
+ temp1.write <<EOF1
74
+ one-1
75
+ two-1
76
+ EOF1
77
+
78
+ temp2.write <<EOF2
79
+ one-2
80
+ two-2
81
+ EOF2
82
+ temp1.close
83
+ temp2.close
84
+ File.open(main, "w") do |f|
85
+ f.write('%include "/tmp/foo[0-9]*.txt"\n')
86
+ end
87
+
88
+ inc = Includer.new(main.path, allow_glob: true)
89
+ contents = inc.read
90
+ assert_equal("one-1\ntwo-1\none-2\ntwo-2\n", contents)
91
+ end
92
+
68
93
  private
69
94
 
70
95
  def make_include_file
@@ -65,7 +65,7 @@ class ZipMixinTestDriver < Test::Unit::TestCase
65
65
  end
66
66
 
67
67
  def test_non_recursive
68
- expected_files = ['foo.txt', 'bar.txt']
68
+ expected_files = ['foo.txt', 'bar.txt'].sort
69
69
  Dir.mktmpdir 'ziptest' do |tmpdir|
70
70
  FileUtils.cd tmpdir do
71
71
 
@@ -85,7 +85,7 @@ class ZipMixinTestDriver < Test::Unit::TestCase
85
85
  with_tempfile('ziptest', '.zip') do |t|
86
86
  zip t.path, tmpdir, :dir_at_top => false, :recursive => false
87
87
 
88
- assert_equal expected_files, zip_file_entries(t.path).to_a
88
+ assert_equal expected_files, zip_file_entries(t.path).to_a.sort
89
89
  end
90
90
  end
91
91
  end
data/test/tc_forwarder.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require './test_helper'
2
2
  require 'test/unit'
3
3
  require 'tempfile'
4
4
  require 'grizzled/forwarder'
data/test/tc_stack.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require './test_helper'
2
2
  require 'test/unit'
3
3
  require 'grizzled/stack'
4
4
 
metadata CHANGED
@@ -1,93 +1,91 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: grizzled-ruby
3
- version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 4
10
- version: 0.1.4
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.7
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Brian M. Clapper
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2011-03-25 00:00:00 -04:00
19
- default_executable:
20
- dependencies: []
21
-
11
+ date: 2015-09-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: zip
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.2
22
33
  description: |
23
34
  Grizzled Ruby is a general purpose library of Ruby modules, classes and tools.
24
-
25
35
  email: bmc@clapper.org
26
36
  executables: []
27
-
28
37
  extensions: []
29
-
30
38
  extra_rdoc_files: []
31
-
32
- files:
33
- - README.md
34
- - LICENSE.md
39
+ files:
35
40
  - CHANGELOG.md
41
+ - LICENSE.md
42
+ - README.md
36
43
  - Rakefile
37
44
  - grizzled-ruby.gemspec
45
+ - lib/grizzled.rb
46
+ - lib/grizzled/dir.rb
38
47
  - lib/grizzled/fileutil.rb
39
- - lib/grizzled/stack.rb
40
48
  - lib/grizzled/fileutil/includer.rb
41
49
  - lib/grizzled/fileutil/ziputil.rb
42
- - lib/grizzled/dir.rb
43
50
  - lib/grizzled/forwarder.rb
51
+ - lib/grizzled/stack.rb
44
52
  - lib/grizzled/string/template.rb
45
53
  - lib/grizzled/unix.rb
46
- - lib/grizzled.rb
47
- - test/tc_stack.rb
48
- - test/tc_forwarder.rb
49
- - test/fileutil/tc_zip.rb
54
+ - lib/grizzled/wrapmany.rb
50
55
  - test/fileutil/tc_includer.rb
51
56
  - test/fileutil/tc_make_dir_tree.rb
57
+ - test/fileutil/tc_zip.rb
52
58
  - test/string/tc_template.rb
53
- has_rdoc: true
59
+ - test/tc_forwarder.rb
60
+ - test/tc_stack.rb
54
61
  homepage: http://software.clapper.org/grizzled-ruby
55
- licenses:
62
+ licenses:
56
63
  - BSD
64
+ metadata: {}
57
65
  post_install_message:
58
66
  rdoc_options: []
59
-
60
- require_paths:
67
+ require_paths:
61
68
  - lib
62
- required_ruby_version: !ruby/object:Gem::Requirement
63
- none: false
64
- requirements:
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
65
71
  - - ">="
66
- - !ruby/object:Gem::Version
67
- hash: 3
68
- segments:
69
- - 0
70
- version: "0"
71
- required_rubygems_version: !ruby/object:Gem::Requirement
72
- none: false
73
- requirements:
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
74
76
  - - ">="
75
- - !ruby/object:Gem::Version
76
- hash: 3
77
- segments:
78
- - 0
79
- version: "0"
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
80
79
  requirements: []
81
-
82
80
  rubyforge_project:
83
- rubygems_version: 1.5.0
81
+ rubygems_version: 2.2.2
84
82
  signing_key:
85
- specification_version: 3
83
+ specification_version: 4
86
84
  summary: Some general-purpose Ruby modules, classes, and tools
87
- test_files:
88
- - test/tc_stack.rb
89
- - test/tc_forwarder.rb
90
- - test/fileutil/tc_zip.rb
85
+ test_files:
91
86
  - test/fileutil/tc_includer.rb
92
87
  - test/fileutil/tc_make_dir_tree.rb
88
+ - test/fileutil/tc_zip.rb
93
89
  - test/string/tc_template.rb
90
+ - test/tc_forwarder.rb
91
+ - test/tc_stack.rb