fun_with_gems 0.0.2 → 0.0.8

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 (61) hide show
  1. checksums.yaml +5 -13
  2. data/.document +5 -0
  3. data/CHANGELOG.markdown +29 -0
  4. data/Gemfile +6 -11
  5. data/README.rdoc +125 -1
  6. data/ROADMAP.md +6 -0
  7. data/Rakefile +15 -46
  8. data/VERSION +1 -1
  9. data/lib/fun_with/gems/api_extender.rb +46 -0
  10. data/lib/fun_with/gems/configuration_installer.rb +86 -0
  11. data/lib/fun_with/gems/constant_builder.rb +36 -0
  12. data/lib/fun_with/gems/core_extender.rb +65 -0
  13. data/lib/fun_with/gems/core_extensions/module.rb +9 -3
  14. data/lib/fun_with/gems/fun_gem_api.rb +62 -3
  15. data/lib/fun_with/gems/gem_api.rb +78 -47
  16. data/lib/fun_with/gems/inclusionizer.rb +34 -0
  17. data/lib/fun_with/gems/library_requirer.rb +54 -0
  18. data/lib/fun_with/gems/rake_class_methods.rb +111 -0
  19. data/lib/fun_with/gems/rakefile.rb +114 -0
  20. data/lib/fun_with/gems/root_setter.rb +19 -0
  21. data/lib/fun_with/gems/test_case_extender.rb +27 -0
  22. data/lib/fun_with/gems/testing/assertions.rb +22 -0
  23. data/lib/fun_with/gems/testing/gem_to_test_methods.rb +37 -0
  24. data/lib/fun_with/gems/testing/test_case_extensions.rb +39 -0
  25. data/lib/fun_with/gems/testing/test_results.rb +40 -0
  26. data/lib/fun_with/gems/testing/test_setup.rb +22 -0
  27. data/lib/fun_with/gems/testing/test_suite_runner.rb +28 -0
  28. data/lib/fun_with/gems/testing/validator.rb +52 -0
  29. data/lib/fun_with/gems/versionizer.rb +41 -0
  30. data/lib/fun_with_gems.rb +15 -14
  31. data/lib/tasks/fun_with/gems/publish.rake +8 -0
  32. data/lib/tasks/fun_with/gems/validate.rake +28 -0
  33. data/tasks/empty/empty.rake +6 -0
  34. data/tasks/empty/environment.rake +7 -0
  35. data/test/assertions.rb +15 -0
  36. data/test/data/test_gems/array_inherits_enumerable/VERSION +1 -0
  37. data/test/data/test_gems/array_inherits_enumerable/lib/array_inherits_enumerable/core_extensions/comparable.rb +9 -0
  38. data/test/data/test_gems/array_inherits_enumerable/lib/array_inherits_enumerable/core_extensions/enumerable.rb +10 -0
  39. data/test/data/test_gems/array_inherits_enumerable/lib/array_inherits_enumerable/core_extensions/numeric.rb +22 -0
  40. data/test/data/test_gems/array_inherits_enumerable/lib/array_inherits_enumerable.rb +1 -0
  41. data/test/data/test_gems/fun_with_llamas/lib/fun_with/llamas/gem_api.rb +10 -0
  42. data/test/data/test_gems/fun_with_llamas/lib/fun_with/llamas/llama.rb +40 -0
  43. data/test/data/test_gems/fun_with_llamas/lib/fun_with/llamas/trainer.rb +15 -0
  44. data/test/data/test_gems/integer_magic/VERSION +1 -0
  45. data/test/data/test_gems/integer_magic/config/gem_config.rb +4 -0
  46. data/test/data/test_gems/integer_magic/lib/integer_magic/core_extensions/integer.rb +28 -0
  47. data/test/data/test_gems/integer_magic/lib/integer_magic/core_extensions/numeric.rb +13 -0
  48. data/test/data/test_gems/integer_magic/lib/integer_magic.rb +1 -0
  49. data/test/helper.rb +9 -38
  50. data/test/test_core_extensions.rb +10 -0
  51. data/test/test_fun_with_gems.rb +9 -16
  52. data/test/test_library_requirer.rb +13 -0
  53. data/test/test_the_test_case.rb +24 -0
  54. data/test/test_the_test_gems.rb +152 -0
  55. metadata +123 -40
  56. data/lib/fun_with/gems/mechanic.rb +0 -27
  57. data/lib/fun_with/gems/validator.rb +0 -69
  58. data/test/test_gem/lib/fun_with/llamas/llama.rb +0 -9
  59. data/test/test_gem/lib/fun_with/llamas/trainer.rb +0 -9
  60. /data/test/{test_gem → data/test_gems/fun_with_llamas}/VERSION +0 -0
  61. /data/test/{test_gem → data/test_gems/fun_with_llamas}/lib/fun_with_llamas.rb +0 -0
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MWQ2MWFiMGFiMjIzYWZiYmJjM2UzZDZlZTIxZDZlZDZhNGIxNzc1YQ==
5
- data.tar.gz: !binary |-
6
- ZWU1MTRmMDBjMzIzMTZlZjJlYzFhMGMxMWNjNTlmZjQ3MWZkNWQ0OA==
2
+ SHA256:
3
+ metadata.gz: 047eb9c496f911ffcd7b0b94617cfee8cbc735525adf3058a71bbd26ef01447b
4
+ data.tar.gz: df363108b13235a078b5100409bc2d7e7884dbcc2bb86ec5cd7a9f76bf8805ce
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NzYxZDVhYzVmNWMxZGE2NWRmYjZjNmRiYzg2YWZmYTg2NzdmYjMzOTFhNjVm
10
- MDczNWE3NGUyNzZkY2NkNGI2MjQwZDBjMTEyNDgzNDc1ZmNmZTI5NzFiZjkz
11
- NzkzY2E1MDZhODkyYjIyNmQwMDk3NzJlMWM2MDY4Nzc2NGEzODY=
12
- data.tar.gz: !binary |-
13
- NzQyMTZkZWYxMDI4N2RlYzY3ZjEzODQyZDUwODVmMzQ4NWQ2MDc5NGVlNjBl
14
- ZjMzMTU0OTZjOWFmYzA5ZTczNGZlNDYwOGI0NGRhMWE3NzRiNTlkOWJmNzAy
15
- MDU4MTAxYTcyOWE0MjQzMGEwMjMxOWZkNDM5MjYxZDk5MDUzZDc=
6
+ metadata.gz: 7c7070b49f2736547ed9f8a5238742078b266226eeeb57130e64dbb5d1446c3bc9a05948a2a61270abb3dc153ba0e233a22a75ed135929ad209e6b20d9cfe718
7
+ data.tar.gz: ef5c76523965a3049a8a97d0b6fb4606ba1a0c557282ffb14ec27fdd02e521f7566509e47a3bfc1bc99f86c6f0be9b1fe2787d7d938fada0fd8865369abd868b
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/CHANGELOG.markdown CHANGED
@@ -1,11 +1,40 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ v0.0.7
5
+ ------
6
+
7
+ Separating some functionality into other gems. Or not? I think this is an old comment. The idea was to break off a bunch of gems and have FWG bring them in as dependencies. But I never got around to it. Requirements gem might be a good candidate.
8
+
9
+ Maybe keep the gem monolithic, but figure out how to let users do `require "fun_with_gems/inclusionizer"` or something.
10
+
11
+ Consider also moving the testing/assertions into the test/lib directory for new gems, since only the test suite needs to see them.
12
+
13
+ v0.0.6
14
+ ------
15
+
16
+ * Simpler Rakefile, using expectations about which folders/files should be included. `add_specification_files()`
17
+ * Added auto-loading of Gem::Name::CoreExtension modules to base classes.
18
+ * FunWith::Gems::Inclusionizer provides a useful, opinionated way to organize your code for mixins.
19
+
20
+ v0.0.5
21
+ ------
22
+
23
+ Moved all "test the gem" code to a separate `fun_with_gemdev` gem.
24
+
25
+ v0.0.3
26
+ ------
27
+
28
+ Moved some of the standard Rakefile boilerplate into FunWith::Gems::Rakefile. Goal is to simplify rakefiles, add a set of fun_with:gems: rake tasks, etc.
29
+ Removed Mechanic (seemed pretty useless)
30
+
31
+
4
32
  v0.0.2
