appkernel 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.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.1.0 2009-06-29
2
+
3
+ * 1 major enhancement:
4
+ * functioning prototype which allows you to create portable, self-validating functions
data/Manifest.txt ADDED
@@ -0,0 +1,15 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/appkernel.rb
6
+ lib/appkernel/function.rb
7
+ lib/appkernel/validation.rb
8
+ script/console
9
+ script/destroy
10
+ script/generate
11
+ spec/appkernel/function_spec.rb
12
+ spec/appkernel/validation_spec.rb
13
+ spec/spec.opts
14
+ spec/spec_helper.rb
15
+ tasks/rspec.rake
data/README.rdoc ADDED
@@ -0,0 +1,73 @@
1
+ = appkernel
2
+
3
+ * http://github.com/cowboyd/appkernel
4
+
5
+ == DESCRIPTION:
6
+
7
+ AppKernel is a microframework for capturing your application in terms of minute, self-validating functions.
8
+ Once defined, these functions can be used in rails, cocoa, an sms gateway, or wherever you want to take them.
9
+
10
+ == FEATURES:
11
+
12
+ * Package the bits of your application in terms of what it *does*, not the entities it contains.
13
+ * Get a command line interface for free (that's better than vanilla script/console)
14
+
15
+ == SYNOPSIS:
16
+
17
+ module Foo
18
+ include AppKernel::Function
19
+
20
+ function :Hello do
21
+ option :to, :index => 1, :required => true
22
+
23
+ validate do
24
+ @to.check(@to != "spam", "I don't like spam!")
25
+ end
26
+
27
+ execute do
28
+ "Hello #{@to}!"
29
+ end
30
+ end
31
+
32
+ Hello("George") #=> "Hello, George!"
33
+ Hello(:to => "George") #=> "Hello, George!"
34
+ apply(Hello, "George").success? #=> true
35
+ apply(Hello, "George").return_value => "Hello, George!"
36
+
37
+ #Error Reporting
38
+
39
+ Hello("spam") #=> "Exception!! I don't like spam!"
40
+ apply(Hello, "spam").success? #=> false
41
+ apply(Hello, "spam").return_value #=> nil
42
+ apply(Hello, "spam").errors[:to] #=> "I don't like spam"
43
+ end
44
+
45
+
46
+ == INSTALL:
47
+
48
+ sudo gem install appkernel
49
+
50
+ == LICENSE:
51
+
52
+ (The MIT License)
53
+
54
+ Copyright (c) 2009 Charles Lowell <cowboyd@thefrontside.net>
55
+
56
+ Permission is hereby granted, free of charge, to any person obtaining
57
+ a copy of this software and associated documentation files (the
58
+ 'Software'), to deal in the Software without restriction, including
59
+ without limitation the rights to use, copy, modify, merge, publish,
60
+ distribute, sublicense, and/or sell copies of the Software, and to
61
+ permit persons to whom the Software is furnished to do so, subject to
62
+ the following conditions:
63
+
64
+ The above copyright notice and this permission notice shall be
65
+ included in all copies or substantial portions of the Software.
66
+
67
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
68
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
69
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
70
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
71
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
72
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
73
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
2
+ %w[rake rake/clean fileutils newgem rubigen].each { |f| require f }
3
+ $:.unshift(File.dirname(__FILE__) + '/lib') unless $:.member?(File.dirname(__FILE__) + '/lib')
4
+ require 'appkernel'
5
+
6
+ # Generate all the Rake tasks
7
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
8
+ $hoe = Hoe.new('appkernel', AppKernel::VERSION) do |p|
9
+ p.developer('Charles Lowell', 'cowboyd@thefrontside.net')
10
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
11
+ p.rubyforge_name = p.name # TODO this is default value
12
+ # p.extra_deps = [
13
+ # ['activesupport','>= 2.0.2'],
14
+ # ]
15
+ p.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ]
18
+
19
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
+ p.rsync_args = '-av --delete --ignore-errors'
23
+ end
24
+
25
+ require 'newgem/tasks' # load /tasks/*.rake
26
+ Dir['tasks/**/*.rake'].each { |t| load t }
27
+
28
+ # TODO - want other tests/tasks run by default? Add them to the list
29
+ # task :default => [:spec, :features]
@@ -0,0 +1,153 @@
1
+ require 'set'
2
+
3
+ class AppKernel
4
+ module Function
5
+
6
+ def apply(fun, *args)
7
+ FunctionApplication.new(fun, *args)
8
+ end
9
+
10
+ def self.included(mod)
11
+ class << mod
12
+ def function(symbol, &definition)
13
+ fun = ::AppKernel::FunctionDefinition.new(definition)
14
+ self.const_set(symbol, fun)
15
+ self.send(:define_method, symbol) do |*args|
16
+ FunctionApplication.apply_or_die(fun, *args)
17
+ end
18
+ if self.class == Module
19
+ self.send(:module_function, symbol)
20
+ else
21
+ class << self;self;end.send(:define_method, symbol) do |*args|
22
+ FunctionApplication.apply_or_die(fun, *args)
23
+ end
24
+ end
25
+ end
26
+
27
+ def apply(fun, *args)
28
+ FunctionApplication.new(fun, *args)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ class FunctionApplication
35
+
36
+ attr_reader :return_value, :errors, :function, :options
37
+
38
+ def initialize(fun, *args)
39
+ @function = fun
40
+ @args = args
41
+ @options = {}
42
+ @errors = {}
43
+ @return_value = self.class.do_apply(self, *args)
44
+ end
45
+
46
+ def successful?
47
+ @errors.empty?
48
+ end
49
+
50
+ class << self
51
+
52
+ def apply_or_die(fun, *args)
53
+ app = new(fun, *args)
54
+ if app.successful?
55
+ app.return_value
56
+ else
57
+ raise ValidationError, app
58
+ end
59
+ end
60
+
61
+ def do_apply(app, *args)
62
+ fun = app.function
63
+ instance = Object.new
64
+ indexed_options = fun.indexed_options
65
+ required_options = Set.new(fun.options.values.select {|o| o.required?})
66
+ for arg in args do
67
+ if arg.kind_of?(Hash)
68
+ arg.each do |k,v|
69
+ if opt = fun.options[k.to_sym]
70
+ opt.set instance, v
71
+ required_options.delete opt
72
+ app.options[opt.name] = v
73
+ end
74
+ end
75
+ elsif opt = indexed_options.shift
76
+ opt.set instance, arg
77
+ required_options.delete opt
78
+ app.options[opt.name] = arg
79
+ end
80
+ end
81
+ for opt in required_options do
82
+ app.errors[opt.name] = "Missing required option '#{opt.name}'"
83
+ end
84
+ app.errors.merge! fun.validation.validate(app.options)
85
+ instance.instance_eval &fun.impl if app.successful?
86
+ end
87
+ end
88
+ end
89
+
90
+ class FunctionDefinition
91
+
92
+ attr_reader :impl, :options, :validation
93
+
94
+ def initialize(definition)
95
+ @options = {}
96
+ @impl = lambda {}
97
+ @validation = ::AppKernel::Validation::Validator.new
98
+ self.instance_eval &definition
99
+ end
100
+
101
+ def option(name, params = {})
102
+ name = name.to_sym
103
+ @options[name] = Option.new(name, params)
104
+ end
105
+
106
+ def indexed_options
107
+ @options.values.select {|o| o.index}.sort_by {|a| a.index}
108
+ end
109
+
110
+ def execute(&impl)
111
+ @impl = impl
112
+ end
113
+
114
+ def validate(&checks)
115
+ @validation = AppKernel::Validation::Validator.new(&checks)
116
+ end
117
+
118
+ class Option
119
+ attr_reader :name, :index
120
+ def initialize(name, params)
121
+ @name = name
122
+ @index = params[:index]
123
+ @required = params[:required] == true
124
+ end
125
+
126
+ def set(o, value)
127
+ o.instance_variable_set("@#{@name}", value)
128
+ end
129
+
130
+ def required?
131
+ @required
132
+ end
133
+
134
+ def optional?
135
+ !@required
136
+ end
137
+ end
138
+
139
+ class Validator
140
+ end
141
+ end
142
+
143
+ class ValidationError < StandardError
144
+ def initialize(application)
145
+ @app = application
146
+ end
147
+
148
+ def message
149
+ @app.errors.values.first
150
+ end
151
+ end
152
+
153
+ end
@@ -0,0 +1,60 @@
1
+ require 'delegate'
2
+ module AppKernel::Validation
3
+ class Validator
4
+
5
+ attr_reader :errors
6
+
7
+ def initialize(&block)
8
+ @body = block
9
+ end
10
+
11
+ def validate(vars = {})
12
+ errors = {}
13
+ scope = Object.new
14
+ for k,v in vars do
15
+ val = case v
16
+ when nil
17
+ NilValue.new
18
+ when Fixnum
19
+ FixnumValue.new(v)
20
+ else
21
+ v.dup
22
+ end
23
+ val.extend Check
24
+ val.instance_eval do
25
+ @_add_validation_error = lambda {|message|
26
+ errors[k] = message
27
+ }
28
+ end
29
+ scope.instance_variable_set("@#{k}", val)
30
+ end
31
+ scope.instance_eval &@body if @body
32
+ errors
33
+ end
34
+
35
+ end
36
+
37
+ module Check
38
+ def check(condition, message)
39
+ unless condition
40
+ @_add_validation_error.call(message)
41
+ end
42
+ end
43
+ end
44
+
45
+ class NilValue < DelegateClass(NilClass)
46
+ def initialize
47
+ super(nil)
48
+ end
49
+
50
+ def nil?
51
+ true
52
+ end
53
+ end
54
+
55
+ class FixnumValue < DelegateClass(Fixnum)
56
+ def initialize(val)
57
+ super(val)
58
+ end
59
+ end
60
+ end
data/lib/appkernel.rb ADDED
@@ -0,0 +1,6 @@
1
+
2
+ class AppKernel
3
+ VERSION = "0.1.0"
4
+ require 'appkernel/function'
5
+ require 'appkernel/validation'
6
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/appkernel.rb'}"
9
+ puts "Loading appkernel gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,211 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe AppKernel::Function do
4
+
5
+ before(:each) do
6
+ @mod = Module.new do |mod|
7
+ mod.module_eval do
8
+ include AppKernel::Function
9
+ end
10
+ end
11
+ extend @mod
12
+ @klass = Class.new.class_eval do
13
+ include AppKernel::Function; self
14
+ end
15
+ end
16
+
17
+ it "allows modules to define an function functions" do
18
+ @mod.module_eval do
19
+ function :Say do
20
+ option :word
21
+
22
+ execute do
23
+ @word
24
+ end
25
+ end
26
+ Say(:word => "hello").should == "hello"
27
+ end
28
+ end
29
+
30
+ it "allows certain options to be the default option" do
31
+ @mod.module_eval do
32
+ function :Say do
33
+ option :greeting, :index => 0
34
+ option :to, :index => 1
35
+ option :extra
36
+
37
+ execute do
38
+ "#{@greeting} #{@to}#{(', ' + @extra) if @extra}"
39
+ end
40
+ end
41
+
42
+
43
+ Say("Hello", "Charles", :extra => "How are you?").should == "Hello Charles, How are you?"
44
+ Say("Hello", "Charles").should == "Hello Charles"
45
+ Say(:greeting => "Hello", :to => "Charles").should == "Hello Charles"
46
+ end
47
+ end
48
+
49
+ it "allows classes that include the module to also use the commands from that module" do
50
+ @mod.module_eval do
51
+ function :Included do
52
+ execute do
53
+ "It worked!"
54
+ end
55
+ end
56
+ end
57
+ mod = @mod
58
+ Class.new(Object).class_eval do
59
+ include mod
60
+ self
61
+ end.new.instance_eval do
62
+ Included().should == "It worked!"
63
+ end
64
+ end
65
+
66
+ it "allows classes to define functions as well as modules" do
67
+ @klass.class_eval do
68
+ function :Say do
69
+ option :word, :index => 1
70
+ execute do
71
+ @word
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ it "can be called by using the apply method instead of invoking it directly" do
78
+ @mod.module_eval do
79
+ function :FiveAlive do
80
+ option :desc, :index => 1
81
+ execute do
82
+ "FiveAlive is a #{@desc}"
83
+ end
84
+ end
85
+ end
86
+ result = apply(@mod::FiveAlive, "candy bar")
87
+ result.return_value.should == "FiveAlive is a candy bar"
88
+ result.successful?.should be(true)
89
+ end
90
+
91
+ it "can have required options, but they are never required by default" do
92
+ @mod.module_eval do
93
+ function :Say do
94
+ option :greeting, :index => 1, :required => true
95
+ option :to, :index => 2, :required => true
96
+ option :extra, :index => 3
97
+ end
98
+ end
99
+ result = apply(@mod::Say, "Hello", "World", "I'm doing fine.")
100
+ result.successful?.should be(true)
101
+ result = apply(@mod::Say)
102
+ result.return_value.should be(nil)
103
+ result.successful?.should be(false)
104
+ result.errors[:greeting].should_not be(nil)
105
+ result.errors[:to].should_not be(nil)
106
+ result.errors[:extra].should be(nil)
107
+ end
108
+
109
+ it "raises an error immediately if you try to call a function that has invalid arguments" do
110
+ @mod.module_eval do
111
+ function :Harpo do
112
+ option :mandatory, :required => true
113
+ end
114
+ end
115
+
116
+ lambda {
117
+ Harpo()
118
+ }.should raise_error(AppKernel::ValidationError)
119
+ end
120
+
121
+ it "allows validation of its arguments" do
122
+ @mod.module_eval do
123
+ function :Picky do
124
+ option :arg, :index => 1
125
+ validate do
126
+ @arg.check @arg == 5 && @arg != 6, "must be 5 and not be 6"
127
+ end
128
+ end
129
+ end
130
+
131
+ apply(@mod::Picky, 5).successful?.should be(true)
132
+ result = apply(@mod::Picky, 6)
133
+ result.successful?.should be(false)
134
+ result.errors[:arg].should == "must be 5 and not be 6"
135
+
136
+ result = apply(@mod::Picky, 7)
137
+ result.successful?.should be(false)
138
+ result.errors[:arg].should == "must be 5 and not be 6"
139
+ end
140
+ end
141
+
142
+
143
+ # module Awacs::Ssid
144
+ # include AppKernel::Function
145
+ #
146
+ # function :GetErrorCountBySource do
147
+ # option :solr, :nil => false
148
+ # option :source, :nil => false, :empty => false
149
+ #
150
+ # item = Struct.new(:source, :error_count)
151
+ # execute do
152
+ # @solr.query("sys_error_marker:(\"SSID-AUGMENTATION-ERROR\")",
153
+ # :filter_queries => ["PublicationTitle_t:[* TO *]"],
154
+ # :rows => 0,
155
+ # :facets => {:fields => "sys_source_id", :mincount => 1, :limit => 1000, :sort => "count"}
156
+ # ).data['facet_counts']['facet_fields']['sys_source_id'].enum_for(:each_slice, 2).map do |slice|
157
+ # item.new(*slice)
158
+ # end
159
+ # end
160
+ # end
161
+ #
162
+ # function :GetErrorCountByPublicationTitle do
163
+ # option :solr, :nil => false
164
+ # option :source, :nil => false, :empty => false
165
+ # option :title, :nil => false, :empty => false
166
+ #
167
+ # item = Struct.new(:title, :error_count)
168
+ #
169
+ # execute do
170
+ # @solr.query(%Q{sys_error_marker:("SSID-AUGMENT-FAILED")},
171
+ # :filter_queries => %Q{sys_source_id:("#{@source}")},
172
+ # :facets => {:fields => ['PublicationTitle_sfacet'], :mincount => 1, :limit => 1000, :sort => :count}
173
+ # ).data['facet_counts']['facet_fields']['PublicationTitle_sfacet'].enum_for(:each_slice, 2).map do |slice|
174
+ # item.new(*slice)
175
+ # end
176
+ # end
177
+ # end
178
+ #
179
+ #
180
+ # executeable :AddMapping do
181
+ # option :type, :nil => false, :type => SsidMatchType, :lookup => proc {|s| SsidMatchType.find_by_name s}
182
+ # option :value, :nil => false
183
+ # option :ssid, :nil => false
184
+ #
185
+ # execute do
186
+ # SsidMapping.create :match_rule => FindOrCreateRule(:type => @type, :value => @value), :ssid => @ssid
187
+ # end
188
+ # end
189
+ #
190
+ # function :DeleteMapping do
191
+ # option :mapping, :index => 1, :type => SsidMapping, :lookup => proc {|s| SsidMapping.find(s)}
192
+ #
193
+ # execute do
194
+ # @mapping.delete!
195
+ # end
196
+ # end
197
+
198
+ # function :SaveMappings do
199
+ # option :adds, :default => [], :massage => proc {|o| [o].flatten}
200
+ # option :deletes, :default => [], :massage => proc {|o| [o].flatten}
201
+ # end
202
+ #
203
+ # end
204
+ #
205
+ # #later on....
206
+ # include Awacs::Ssid
207
+ # GetErrorCountBySource :source => "proquest"
208
+ # GetErrorCountByPublicationTitle, :source => "proquest", :title => "Journal of Water Law"
209
+ # AddMapping :rule => {:match_type => 'ISSN', :match_value => '001287'}, :ssid => '123459'
210
+ # AddMapping :rule => 89, :ssid => 1234569
211
+ #
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe AppKernel::Validation do
4
+
5
+
6
+ it "can do assertions which are associated with a field" do
7
+ validate({:foo => 'bar'}) do
8
+ @foo.check(!@foo.nil?, "'foo' cannot be nil")
9
+ end.should be_empty
10
+
11
+ validate({:foo => nil}) do
12
+ @foo.check(!@foo.nil?, "cannot be nil.")
13
+ end[:foo].should == "cannot be nil."
14
+ end
15
+
16
+ it "returns a positive result if there is no validation body passed" do
17
+ validate().should be_empty
18
+ end
19
+
20
+
21
+ it "can validate fixnum fields fixnums" do
22
+ validate({:num => 5}) do
23
+ @num.check(@num < 5, "too big number!")
24
+ end[:num].should == "too big number!"
25
+ end
26
+
27
+ def validate(vars = {}, &block)
28
+ v = AppKernel::Validation::Validator.new(&block)
29
+ v.validate vars
30
+ end
31
+
32
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'appkernel'
data/tasks/rspec.rake ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appkernel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Charles Lowell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-29 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.4.1
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
35
+ description: |-
36
+ AppKernel is a microframework for capturing your application in terms of minute, self-validating functions.
37
+ Once defined, these functions can be used in rails, cocoa, an sms gateway, or wherever you want to take them.
38
+ email:
39
+ - cowboyd@thefrontside.net
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files:
45
+ - History.txt
46
+ - Manifest.txt
47
+ - README.rdoc
48
+ files:
49
+ - History.txt
50
+ - Manifest.txt
51
+ - README.rdoc
52
+ - Rakefile
53
+ - lib/appkernel.rb
54
+ - lib/appkernel/function.rb
55
+ - lib/appkernel/validation.rb
56
+ - script/console
57
+ - script/destroy
58
+ - script/generate
59
+ - spec/appkernel/function_spec.rb
60
+ - spec/appkernel/validation_spec.rb
61
+ - spec/spec.opts
62
+ - spec/spec_helper.rb
63
+ - tasks/rspec.rake
64
+ has_rdoc: true
65
+ homepage: http://github.com/cowboyd/appkernel
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options:
70
+ - --main
71
+ - README.rdoc
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ version:
86
+ requirements: []
87
+
88
+ rubyforge_project: appkernel
89
+ rubygems_version: 1.3.4
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: AppKernel is a microframework for capturing your application in terms of minute, self-validating functions
93
+ test_files: []
94
+