rid 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.gitignore +21 -0
  2. data/.gitmodules +3 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +93 -0
  5. data/Rakefile +72 -0
  6. data/bin/rid +7 -0
  7. data/lib/rid.rb +43 -0
  8. data/lib/rid/actions/base.rb +15 -0
  9. data/lib/rid/actions/pull.rb +28 -0
  10. data/lib/rid/actions/push.rb +53 -0
  11. data/lib/rid/actions/routes.rb +41 -0
  12. data/lib/rid/attachments.rb +59 -0
  13. data/lib/rid/commands.rb +41 -0
  14. data/lib/rid/commands/destroy.rb +9 -0
  15. data/lib/rid/commands/generate.rb +9 -0
  16. data/lib/rid/commands/pull.rb +4 -0
  17. data/lib/rid/commands/push.rb +4 -0
  18. data/lib/rid/commands/routes.rb +4 -0
  19. data/lib/rid/design_document.rb +179 -0
  20. data/lib/rid/generators.rb +63 -0
  21. data/lib/rid/generators/application/USAGE +10 -0
  22. data/lib/rid/generators/application/application_generator.rb +51 -0
  23. data/lib/rid/generators/application/templates/README +1 -0
  24. data/lib/rid/generators/application/templates/_attachments/index.html +11 -0
  25. data/lib/rid/generators/application/templates/_attachments/stylesheets/application.css +25 -0
  26. data/lib/rid/generators/application/templates/_id +1 -0
  27. data/lib/rid/generators/application/templates/gitignore +0 -0
  28. data/lib/rid/generators/application/templates/lib/mustache.js +305 -0
  29. data/lib/rid/generators/application/templates/ridrc +1 -0
  30. data/lib/rid/generators/application/templates/validate_doc_update.js +3 -0
  31. data/lib/rid/generators/base.rb +66 -0
  32. data/lib/rid/generators/list/USAGE +8 -0
  33. data/lib/rid/generators/list/list_generator.rb +9 -0
  34. data/lib/rid/generators/list/templates/list.js +29 -0
  35. data/lib/rid/generators/named_base.rb +22 -0
  36. data/lib/rid/generators/scaffold/USAGE +10 -0
  37. data/lib/rid/generators/scaffold/scaffold_generator.rb +28 -0
  38. data/lib/rid/generators/show/USAGE +8 -0
  39. data/lib/rid/generators/show/show_generator.rb +9 -0
  40. data/lib/rid/generators/show/templates/show.js +20 -0
  41. data/lib/rid/generators/validation/USAGE +9 -0
  42. data/lib/rid/generators/validation/templates/validate_doc_update.js +3 -0
  43. data/lib/rid/generators/validation/validation_generator.rb +34 -0
  44. data/lib/rid/generators/view/USAGE +8 -0
  45. data/lib/rid/generators/view/templates/map.js +5 -0
  46. data/lib/rid/generators/view/view_generator.rb +17 -0
  47. data/lib/rid/makros.rb +105 -0
  48. data/lib/rid/version.rb +3 -0
  49. data/rid.gemspec +113 -0
  50. data/spec/rid/design_document_spec.rb +329 -0
  51. data/spec/rid_spec.rb +7 -0
  52. data/spec/spec.opts +1 -0
  53. data/spec/spec_helper.rb +9 -0
  54. metadata +187 -0