5
33
  ------
6
34
 
7
35
  Dependent on `fun_with_testing` and `fun_with_files`, even `fun_with_version_strings`. It's all very silly, really.
8
36
 
37
+
9
38
  0.0.1
10
39
  -----
11
40
 
data/Gemfile CHANGED
@@ -6,16 +6,11 @@ source "http://rubygems.org"
6
6
  # Add dependencies to develop your gem here.
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development do
9
- # gem "shoulda", "~> 3.5"
10
- # gem "rdoc", "~> 3.12"
11
- # gem "bundler", "~> 1.0"
12
- # gem "jeweler", "~> 2.0"
13
- # gem "simplecov", "~> 0", ">= 0.8"
14
-
15
- # Should be safe to add. By default, none of the assert functions get added to Test::Unit::TestCase
16
- gem "fun_with_testing", "~> 0.0"
9
+ gem "fun_with_testing", "~> 0.0", ">= 0.0.8"
17
10
  end
18
11
 
19
- gem "fun_with_files", "~> 0.0", ">= 0.0.7"
20
- gem "fun_with_version_strings", "~> 0.0", ">= 0.0.3"
21
-
12
+ gem "juwelier"
13
+ gem "rake"
14
+ gem "fun_with_files", "~> 0.0", ">= 0.0.17"
15
+ gem "fun_with_version_strings", "~> 0.0", ">= 0.0.4"
16
+ gem "sorted_set" # why is it even asking for this?
data/README.rdoc CHANGED
@@ -1,5 +1,129 @@
1
1
  = fun_with_gems
