damsel 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ## v0.1.0:
4
+ * add changelog tasks
5
+ * smarter detection of whether something was passed to the method
6
+ * fixes for volume support
7
+ * refactor data to to_hash
8
+ * use define_method instead of method_missing. change attribute tracking to classes, instead of hashes
9
+ * Damsel::Base and Damsel::Data DSL's working
10
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in damsel.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Shawn Catanzarite
2
+
3
+ MIT License
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
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Damsel
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'damsel'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install damsel
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ def changelog(last=nil, single=false)
4
+ command="git --no-pager log --format='%an::::%h::::%s'"
5
+
6
+ list = `git tag`
7
+
8
+ puts "# Changelog"
9
+ puts
10
+
11
+ ordered = list.lines.sort_by {|e| (a,b,c) = e.gsub(/^v/,"").split("."); "%3d%3d%3d" % [a, b, c]}
12
+
13
+ ordered.reject{|e| (a,b,c,d) = e.split("."); !d.nil?}.reverse_each do |t|
14
+ tag = t.chomp
15
+
16
+ if last
17
+ check = { }
18
+ out = []
19
+ log = `#{command} #{last}...#{tag}`
20
+ log.lines.each do |line|
21
+ (who, hash, msg) = line.split('::::')
22
+ unless check[msg]
23
+ unless msg =~ /^Merge branch/ || msg =~ /CHANGELOG/ || msg =~ /^(v|version|changes for|preparing|ready for release|ready to release|bump version)*\s*(v|version)*\d+\.\d+\.\d+/
24
+ msg.gsub(" *", "\n*").gsub(/^\*\*/, " *").lines.each do |l|
25
+ line = l =~ /^(\s+)*\*/ ? l : "* #{l}"
26
+ out << line
27
+ end
28
+ check[msg] = hash
29
+ end
30
+ end
31
+ end
32
+ puts "## #{last}:"
33
+ out.each { |e| puts e }
34
+ #puts log
35
+ puts
36
+ end
37
+
38
+ last = tag
39
+ exit if single
40
+ end
41
+ end
42
+
43
+ desc "generate changelog output"
44
+ task :changelog do
45
+ changelog
46
+ end
47
+
48
+ desc "show current changes (changelog output from HEAD to most recent tag)"
49
+ task :current do
50
+ changelog("HEAD",true)
51
+ end
data/damsel.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'damsel/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "damsel"
8
+ spec.version = Damsel::Version::STRING
9
+ spec.authors = ["Shawn Catanzarite"]
10
+ spec.email = ["me@shawncatz.com"]
11
+ spec.description = %q{simplied creation of DSL's}
12
+ spec.summary = %q{simplied creation of DSL's}
13
+ spec.homepage = "https://github.com/shawncatz/damsel"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
data/lib/damsel.rb ADDED
@@ -0,0 +1 @@
1
+ require "damsel/version"
@@ -0,0 +1,47 @@
1
+ module Damsel
2
+ class Attribute
3
+ attr_reader :name, :type, :default, :klass, :block
4
+
5
+ def initialize(name, options={})
6
+ o = {
7
+ child: false,
8
+ default: nil,
9
+ type: String,
10
+ klass: nil,
11
+ many: false,
12
+ named: false,
13
+ block: nil,
14
+ }.merge(options)
15
+ @name = name.to_sym
16
+ @child = o[:child]
17
+ @default = o[:default]
18
+ @named = o[:named]
19
+ @many = o[:many]
20
+ @klass = o[:klass]
21
+ @type = o[:type]
22
+ @block = o[:block]
23
+
24
+ if type == Array
25
+ @default = []
26
+ elsif type == :child
27
+ if many?
28
+ @default = []
29
+ else
30
+ @default = {}
31
+ end
32
+ end
33
+ end
34
+
35
+ def child?
36
+ @child
37
+ end
38
+
39
+ def many?
40
+ @many
41
+ end
42
+
43
+ def named?
44
+ @named
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ module Damsel
2
+ class AttributeSet
3
+ attr_reader :attrs
4
+
5
+ def initialize
6
+ @attrs = {}
7
+ end
8
+
9
+ def <<(attribute)
10
+ @attrs[attribute.name] = attribute
11
+ end
12
+
13
+ def [](name)
14
+ return @attrs[name] if @attrs[name]
15
+ singular = name.to_s.singularize.to_sym
16
+ return @attrs[singular] if @attrs[singular]
17
+ plural = name.to_s.pluralize.to_sym
18
+ return @attrs[plural] if @attrs[plural]
19
+ raise "unknown attribute: #{name} (#{singular} #{plural})"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,168 @@
1
+ require "damsel/attribute_set"
2
+ require "damsel/attribute"
3
+
4
+ module Damsel
5
+ class Base
6
+ def initialize(name)
7
+ @name = name
8
+ @data = {}
9
+ @names = []
10
+ end
11
+
12
+ def attrs
13
+ self.class.attrs
14
+ end
15
+
16
+ def [](name)
17
+ @data[name.to_sym]
18
+ end
19
+
20
+ def validate!
21
+ if @data[:block]
22
+ #block.call(self)
23
+ end
24
+ rescue => e
25
+ raise "validation failed: #{e.message} at #{e.backtrace.first}"
26
+ end
27
+
28
+ def data
29
+ raise "not used"
30
+ end
31
+
32
+ def to_hash
33
+ recursive_hash(@data)
34
+ end
35
+
36
+ private
37
+
38
+ def recursive_hash(value)
39
+ if value.is_a?(Damsel::Base)
40
+ #puts "BASE:#{value.inspect}"
41
+ value.to_hash
42
+ elsif value.is_a?(Hash)
43
+ #puts "HASH:#{value.inspect}"
44
+ out = {}
45
+ value.each do |k, v|
46
+ out[k] = recursive_hash(v)
47
+ end
48
+ out
49
+ elsif value.is_a?(Array)
50
+ #puts "ARRAY:#{value.inspect}"
51
+ out = []
52
+ value.each do |e|
53
+ #puts "ARRAY:#{e}:"
54
+ out << recursive_hash(e)
55
+ end
56
+ out
57
+ else
58
+ value
59
+ end
60
+ end
61
+
62
+ class << self
63
+ @attrs = {}
64
+ attr_accessor :attrs
65
+ attr_accessor :search_module
66
+
67
+ def attribute(name, options={}, &block)
68
+ name = name.to_sym
69
+ options = {
70
+ value: nil,
71
+ type: :string,
72
+ klass: nil
73
+ }.merge(options)
74
+ #puts "ATTR: #{name} - #{o.inspect}"
75
+
76
+ name = name.to_s.singularize.to_sym if options[:type] == Array
77
+ options[:block] = block if block_given?
78
+
79
+ @attrs ||= Damsel::AttributeSet.new
80
+ @attrs << Damsel::Attribute.new(name, options)
81
+
82
+ define_method name, ->(value=nil, &b) do
83
+ attr = attrs[name]
84
+ return @data[name] if value.nil? && b.nil?
85
+ @data[name] ||= attr.default ? attr.default.dup : nil
86
+
87
+ if attr.block
88
+ valid = attr.block.call(value)
89
+ raise "validation for #{name} failed: #{attr.block}" unless valid
90
+ end
91
+
92
+ if attr.type == Array
93
+ @data[name] << value
94
+ elsif attr.type == :child
95
+ k = attr.klass.constantize
96
+ obj = k.new(name)
97
+ obj.name value if value
98
+
99
+ if attr.many?
100
+ if attr.named?
101
+ value = value.to_sym
102
+ raise "setting more than one #{name}[#{value}]: previous: #{@data[name]}" if @names.include?("#{name}#{value}")
103
+ @names << "#{name}#{value}"
104
+ @data[name] << obj
105
+ else
106
+ @data[name] << obj
107
+ end
108
+ else
109
+ raise "setting more than one #{name}: previous: #{@data[name].inspect}" if @data[name].count > 0
110
+ @data[name] = obj
111
+ end
112
+
113
+ if obj.is_a?(Damsel::Data)
114
+ obj.instance_eval &b if b
115
+ elsif obj.is_a?(Damsel::Exec)
116
+ obj.save b
117
+ end
118
+ else
119
+ @data[name] = value
120
+ end
121
+ end
122
+ end
123
+
124
+ def has_one(name, options={})
125
+ o = {
126
+ klass: find_class(name),
127
+ type: :child,
128
+ many: false,
129
+ named: false,
130
+ value: nil
131
+ }.merge(options)
132
+ attribute(name, o)
133
+ end
134
+
135
+ def has_many(names, options={})
136
+ singular = names.to_s.singularize
137
+ o = {
138
+ klass: find_class(singular),
139
+ type: :child,
140
+ many: true,
141
+ named: false,
142
+ value: nil
143
+ }.merge(options)
144
+ attribute(singular, o)
145
+ end
146
+
147
+ def references(name, options={})
148
+ attribute(name, options)
149
+ end
150
+
151
+ def find_module(name)
152
+ @module ||= begin
153
+ list = name.split('::')
154
+ list.pop
155
+ list.join('::')
156
+ end
157
+ end
158
+
159
+ def find_class(name)
160
+ c = "#{find_module(self.name)}::#{name.capitalize}"
161
+ #puts "FINDCLASS: #{name} #{c}"
162
+ c
163
+ rescue => e
164
+ raise "could not find class: #{c}: #{e.message} at #{e.backtrace.first}"
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,7 @@
1
+ require "damsel/base"
2
+
3
+ module Damsel
4
+ class Data < Base
5
+
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ module Damsel
2
+ class Exec < Base
3
+ def intialize
4
+ @id = false
5
+ end
6
+
7
+ def save(block)
8
+ @id = block.object_id
9
+ Damsel::Exec.save(@id, &block)
10
+ end
11
+
12
+ def to_hash
13
+ {
14
+ id: @id,
15
+ }
16
+ end
17
+
18
+ class << self
19
+ def save(id, &block)
20
+ @blocks ||= {}
21
+ @blocks[id] = block
22
+ end
23
+
24
+ def get(id)
25
+ @blocks[id]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ unless defined?(Damsel::Version)
2
+ module Damsel
3
+ module Version
4
+ MAJOR = 0
5
+ MINOR = 1
6
+ TINY = 0
7
+ TAG = nil
8
+ STRING = [MAJOR, MINOR, TINY, TAG].compact.join(".")
9
+ end
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: damsel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Shawn Catanzarite
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: simplied creation of DSL's
47
+ email:
48
+ - me@shawncatz.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - CHANGELOG.md
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - damsel.gemspec
60
+ - lib/damsel.rb
61
+ - lib/damsel/attribute.rb
62
+ - lib/damsel/attribute_set.rb
63
+ - lib/damsel/base.rb
64
+ - lib/damsel/data.rb
65
+ - lib/damsel/exec.rb
66
+ - lib/damsel/version.rb
67
+ homepage: https://github.com/shawncatz/damsel
68
+ licenses:
69
+ - MIT
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ segments:
81
+ - 0
82
+ hash: 3394562117424329318
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ segments:
90
+ - 0
91
+ hash: 3394562117424329318
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 1.8.25
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: simplied creation of DSL's
98
+ test_files: []