@@ -0,0 +1 @@
1
+ database: "http://127.0.0.1:5984/<%= app_name %>"
@@ -0,0 +1,3 @@
1
+ function (newDoc, oldDoc, userCtx) {
2
+ // validation code goes here
3
+ }
@@ -0,0 +1,66 @@
1
+ require 'thor/group'
2
+ require 'active_support/inflector'
3
+
4
+ module Rid
5
+ module Generators
6
+ class Error < Thor::Error
7
+ end
8
+
9
+ class Base < Thor::Group
10
+ include Thor::Actions
11
+
12
+ add_runtime_options!
13
+
14
+ class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
15
+ :desc => "Skip Git ignores and keeps"
16
+
17
+ # Automatically sets the source root based on the class name.
18
+ #
19
+ def self.source_root
20
+ @_rid_source_root ||= begin
21
+ if generator_name
22
+ File.expand_path(File.join("../generators", generator_name, 'templates'), File.dirname(__FILE__))
23
+ end
24
+ end
25
+ end
26
+
27
+ # Tries to get the description from a USAGE file one folder above the source
28
+ # root otherwise uses a default description.
29
+ #
30
+ def self.desc(description=nil)
31
+ return super if description
32
+ usage = File.expand_path(File.join(source_root, "..", "USAGE"))
33
+
34
+ @desc ||= if File.exist?(usage)
35
+ File.read(usage)
36
+ else
37
+ "Description:\n Create files for #{generator_name} generator."
38
+ end
39
+ end
40
+
41
+ def self.info
42
+ desc.split(/\n+/)[1].strip
43
+ end
44
+
45
+ protected
46
+
47
+ # Use Rid default banner.
48
+ #
49
+ def self.banner
50
+ "rid generate|destroy #{generator_name} #{self.arguments.map{ |a| a.usage }.join(' ')} [options]"
51
+ end
52
+
53
+ # Removes the namespaces and get the generator name. For example,
54
+ # Rid::Generators::MetalGenerator will return "metal" as generator name.
55
+ #
56
+ def self.generator_name
57
+ @generator_name ||= begin
58
+ if generator = name.to_s.split('::').last
59
+ generator.sub!(/Generator$/, '')
60
+ generator.underscore
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ The 'show' generator creates a scaffold show function
3
+ for the name you specify
4
+
5
+ Example:
6
+ rid generate show post
7
+
8
+ This generates a skeletal post show function
@@ -0,0 +1,9 @@
1
+ require 'rid/generators/named_base'
2
+
3
+ module Rid::Generators
4
+ class ListGenerator < NamedBase
5
+ def create_list_function
6
+ template "list.js", "lists/#{pluralized_model_name}.js"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ function(head, req) {
2
+ provides("html", function() {
3
+ var header = '<html><head><link rel="stylesheet" href="../../stylesheets/application.css" type="text/css" media="screen" charset="utf-8"></head><body><h1>Listing <%= pluralized_model_name.humanize %></h1>';
4
+
5
+ header += '<p><a href="../../_show/<%= model_name %>/">New <%= model_name.humanize %></a></p>';
6
+
7
+ header += '<table><tr>';
8
+ <% attributes.each do |attribute| -%>
9
+ header += '<th><%= attribute.humanize %></th>';
10
+ <% end -%>
11
+ header += '<th></th>';
12
+ header += '</tr>';
13
+ send(header);
14
+
15
+ var row;
16
+ while (row = getRow()) {
17
+ var body = '<tr>';
18
+ <% attributes.each do |attribute| -%>
19
+ body += '<td>' + row.value['<%= attribute %>'] + '</td>';
20
+ <% end -%>
21
+ body += '<td><a href="../../_show/<%= model_name %>/' + row.id + '" alt="Show <%= model_name.humanize %>">Show</a></td>';
22
+ body += '</tr>';
23
+ send(body);
24
+ }
25
+
26
+ var tail = '</table></body></html>';
27
+ return tail;
28
+ });
29
+ }
@@ -0,0 +1,22 @@
1
+ require 'thor/group'
2
+ require 'active_support/inflector'
3
+
4
+ module Rid
5
+ module Generators
6
+ class NamedBase < Base
7
+ argument :name, :type => :string
8
+ argument :attributes, :type => :array, :default => []
9
+
10
+ protected
11
+
12
+ # force underscored and singularized model name
13
+ def model_name
14
+ @model_name ||= name.underscore.singularize
15
+ end
16
+
17
+ def pluralized_model_name
18
+ model_name.pluralize
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ Description:
2
+ The 'scaffold' generator creates a scaffold skelet
3
+ with a default show function, list function
4
+ of the name and attributes you specify
5
+
6
+ Example:
7
+ rid generate scaffold post title body
8
+
9
+ This generates a skeletal model post with a posts list view,
10
+ post show function and validation.
@@ -0,0 +1,28 @@
1
+ require 'rid/generators/named_base'
2
+
3
+ module Rid::Generators
4
+ class ScaffoldGenerator < NamedBase
5
+ def create_view_function
6
+ Rid::Generators.invoke :view, *invokation_options
7
+ end
8
+
9
+ def inject_validations
10
+ Rid::Generators.invoke :validation, *invokation_options
11
+ end
12
+
13
+ def create_list_function
14
+ Rid::Generators.invoke :list, *invokation_options
15
+ end
16
+
17
+ def create_show_function
18
+ Rid::Generators.invoke :show, *invokation_options
19
+ end
20
+
21
+ protected
22
+
23
+ # TODO: add default options, like --help, --force etc
24
+ def invokation_options
25
+ [[name] + attributes, { :behavior => behavior }]
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ The 'show' generator creates a scaffold show function
3
+ for the name you specify
4
+
5
+ Example:
6
+ rid generate show post
7
+
8
+ This generates a skeletal post show function
@@ -0,0 +1,9 @@
1
+ require 'rid/generators/named_base'
2
+
3
+ module Rid::Generators
4
+ class ShowGenerator < NamedBase
5
+ def create_show_function
6
+ template "show.js", "shows/#{model_name}.js"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ function(doc, req) {
2
+ var head = '<html><head><link rel="stylesheet" href="../../stylesheets/application.css" type="text/css" media="screen" charset="utf-8"></head><body>';
3
+ var body = '';
4
+ var tail = '</body></html>';
5
+ if(doc) {
6
+ body += '<p><a href="../../_list/<%= pluralized_model_name %>/<%= pluralized_model_name %>">List <%= pluralized_model_name.humanize %></a></p>';
7
+ <% attributes.each do |attribute| -%>
8
+ if(doc['<%= attribute %>']) {
9
+ body += '<p><strong><%= attribute.humanize %></strong>: ' + doc['<%= attribute %>'] + '</p>';
10
+ }
11
+ <% end -%>
12
+ return head + '<h1>Showing <%= model_name.humanize %></h1>' + body + tail;
13
+ } else {
14
+ <% attributes.each do |attribute| -%>
15
+ body += '<p><label><%= attribute.humanize %></label>: <input type="text" name="<%= model_name %>[<%= attribute %>]" id="<%= model_name %>_<%= attribute %>" /></p>';
16
+ <% end -%>
17
+ body += '<p><input type="submit" /> <a href="../../_list/<%= pluralized_model_name %>/<%= pluralized_model_name %>">Cancel</a></p>';
18
+ return head + '<h1>New <%= model_name.humanize %></h1>' + body + tail;
19
+ }
20
+ }
@@ -0,0 +1,9 @@
1
+ Description:
2
+ The 'validation' generator creates a validation function
3
+ for the model name and attributes you specify
4
+
5
+ Example:
6
+ rid generate validation post title body
7
+
8
+ This generates a skeletal model validation for post
9
+ with validations of presence for title and body
@@ -0,0 +1,3 @@
1
+ function (newDoc, oldDoc, userCtx) {
2
+ // your validation code goes here
3
+ }
@@ -0,0 +1,34 @@
1
+ require 'rid/generators/named_base'
2
+
3
+ module Rid::Generators
4
+ class ValidationGenerator < NamedBase
5
+ def create_validate_doc_update
6
+ return if File.exists?(File.join(destination_root, "validate_doc_update.js"))
7
+ template "validate_doc_update.js"
8
+ end
9
+
10
+ def inject_validations
11
+ inject_into_file "validate_doc_update.js", model_validations, :after => "function (newDoc, oldDoc, userCtx) {\n"
12
+ end
13
+
14
+ protected
15
+
16
+ def model_validations
17
+ str = <<-STR
18
+ if(newDoc.type == '#{model_name}') {
19
+ // validations for #{model_name}
20
+ STR
21
+
22
+ attributes.each do |attribute|
23
+ str << <<-STR
24
+ if (typeof(newDoc['#{attribute}']) === 'undefined') {
25
+ throw({ forbidden: '#{attribute} is required' });
26
+ }
27
+ STR
28
+ end
29
+
30
+ str << " }\n"
31
+ str
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ The 'view' generator creates a scaffold view function
3
+ for the name you specify
4
+
5
+ Example:
6
+ rid generate view post
7
+
8
+ This generates a skeletal posts list function
@@ -0,0 +1,5 @@
1
+ function(doc) {
2
+ if(doc.type && doc.type == '<%= model_name %>') {
3
+ emit(doc._id, <%= mydoc %>);
4
+ }
5
+ }
@@ -0,0 +1,17 @@
1
+ require 'rid/generators/named_base'
2
+
3
+ module Rid::Generators
4
+ class ViewGenerator < NamedBase
5
+ def create_view_function
6
+ path = "views/#{pluralized_model_name}"
7
+ empty_directory path
8
+ template "map.js", "#{path}/map.js"
9
+ end
10
+
11
+ protected
12
+
13
+ def mydoc
14
+ "{ %s }" % attributes.map { |a| '"%s": doc["%s"]' % [a,a] }.join(", ")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,105 @@
1
+ module Rid
2
+ module Makros
3
+ def inject_makros!
4
+ self.hash = inject_code_makro(hash)
5
+ self.hash = inject_json_makro(hash)
6
+ end
7
+
8
+ def reject_makros!
9
+ return if libs.empty?
10
+ # Attention: replace json makros first!
11
+ self.hash = reject_json_makro(hash, libs)
12
+ self.hash = reject_code_makro(hash, libs)
13
+ end
14
+
15
+ def libs
16
+ @libs ||= flatten_libs
17
+ end
18
+
19
+ def flatten_libs(libs = hash["lib"] || {}, key = nil)
20
+ result = {}
21
+ libs.each do |name, value|
22
+ new_key = key ? File.join(key, name) : name
23
+ if value.is_a?(Hash)
24
+ result.update flatten_libs(value, new_key)
25
+ else
26
+ result.update new_key => value
27
+ end
28
+ end
29
+ result
30
+ end
31
+
32
+
33
+ def inject_code_makro(doc)
34
+ doc.each do |key, value|
35
+ doc[key] = if value.is_a?(String)
36
+ value.gsub(/\/\/\s*!code.*$/) do |match|
37
+ filename = match.sub(/^.*!code\s*(\S+).*$/, '\1')
38
+ libs[filename]
39
+ end
40
+ elsif value.is_a?(Hash)
41
+ inject_code_makro(value)
42
+ else
43
+ value
44
+ end
45
+ end
46
+
47
+ doc
48
+ end
49
+
50
+ def inject_json_makro(doc)
51
+ doc.each do |key, value|
52
+ doc[key] = if value.is_a?(String)
53
+ value.gsub(/\/\/\s*!json.*$/) do |match|
54
+ filename = match.sub(/^.*!json\s*(\S+).*$/, '\1')
55
+ 'var %s = %s;' % [filename.sub(/\..*$/, ''), libs[filename].to_json]
56
+ end
57
+ elsif value.is_a?(Hash)
58
+ inject_json_makro(value)
59
+ else
60
+ value
61
+ end
62
+ end
63
+
64
+ doc
65
+ end
66
+
67
+
68
+ def reject_code_makro(doc, libs)
69
+ doc = doc.dup
70
+ doc.each do |key, value|
71
+ next if key == "lib"
72
+
73
+ if value.is_a?(String)
74
+ libs.each do |name, content|
75
+ # only try substituting strings
76
+ next unless content.is_a?(String)
77
+ next unless value.include?(content)
78
+ doc[key] = value.gsub(content, "// !code #{name}")
79
+ end
80
+ elsif value.is_a?(Hash)
81
+ doc[key] = reject_code_makro(value, libs)
82
+ end
83
+ end
84
+ doc
85
+ end
86
+
87
+ def reject_json_makro(doc, libs)
88
+ doc.each do |key, value|
89
+ next if key == "lib"
90
+ if value.is_a?(String)
91
+ libs.each do |name, content|
92
+ # only try substituting strings
93
+ next unless content.is_a?(String)
94
+ json = 'var %s = %s;' % [name.sub(/\..*$/, ''), content.to_json]
95
+ next unless value.include?(json)
96
+ doc[key] = value.gsub(json, "// !json #{name}")
97
+ end
98
+ elsif value.is_a?(Hash)
99
+ doc[key] = reject_json_makro(value, libs)
100
+ end
101
+ end
102
+ doc
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,3 @@
1
+ module Rid
2
+ VERSION = "0.3.0"
3
+ end
@@ -0,0 +1,113 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rid}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Johannes J. Schmidt"]
12
+ s.date = %q{2010-03-11}
13
+ s.default_executable = %q{rid}
14
+ s.description = %q{With Couch you can easy build a standalone CouchDB application. Couch aims to bring some of the Rails beauty to CouchDB. Currently Couch supports Rails style Generators you will love, using the same awesome Thor library used in Rails3.}
15
+ s.email = %q{schmidt@netzmerk.com}
16
+ s.executables = ["rid"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ ".gitmodules",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "bin/rid",
28
+ "lib/rid.rb",
29
+ "lib/rid/actions/base.rb",
30
+ "lib/rid/actions/pull.rb",
31
+ "lib/rid/actions/push.rb",
32
+ "lib/rid/actions/routes.rb",
33
+ "lib/rid/attachments.rb",
34
+ "lib/rid/commands.rb",
35
+ "lib/rid/commands/destroy.rb",
36
+ "lib/rid/commands/generate.rb",
37
+ "lib/rid/commands/pull.rb",
38
+ "lib/rid/commands/push.rb",
39
+ "lib/rid/commands/routes.rb",
40
+ "lib/rid/design_document.rb",
41
+ "lib/rid/generators.rb",
42
+ "lib/rid/generators/application/USAGE",
43
+ "lib/rid/generators/application/application_generator.rb",
44
+ "lib/rid/generators/application/templates/README",
45
+ "lib/rid/generators/application/templates/_attachments/index.html",
46
+ "lib/rid/generators/application/templates/_attachments/stylesheets/application.css",
47
+ "lib/rid/generators/application/templates/_id",
48
+ "lib/rid/generators/application/templates/gitignore",
49
+ "lib/rid/generators/application/templates/lib/mustache.js",
50
+ "lib/rid/generators/application/templates/ridrc",
51
+ "lib/rid/generators/application/templates/validate_doc_update.js",
52
+ "lib/rid/generators/base.rb",
53
+ "lib/rid/generators/list/USAGE",
54
+ "lib/rid/generators/list/list_generator.rb",
55
+ "lib/rid/generators/list/templates/list.js",
56
+ "lib/rid/generators/named_base.rb",
57
+ "lib/rid/generators/scaffold/USAGE",
58
+ "lib/rid/generators/scaffold/scaffold_generator.rb",
59
+ "lib/rid/generators/show/USAGE",
60
+ "lib/rid/generators/show/show_generator.rb",
61
+ "lib/rid/generators/show/templates/show.js",
62
+ "lib/rid/generators/validation/USAGE",
63
+ "lib/rid/generators/validation/templates/validate_doc_update.js",
64
+ "lib/rid/generators/validation/validation_generator.rb",
65
+ "lib/rid/generators/view/USAGE",
66
+ "lib/rid/generators/view/templates/map.js",
67
+ "lib/rid/generators/view/view_generator.rb",
68
+ "lib/rid/makros.rb",
69
+ "lib/rid/version.rb",
70
+ "rid.gemspec",
71
+ "spec/rid/design_document_spec.rb",
72
+ "spec/rid_spec.rb",
73
+ "spec/spec.opts",
74
+ "spec/spec_helper.rb"
75
+ ]
76
+ s.homepage = %q{http://github.com/jo/rid}
77
+ s.rdoc_options = ["--charset=UTF-8"]
78
+ s.require_paths = ["lib"]
79
+ s.rubyforge_project = %q{rid}
80
+ s.rubygems_version = %q{1.3.6}
81
+ s.summary = %q{Standalone Couchdb Application Development Suite}
82
+ s.test_files = [
83
+ "spec/spec_helper.rb",
84
+ "spec/rid_spec.rb",
85
+ "spec/rid/design_document_spec.rb"
86
+ ]
87
+
88
+ if s.respond_to? :specification_version then
89
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
90
+ s.specification_version = 3
91
+
92
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
93
+ s.add_runtime_dependency(%q<thor>, [">= 0.13.4"])
94
+ s.add_runtime_dependency(%q<rest-client>, [">= 1.4.1"])
95
+ s.add_runtime_dependency(%q<json_pure>, [">= 1.2.2"])
96
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0.beta"])
97
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
98
+ else
99
+ s.add_dependency(%q<thor>, [">= 0.13.4"])
100
+ s.add_dependency(%q<rest-client>, [">= 1.4.1"])
101
+ s.add_dependency(%q<json_pure>, [">= 1.2.2"])
102
+ s.add_dependency(%q<activesupport>, [">= 3.0.0.beta"])
103
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
104
+ end
105
+ else
106
+ s.add_dependency(%q<thor>, [">= 0.13.4"])
107
+ s.add_dependency(%q<rest-client>, [">= 1.4.1"])
108
+ s.add_dependency(%q<json_pure>, [">= 1.2.2"])
109
+ s.add_dependency(%q<activesupport>, [">= 3.0.0.beta"])
110
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
111
+ end
112
+ end
113
+