2
2
 
3
+ Opinionated Ruby gems with a consistent file schema. Gems made easy.
4
+
5
+ FunWith::Gems assumes turns one of the modules defined in your gem folder to be "the fun gem."
6
+
7
+ You define the gem in the file lib/<gem_initialization_file>.rb by putting the following contents in it:
8
+
9
+ require 'fun_with_gems'
10
+ FunWith::Gems.make_gem_fun( "MyNeatoGem" )
11
+
12
+ Doing this has the following effects:
13
+
14
+ * Identifies the gem as being a 'fun gem' (`MyNeatoGem.is_fun_gem? => true`)
15
+ * learns where the gem's root directory is (you can find this info by calling `MyNeatoGem.root`)
16
+ * loads the "VERSION" file at the root of the directory (get via `MyNeatoGem.version`, `MyNeatoGem.version.(major|minor|patch)`)
17
+ * .version returns a subclass of string, but one that understands that "0.2" < "0.12", making version comparisons sensible.
18
+ * loads every file in the `<ROOT>/lib/<GEM_NAME>` directory. Don't expect them to be loaded in any specific order.
19
+ * If there is a file `lib/my_neato_gem/gem_api.rb`, we expect it to define MyNeatoGem::GemAPI, which is used to extend MyNeatoGem with callable methods.
20
+
21
+
22
+
23
+
24
+
25
+
26
+ Should also:
27
+
28
+ * TODO: Check for API modules and attach them to their apis. For example, if there's a lib/my_neato_gem/api.rb, and it defines a module MyNeatoGem::API, the MyNeatoGem module should be extended with the module
29
+
30
+
31
+ Testing!
32
+
33
+ Simplifies your Rakefile
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+ Testing
43
+ -------
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+ Where to put things and what those things do
55
+ ---------------------------------------------
56
+
57
+ Let's say your gem is called Cobbler. It... cobbles... um, things. It lives in a folder called `cobbler`.
58
+
59
+ cobbler/ Cobbler.root() should return the location of this directory in the filespace
60
+ ↳ bin/
61
+ cobbler An executable that should maybe somehow be available from the command line.
62
+ Multiple executables might live here.
63
+
64
+ ↳ config/ Anything you could think of as "gem configuration" would go in this folder.
65
+ ↳ gem_config.rb Alternately, could be a YAML file (.yml or .yaml)
66
+ Either way, it gets loaded into a FunWith::Configurations::Config object
67
+ that can be accessed through Cobbler.config
68
+ ↳ cache/ Might make more sense to use the ~/.cache/cobbler_gem directory?
69
+ ↳ lib/
70
+ ↳ cobbler.rb Where the gem initialization stuff lives (including invoking make_gem_fun())
71
+ ↳ cobbler/
72
+ ↳ core_extensions/
73
+ ↳ string.rb
74
+ ↳ nil_class.rb Cobbler::CoreExtensions::NilClass gets included in nil, making nil more useful
75
+ ↳ integer.rb Cobbler::CoreExtensions::Integer extends the Integer class
76
+
77
+ ↳ gem_api.rb Cobbler::GemAPI
78
+ ↳ testing/
79
+ ↳ assertions.rb This is where you put testing assertions that you want to be available
80
+ to gems that include Cobbler as a dependency
81
+ ↳ test_case_extensions.rb ????
82
+
83
+ ↳ fun_with/ Example: Anything that would extend a FunWith gem
84
+ ↳ active_record/ Example: Anything you'd use to extend/override something in ActiveRecord
85
+ It might not be good to encourage gem authors to do this sort of thing.
86
+
87
+ ↳ test/
88
+ ↳ data/ Data that the tests can test against. For example, if your gem plays with
89
+ ebooks, this might be a place to put compiled ebooks and source directory
90
+ trees. If it plays with images, sample images would go here.
91
+ ↳ fixtures/ (not implemented)
92
+ ↳ lib/
93
+ useful_testing_class.rb Classes that you can use in testing. Everything in the directory gets
94
+ require'd before the tests run.
95
+ ↳ VERSION The file contains a simple string, like 12.3.11
96
+ calling Cobbler.version returns a VersionString object (a string that also responds
97
+ to major(), minor(), patch() etc, and comparisons between version strings actually
98
+ work as you'd hope)
99
+
100
+ ↳ Rakefile
101
+ ↳ Gemfile
102
+
103
+
104
+ For local settings, FunWith::Gems tries to loosely follow the XDG guidelines, which can be found at https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html .
105
+
106
+ (proposed)
107
+
108
+ ~/.config/cobbler.gem/gem_config.(rb/yml) # if present, the configuration can override and extend gem configurations
109
+ ~/.cache/cobbler.gem/ # data caches and whatnot
110
+
111
+ This could be improved further by checking for the $XDG_ environment variables
112
+
113
+ How much use is there for both a gem cache and a user cache?
114
+
115
+
116
+
117
+
118
+
119
+
120
+ Features:
121
+
122
+ * Version...ing?
123
+
124
+
125
+
126
+
3
127
  Description goes here.
4
128
 
5
129
  == Contributing to fun_with_gems
@@ -14,6 +138,6 @@ Description goes here.
14
138
 
15
139
  == Copyright
16
140
 
17
- Copyright (c) 2014 Bryce Anderson. See LICENSE.txt for
141
+ Copyright (c) 2020 Bryce Anderson. See LICENSE.txt for
18
142
  further details.
19
143
 
data/ROADMAP.md ADDED
@@ -0,0 +1,6 @@
1
+ It might not be the absolute best idea, but I also want FW::Gems to become a Juweiler/hoe/etc. gem manager, drawing on ideas from the others.
2
+
3
+ Maybe https://github.com/postmodern/rubygems-tasks is the right approach. The gem you build and the gem you use to publish it really shouldn't have anything to do with each other.
4
+
5
+ I've got that FunWith::Templates gem template directory. That could use a lot of polish (pardon the pun).
6
+
data/Rakefile CHANGED
@@ -1,55 +1,24 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'rubygems'
4
- require 'bundler'
5
- begin
6
- Bundler.setup(:default, :development)
7
- rescue Bundler::BundlerError => e
8
- $stderr.puts e.message
9
- $stderr.puts "Run `bundle install` to install missing gems"
10
- exit e.status_code
11
- end
12
- require 'rake'
3
+ require_relative 'lib/fun_with_gems'
4
+ self.extend( FunWith::Gems::Rakefile )
5
+
6
+ rakefile_setup( FunWith::Gems )
7
+
13
8
 
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |gem|
9
+
10
+ gem_specification do |gem|
16
11
  # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
- gem.name = "fun_with_gems"
18
- gem.homepage = "http://github.com/darthschmoo/fun_with_gems"
19
- gem.license = "MIT"
20
- gem.summary = "Dependency for most of my FunWith:: gems. Not much use standalone."
12
+ gem.name = "fun_with_gems"
13
+ gem.homepage = "http://github.com/darthschmoo/fun_with_gems"
14
+ gem.license = "MIT"
15
+ gem.summary = "Dependency for most of my FunWith:: gems. Not much use standalone."
21
16
  gem.description = "Dependency for FunWith gems, simplifies the setup of new gems, installing version data, root filepath, and default requirements."
22
- gem.email = "keeputahweird@gmail.com"
23
- gem.authors = ["Bryce Anderson"]
17
+ gem.email = "keeputahweird@gmail.com"
18
+ gem.authors = ["Bryce Anderson"]
24
19
  # dependencies defined in Gemfile
25
20
 
26
- gem.files = Dir.glob( File.join( ".", "lib", "**", "*.rb" ) ) +
27
- Dir.glob( File.join( ".", "test", "**", "*" ) ) +
28
- %w( Gemfile Rakefile LICENSE.txt README.rdoc VERSION CHANGELOG.markdown )
29
- end
30
- Jeweler::RubygemsDotOrgTasks.new
31
-
32
- require 'rake/testtask'
33
- Rake::TestTask.new(:test) do |test|
34
- test.libs << 'lib' << 'test'
35
- test.pattern = 'test/**/test_*.rb'
36
- test.verbose = true
21
+ add_specification_files( gem, :default )
37
22
  end
38
23
 
39
- desc "Code coverage detail"
40
- task :simplecov do
41
- ENV['COVERAGE'] = "true"
42
- Rake::Task['test'].execute
43
- end
44
-
45
- task :default => :test
46
-
47
- require 'rdoc/task'
48
- Rake::RDocTask.new do |rdoc|
49
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
-
51
- rdoc.rdoc_dir = 'rdoc'
52
- rdoc.title = "fun_with_gems #{version}"
53
- rdoc.rdoc_files.include('README*')
54
- rdoc.rdoc_files.include('lib/**/*.rb')
55
- end
24
+ setup_gem_boilerplate
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.8
@@ -0,0 +1,46 @@
1
+ module FunWith
2
+ module Gems
3
+ class ApiExtender
4
+ def self.extend_with_api( *args, &block )
5
+ self.new(*args,&block).extend_with_api
6
+ end
7
+
8
+ def initialize(const)
9
+ @const = const
10
+ end
11
+
12
+ def extend_with_api
13
+ api = get_gem_api_module
14
+
15
+ if api.is_a?(Module)
16
+ @const.extend( api )
17
+ end
18
+ end
19
+
20
+ def get_gem_api_module
21
+ existing_gem_api_constant || load_api_constant
22
+ end
23
+
24
+ def load_api_constant
25
+ if @const.respond_to?(:root)
26
+ rootpath = @const.root / :lib
27
+ gem_api_path = @const.to_s.gsub("::","/").gsub(/(.)([A-Z])/,'\1_\2').downcase
28
+
29
+ path = rootpath / gem_api_path
30
+
31
+ require path if path.ext(:rb).file?
32
+ existing_gem_api_constant # maybe it exists now?
33
+ end
34
+ end
35
+
36
+ def existing_gem_api_constant
37
+ return @const::GemAPI if defined?(@const::GemAPI)
38
+ return @const::API if defined?(@const::API)
39
+ return @const::GemApi if defined?(@const::GemApi)
40
+
41
+ return nil
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,86 @@
1
+ module FunWith
2
+ module Gems
3
+ class ConfigurationInstaller
4
+ def self.install_configuration( *args, &block )
5
+ self.new.install_configuration( *args, &block )
6
+ end
7
+
8
+ def install_configuration( gc, opts = {} )
9
+ cfg = opts.fetch(:configuration){ false }
10
+
11
+ if configuration_needed?( gc, cfg )
12
+ return false unless load_fun_with_configurations
13
+
14
+ cfg = get_configuration( gc, cfg )
15
+
16
+ if cfg.is_a?( FunWith::Configurations::Config )
17
+ gc.install_fwc_config( cfg )
18
+ end
19
+ end
20
+ end
21
+
22
+ protected
23
+ # If no configuration (or file) was passed in as an argument and a magic file doesn't exist
24
+ # for the gem configuration, don't do anything
25
+ def configuration_needed?( gc, cfg = false )
26
+ return false if cfg == :skip
27
+ return true if cfg # user has provided a configuration
28
+ # a configuration has already been installed, or .config() is already defined
29
+ return false if gc.respond_to?( :config )
30
+
31
+ # returns false if there's no magic file below the gem's root
32
+ gem_default_configuration_file( gc ) ? true : false
33
+ end
34
+
35
+ #
36
+ def load_fun_with_configurations
37
+ require 'fun_with_configurations' unless defined?( FunWith::Configurations )
38
+ true
39
+ rescue LoadError
40
+ false
41
+ end
42
+
43
+ # returns a FunWith::Configurations::Config option which can be installed on the gem
44
+ #
45
+ # if
46
+ def get_configuration( gc, cfg )
47
+ case cfg
48
+ when :skip
49
+ return false # don't try to install a configuration, not even the default one
50
+ when FunWith::Configurations::Config
51
+ return cfg
52
+ when Hash
53
+ return FunWith::Configurations::Config.from_hash( cfg )
54
+ when FunWith::Files::FilePath
55
+ return get_configuration_from_file( cfg )
56
+ when String
57
+ # assume we've been given a filepath
58
+ return get_configuration_from_file( cfg.fwf_filepath )
59
+ when false
60
+ #
61
+ return get_configuration_from_file( gem_default_configuration_file( gc ) ) # returns
62
+ end
63
+ end
64
+
65
+ def get_configuration_from_file( f )
66
+ return false if f == false
67
+ (f.file? && f.readable?) ? FunWith::Configurations::Config.from_file( f ) : false
68
+ end
69
+
70
+ # Default configuration file is either <GEM_ROOT>/config/gem_config.(yml or rb).
71
+ # If both exist, the .rb file is returned
72
+ def gem_default_configuration_file( gc )
73
+ return false unless gc.respond_to?(:root)
74
+ config_dir = gc.root / :config
75
+
76
+ for filename in ["gem_config.rb", "gem_config.yml", "gem_config.yaml"]
77
+ f = config_dir / filename
78
+
79
+ return f if (f.file? && f.readable?)
80
+ end
81
+
82
+ return false
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,36 @@
1
+ module FunWith
2
+ module Gems
3
+ class ConstantBuilder
4
+ def self.build_constant( *args, &block )
5
+ self.new.build_constant( *args, &block )
6
+ end
7
+
8
+ # Expecting that constants will only be passed as strings when the constants hasn't been previously defined.
9
+ #
10
+ # returns the constant
11
+ def build_constant( c )
12
+ if c.is_a?( String )
13
+ #create the module
14
+ const = Object
15
+
16
+ # go down the ::Module stack, creating modules along the way
17
+ full_const_name = ""
18
+ c.split("::").each do |module_name|
19
+ full_const_name << "::" unless full_const_name.fwf_blank?
20
+ full_const_name << module_name
21
+
22
+ if eval( "defined?(#{full_const_name})")
23
+ const = eval( full_const_name )
24
+ else
25
+ const = const.const_set( module_name, Module.new )
26
+ end
27
+ end
28
+
29
+ eval( c )
30
+ else
31
+ c
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,65 @@
1
+ module FunWith
2
+ module Gems
3
+ class CoreExtender
4
+ def self.extend_core( *args, &block )
5
+ self.new.extend_core( *args, &block )
6
+ end
7
+
8
+ def extend_core( gem_const )
9
+ return false unless defined?( gem_const::CoreExtensions )
10
+
11
+ ce = gem_const::CoreExtensions
12
+
13
+ for mod in ce.constants
14
+ if Object.const_defined?( mod )
15
+ original = Object.const_get( mod )
16
+ includable = ce.const_get( mod )
17
+ include_in_core( original, includable )
18
+ end
19
+ end
20
+ end
21
+
22
+ protected
23
+ def include_in_core( original, includable )
24
+ unless original.included_modules.include?( includable ) # it's already been included, so don't bother.
25
+ override_default_included_method( includable ) # basically gives it the inclusionizer treatment
26
+ original.send( :include, includable )
27
+ reinclude( original ) if original.is_a?( Module )
28
+ end
29
+ end
30
+
31
+ def override_default_included_method( includable )
32
+ # leave it alone if an #included() method is already defined,
33
+ # or if the module doesn't define the submodules that
34
+ # the new #included() method expects it to.
35
+ unless includable.respond_to?( :included ) || !( defined?(includable::ClassMethods) || defined?(includable::InstanceMethods) || defined?(includable::Constants) )
36
+ Inclusionizer.inclusionize( includable )
37
+ end
38
+ end
39
+
40
+ # There's something odd about Ruby. When you include a module into a module that is itself included in a class/module, the class/module
41
+ # needs the included module to be re-included, otherwise stuff doesn't show up.
42
+ def reinclude( const )
43
+ silence_deprecation_warnings do
44
+ @core_classes_and_modules = Object.constants.map{|sym| Object.const_get(sym) }.select{|cnst| cnst.is_a?(Class) || cnst.is_a?(Module)}
45
+
46
+ for klass in @core_classes_and_modules
47
+ if klass.included_modules.include?( const )
48
+ klass.send( :include, const )
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+
55
+ # reinclude() pulls up a bunch of classes that have been marked as deprecated, and spits out warnings.
56
+ def silence_deprecation_warnings(&block)
57
+ old_stderr = $stderr
58
+ $stderr = StringIO.new
59
+ yield
60
+ ensure
61
+ $stderr = old_stderr
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,5 +1,11 @@
1
- class Module
2
- def is_fun_gem?
3
- false
1
+ module FunWith
2
+ module Gems
3
+ module CoreExtensions
4
+ module Module
5
+ def is_fun_gem?
6
+ false
7
+ end
8
+ end
9
+ end
4
10
  end
5
11
  end
@@ -1,20 +1,28 @@
1
1
  module FunWith
2
2
  module Gems
3
+ # The API that gets added to a "gem module" by FunWithGems.make_gem_fun(*)
3
4
  module FunGemAPI
4
5
  def is_fun_gem?
5
6
  true
6
7
  end
7
8
 
8
9
  def validate_gem
9
- FunWith::Gems::Validator.new( self ).validate
10
+ errors = FunWith::Gems::Testing::Validator.validate self
11
+ errors
10
12
  end
11
13
 
12
14
  def valid_gem?
13
- self.validate_gem.fwf_blank?
15
+ errors = self.validate_gem
16
+ errors.fwf_blank?
17
+ end
18
+
19
+ def passes_tests?
20
+ FunWith::Gems::Testing::TestSuiteRunner.new( self ).passes_tests?
14
21
  end
15
22
 
16
23
  def gem_test_mode?
17
- @fwg_gem_test_mode || false
24
+ @fwg_gem_test_mode = false unless defined?( @fwg_gem_test_mode )
25
+ @fwg_gem_test_mode
18
26
  end
19
27
 
20
28
  # I can't think of a compelling reason to go beyond true/false here
@@ -33,6 +41,57 @@ module FunWith
33
41
  def say_if_verbose( msg, stream = $stdout )
34
42
  stream.puts( msg ) if gem_verbose?
35
43
  end
44
+
45
+ def setup_for_testing
46
+ FunWith::Gems::Testing::TestSetup.setup( self )
47
+ end
48
+
49
+ def load_tasks
50
+ load_internal_tasks
51
+ load_external_tasks
52
+ end
53
+
54
+ # Tasks in gem/tasks should be those which are specific to the gem itself.
55
+ # Tasks located here will not be made available to gems which depend on it.
56
+ # Made accessible during the Rakefile.setup
57
+ def load_internal_tasks
58
+ _load_tasks_from_directory self.root( "tasks" )
59
+ end
60
+
61
+ # Tasks in gem/lib/tasks will be usable by gems which have this gem as a dependency.
62
+ def load_external_tasks
63
+ _load_tasks_from_directory self.root( "lib", "tasks" )
64
+ end
65
+
66
+ protected
67
+ def _load_tasks_from_directory dir
68
+ _rake_gem_loaded? do
69
+ files = dir.glob.select{ |f|
70
+ f.file? && ( f.ext == "rb" || f.ext == "rake" )
71
+ }
72
+
73
+ return false if files.length == 0
74
+
75
+ unless Rake.respond_to?( :load_rakefile )
76
+ puts "Rake.load_rakefile missing: #{files.length} files will not be loaded."
77
+ return false
78
+ end
79
+
80
+ for file in files
81
+ Rake.load_rakefile( file )
82
+ end
83
+ end
84
+ end
85
+
86
+ def _rake_gem_loaded?( &block )
87
+ loaded = defined?( Gem ) && Gem.respond_to?( :loaded_specs ) && defined?( Rake ) && Gem.loaded_specs.keys.include?( "rake" )
88
+
89
+ if block_given?
90
+ yield if loaded
91
+ else
92
+ loaded
93
+ end
94
+ end
36
95
  end
37
96
  end
38
97
  end