rid 0.5.2 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/LICENSE +1 -1
  2. data/README +14 -0
  3. data/Rakefile +18 -33
  4. data/VERSION +1 -0
  5. data/bin/rid +3 -6
  6. data/lib/rid/app.rb +49 -0
  7. data/lib/rid/attachments.rb +6 -2
  8. data/lib/rid/commands.rb +61 -39
  9. data/lib/rid/core_ext/hash.rb +1 -1
  10. data/lib/rid/database.rb +69 -0
  11. data/lib/rid/document.rb +99 -0
  12. data/lib/rid.rb +14 -41
  13. data/rid.gemspec +49 -78
  14. data/spec/mock_app/_database +1 -0
  15. data/spec/rid/app_spec.rb +59 -0
  16. data/spec/rid/attachments_spec.rb +2 -2
  17. data/spec/rid/commands_spec.rb +14 -0
  18. data/spec/rid/database_spec.rb +25 -0
  19. data/spec/rid/document_spec.rb +36 -0
  20. data/spec/spec_helper.rb +6 -0
  21. metadata +127 -86
  22. data/.gitmodules +0 -3
  23. data/README.rdoc +0 -92
  24. data/lib/rid/actions/base.rb +0 -15
  25. data/lib/rid/actions/pull.rb +0 -28
  26. data/lib/rid/actions/push.rb +0 -53
  27. data/lib/rid/actions/routes.rb +0 -44
  28. data/lib/rid/commands/destroy.rb +0 -9
  29. data/lib/rid/commands/generate.rb +0 -9
  30. data/lib/rid/commands/pull.rb +0 -4
  31. data/lib/rid/commands/push.rb +0 -4
  32. data/lib/rid/commands/routes.rb +0 -4
  33. data/lib/rid/design_document.rb +0 -149
  34. data/lib/rid/generators/application/USAGE +0 -10
  35. data/lib/rid/generators/application/application_generator.rb +0 -56
  36. data/lib/rid/generators/application/templates/README +0 -1
  37. data/lib/rid/generators/application/templates/_attachments/index.html +0 -11
  38. data/lib/rid/generators/application/templates/_attachments/stylesheets/application.css +0 -25
  39. data/lib/rid/generators/application/templates/_id +0 -1
  40. data/lib/rid/generators/application/templates/gitignore +0 -0
  41. data/lib/rid/generators/application/templates/lib/mustache.js +0 -305
  42. data/lib/rid/generators/application/templates/lib/path.js +0 -5
  43. data/lib/rid/generators/application/templates/lib/templates/layout.mustache +0 -14
  44. data/lib/rid/generators/application/templates/ridrc +0 -1
  45. data/lib/rid/generators/application/templates/validate_doc_update.js +0 -3
  46. data/lib/rid/generators/base.rb +0 -66
  47. data/lib/rid/generators/list/USAGE +0 -8
  48. data/lib/rid/generators/list/list_generator.rb +0 -10
  49. data/lib/rid/generators/list/templates/index.mustache +0 -23
  50. data/lib/rid/generators/list/templates/list.js +0 -34
  51. data/lib/rid/generators/named_base.rb +0 -22
  52. data/lib/rid/generators/scaffold/USAGE +0 -10
  53. data/lib/rid/generators/scaffold/scaffold_generator.rb +0 -32
  54. data/lib/rid/generators/show/USAGE +0 -8
  55. data/lib/rid/generators/show/show_generator.rb +0 -13
  56. data/lib/rid/generators/show/templates/delete.mustache +0 -20
  57. data/lib/rid/generators/show/templates/deleted.mustache +0 -3
  58. data/lib/rid/generators/show/templates/form.mustache +0 -22
  59. data/lib/rid/generators/show/templates/show.js +0 -48
  60. data/lib/rid/generators/show/templates/show.mustache +0 -13
  61. data/lib/rid/generators/update/USAGE +0 -8
  62. data/lib/rid/generators/update/templates/update.js +0 -48
  63. data/lib/rid/generators/update/update_generator.rb +0 -9
  64. data/lib/rid/generators/validation/USAGE +0 -9
  65. data/lib/rid/generators/validation/templates/validate_doc_update.js +0 -3
  66. data/lib/rid/generators/validation/validation_generator.rb +0 -34
  67. data/lib/rid/generators/view/USAGE +0 -8
  68. data/lib/rid/generators/view/templates/map.js +0 -5
  69. data/lib/rid/generators/view/view_generator.rb +0 -17
  70. data/lib/rid/generators.rb +0 -63
  71. data/lib/rid/makros.rb +0 -114
  72. data/lib/rid/version.rb +0 -3
  73. data/spec/rid/design_document_spec.rb +0 -220
  74. data/spec/rid/makros_spec.rb +0 -94
  75. data/spec/rid_spec.rb +0 -7
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Johannes J. Schmidt
1
+ Copyright (c) 2010 Johannes J. Schmidt
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README ADDED
@@ -0,0 +1,14 @@
1
+ = Rid
2
+
3
+ In the spirit of Ruby on Rails Rid tends on programmers happiness.
4
+
5
+ Rid eases the process of building standalone CouchDB applications
6
+ with tools for deployment, codegenerators and a javascript library.
7
+
8
+ This is the rid gem with the CouchDB model and command line
9
+ infrastructure.
10
+
11
+
12
+ == Copyright
13
+
14
+ Copyright (c) 2010 Johannes J. Schmidt. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,48 +1,31 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
- require File.join(File.dirname(__FILE__), 'lib', 'rid', 'version')
4
-
5
- namespace :vendor do
6
- desc "Update vendor"
7
- task :update do
8
- `git submodule update`
9
- end
10
-
11
- desc "vendor mustache"
12
- task :mustache do
13
- dir = File.expand_path('..', __FILE__)
14
- source = File.join(dir, 'vendor/mustache.js/mustache.js')
15
- target = File.join(dir, 'lib/rid/generators/application/templates/lib/')
16
- FileUtils.cp source, target
17
- end
18
- end
19
-
20
- desc "Vendor all"
21
- task :vendor => ["vendor:update", "vendor:mustache"]
22
-
23
3
 
24
4
  begin
25
5
  require 'jeweler'
26
6
  Jeweler::Tasks.new do |gem|
27
7
  gem.name = "rid"
28
- gem.version = Rid::VERSION
29
- gem.summary = %Q{Standalone Couchdb Application Development Suite}
30
- gem.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.}
8
+ gem.summary = %Q{Rest in development core.}
9
+ gem.description = %Q{Rid is a toolkit to relax in web development. Based on CouchDB you get a distributed, high scaling web application infrastructure with Rid. This is the Rid core.}
31
10
  gem.email = "schmidt@netzmerk.com"
32
- gem.homepage = "http://jo.github.com/rid/"
11
+ gem.homepage = "http://rid.github.com/rid"
33
12
  gem.authors = ["Johannes J. Schmidt"]
34
- gem.rubyforge_project = "rid"
35
- gem.add_dependency "thor", ">= 0.13.4"
36
- gem.add_dependency "rest-client", ">= 1.4.1"
37
- gem.add_dependency "json_pure", ">= 1.2.2"
38
- gem.add_dependency "activesupport", ">= 3.0.0.beta"
13
+
14
+ gem.add_dependency "commander", ">= 4.0.3"
15
+ gem.add_dependency "filander", ">= 0.6.0"
16
+ gem.add_dependency "rest-client", ">= 1.5.0"
17
+ gem.add_dependency "json_pure", ">= 1.4.2"
18
+ gem.add_dependency "activesupport"
19
+
20
+ gem.add_dependency "rid-push"
21
+ gem.add_dependency "rid-init"
22
+ gem.add_dependency "rid-dd"
23
+ gem.add_dependency "rid-export"
24
+
39
25
  gem.add_development_dependency "rspec", ">= 1.2.9"
40
26
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
41
27
  end
42
28
  Jeweler::GemcutterTasks.new
43
- Jeweler::RubyforgeTasks.new do |rubyforge|
44
- rubyforge.doc_task = "rdoc"
45
- end
46
29
  rescue LoadError
47
30
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
48
31
  end
@@ -65,8 +48,10 @@ task :default => :spec
65
48
 
66
49
  require 'rake/rdoctask'
67
50
  Rake::RDocTask.new do |rdoc|
51
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
52
+
68
53
  rdoc.rdoc_dir = 'rdoc'
69
- rdoc.title = "rid #{Rid::VERSION}"
54
+ rdoc.title = "rid #{version}"
70
55
  rdoc.rdoc_files.include('README*')
71
56
  rdoc.rdoc_files.include('lib/**/*.rb')
72
57
  end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.2
data/bin/rid CHANGED
@@ -1,7 +1,4 @@
1
- #!/usr/bin/env ruby1.8
1
+ #!/usr/bin/env ruby
2
2
 
3
- rid_path = File.expand_path('../../lib', __FILE__)
4
- $:.unshift(rid_path) if File.directory?(rid_path) && !$:.include?(rid_path)
5
-
6
- require 'rid'
7
- require 'rid/commands'
3
+ require File.join(File.dirname(__FILE__), '../lib/rid')
4
+ include Rid::Commands
data/lib/rid/app.rb ADDED
@@ -0,0 +1,49 @@
1
+ module Rid
2
+ # Holds Application config
3
+ #
4
+ class App
5
+ attr_reader :db_url, :db
6
+ attr_accessor :root
7
+
8
+ # Initialize app with an options object,
9
+ # which behaves like an open struct.
10
+ #
11
+ # Options are:
12
+ # root: specify app root directory
13
+ # database: set database name
14
+ #
15
+ def initialize(options = OpenStruct.new)
16
+ @root = options.root
17
+ @root ||= Dir.pwd
18
+ @root = Pathname.new(@root)
19
+
20
+ @db_url = options.database
21
+ @db_url ||= read_db_url
22
+ end
23
+
24
+ # Returns an instance of Rid::Database,
25
+ # configured with db_name.
26
+ #
27
+ def db
28
+ return unless @db_url
29
+ @db ||= Rid::Database.new(@db_url)
30
+ end
31
+
32
+ # List application documents.
33
+ # Each entry is a filename.
34
+ #
35
+ def documents
36
+ @documents ||= Dir[root.join("*")].
37
+ select { |f| File.directory? f }.
38
+ map { |f| Rid::Document.new :path => f }
39
+ end
40
+
41
+ private
42
+
43
+ def read_db_url
44
+ filename = root.join('_database')
45
+ File.read(filename).strip
46
+ rescue Errno::ENOENT
47
+ end
48
+ end
49
+ end
@@ -2,9 +2,13 @@ module Rid
2
2
  module Attachments
3
3
  # Mime type mapping from extensions
4
4
  MIME_TYPE_MAPPING = {
5
+ ".htm" => "text/html",
5
6
  ".html" => "text/html",
6
7
  ".js" => "text/javascript",
7
8
  ".css" => "text/css",
9
+ ".manifest" => "text/cache-manifest",
10
+ ".png" => "image/png",
11
+ ".gif" => "image/gif",
8
12
  }
9
13
 
10
14
 
@@ -44,11 +48,11 @@ module Rid
44
48
  # accessor for attachments hash
45
49
  #
46
50
  def attachments
47
- hash["_attachments"] || {}
51
+ @hash["_attachments"] || {}
48
52
  end
49
53
 
50
54
  def attachments=(value)
51
- self.hash["_attachments"] = value
55
+ @hash["_attachments"] = value
52
56
  end
53
57
 
54
58
 
data/lib/rid/commands.rb CHANGED
@@ -1,41 +1,63 @@
1
- if ARGV.empty?
2
- ARGV << '--help'
3
- end
1
+ module Rid
2
+ # Rid Commands module defines the available Rid commands.
3
+ # A Rid command is a commander command.
4
+ # See http://github.com/visionmedia/commander for more information.
5
+ #
6
+ module Commands
7
+ # Returns the version specified in VERSION file at project root.
8
+ #
9
+ def self.version
10
+ versionfile = File.expand_path('../../../VERSION', __FILE__)
11
+ File.read(versionfile) if File.file?(versionfile)
12
+ end
13
+
14
+ program :name, 'Rid: Rest in development.'
15
+ program :version, version
16
+ program :description, <<-STR
17
+ Rid is a toolkit to relax in web development.
18
+
19
+ Based on CouchDB you get a distributed,
20
+ high scaling web application infrastructure with Rid.
21
+
22
+ Rid commands are distributed as RubyGems. Explore more Rid commands via
23
+ 'gem list --remote rid-'
24
+
25
+ Type 'rid help command'
26
+ to get information about each command.
27
+ STR
28
+
29
+ program :help, 'Author', 'Johannes Jörg Schmidt, TF <schmidt@netzmerk.com>'
30
+
31
+ global_option '-q', '--quiet', 'Supress status output'
32
+
33
+ global_option '-b BEHAVIOR', '--behavior BEHAVIOR', String, 'Can be skip, pretend and force'
34
+
35
+ default_command :help
36
+
37
+ # List all installed rid gems, which starts with rid-.
38
+ #
39
+ def self.gems
40
+ Gem.path.
41
+ map { |p| Dir[File.join(p, 'gems/rid-*')] }.
42
+ flatten.
43
+ map { |g| File.basename(g).sub /-(\d+\.)*(\d+)$/, '' }.
44
+ uniq.
45
+ sort
46
+ end
47
+
48
+ private
49
+
50
+ # require rid gem and do not care if that fails.
51
+ #
52
+ def self.require_rid_gem(gem)
53
+ begin
54
+ require gem
55
+ rescue LoadError
56
+ return
57
+ end
58
+ end
4
59
 
5
- HELP_TEXT = <<-EOT
6
- Usage: rid COMMAND [ARGS]
7
-
8
- The most common rid commands are:
9
- generate Generate new code (short-cut alias: "g")
10
- push Push application code to Couchdb
11
- pull Pull latest application code from Couchdb
12
- routes List application urls
13
-
14
- In addition to those, there are:
15
- destroy Undo code generated with "generate"
16
-
17
- All commands can be run with -h for more information.
18
- EOT
19
-
20
-
21
- case ARGV.shift
22
- when 'g', 'generate'
23
- require 'rid/commands/generate'
24
- when 'destroy'
25
- require 'rid/commands/destroy'
26
- when 'push'
27
- require 'rid/commands/push'
28
- when 'pull'
29
- require 'rid/commands/pull'
30
- when 'routes'
31
- require 'rid/commands/routes'
32
-
33
- when '--help', '-h'
34
- puts HELP_TEXT
35
- when '--version', '-v'
36
- require 'rid/version'
37
- puts "Rid #{Rid::VERSION}"
38
- else
39
- puts "Error: Command not recognized"
40
- puts HELP_TEXT
60
+ # actually load all rid gems
61
+ gems.each { |g| require_rid_gem(g) }
62
+ end
41
63
  end
@@ -1,5 +1,5 @@
1
1
  class Hash
2
- DEFAULT_SEPERATOR = '/'
2
+ DEFAULT_SEPERATOR = '/' unless defined? DEFAULT_SEPERATOR
3
3
 
4
4
  def flatten(seperator = DEFAULT_SEPERATOR, prefix = nil)
5
5
  new_hash = {}
@@ -0,0 +1,69 @@
1
+ module Rid
2
+ class Database
3
+ attr_accessor :name
4
+
5
+ # Initialize new Database object by url.
6
+ #
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ # Get document.
12
+ #
13
+ def get(doc, options = {})
14
+ response = RestClient.get(url(doc, options)) rescue nil
15
+ Rid::Document.new(:json => response.body) if response
16
+ end
17
+
18
+ # Save document.
19
+ # Creates it, until exists.
20
+ #
21
+ def save(doc)
22
+ # create database unless exists
23
+ # TODO: make this lazy
24
+ begin
25
+ RestClient.put @name, nil
26
+ rescue RestClient::PreconditionFailed
27
+ # database already exists
28
+ end
29
+ # push document
30
+ response = RestClient.put(url(doc), doc.to_json)
31
+ json = JSON.parse(response.body)
32
+ if json && json["ok"] && json["rev"]
33
+ doc.rev = json["rev"]
34
+ end
35
+ # return response
36
+ response
37
+ end
38
+
39
+ # Base URL for design document
40
+ #
41
+ def base_url(doc)
42
+ File.join(@name, doc.id)
43
+ end
44
+
45
+ # URL for accessing document
46
+ #
47
+ # Takes an optional options hash
48
+ # which gets converted to url encoded options
49
+ # and appended to the documents base url
50
+ #
51
+ def url(doc, options = {})
52
+ base_url(doc) + build_options_string(options)
53
+ end
54
+
55
+ private
56
+
57
+ # construct url options string
58
+ # values are url encoded
59
+ #
60
+ def build_options_string(options)
61
+ return '' if options.empty?
62
+ options_array = []
63
+ options.each do |key, value|
64
+ options_array << URI.escape([key, value].join('='))
65
+ end
66
+ '?' + options_array.join("&")
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,99 @@
1
+ require 'erb'
2
+
3
+ module Rid
4
+ class Document
5
+ include Attachments
6
+
7
+ attr_accessor :hash, :path
8
+
9
+ def initialize(options = {})
10
+ path = options[:path]
11
+ path = Pathname.new(path) unless path.nil? || path.is_a?(Pathname)
12
+ @path = path
13
+ # build hash from options hash
14
+ @hash = options[:hash]
15
+ # build hash from json option
16
+ self.json = options[:json] if !@hash && options[:json]
17
+ @hash ||= {}
18
+ end
19
+
20
+ def ==(other)
21
+ @hash == other.hash
22
+ end
23
+
24
+ # Read document from a filesystem.
25
+ #
26
+ # Takes a filename,
27
+ # many filenames,
28
+ # or an array of filenames
29
+ # and assign the return value of a yielded block to the hash.
30
+ #
31
+ # Nested hashes
32
+ # like { "hash" => { "key" => "value" } }
33
+ # can be constructed if the filename contains a slash (/),
34
+ # eg "hash/key".
35
+ #
36
+ def read!(&block)
37
+ raise 'No path given!' unless @path
38
+
39
+ Dir[@path.join '**/*'].
40
+ map! { |file| Pathname.new file }.
41
+ delete_if { |f| !f.file? }.
42
+ flatten.
43
+ uniq.
44
+ each do |filename|
45
+ key = filename.relative_path_from(@path).to_s
46
+ # strip js extname from javascript files
47
+ key.sub!(/\.js$/, '') unless key =~ /^_attachments/
48
+ key.sub!(/\.erb$/, '')
49
+
50
+ value = block_given? ? block.call(filename) : read_file(filename)
51
+ # strip value if its a one-liner
52
+ value.strip! if value.count("\n") == 1
53
+ @hash.update_at key, value
54
+ end
55
+
56
+ map_attachments!
57
+ end
58
+
59
+
60
+ # Returns a JSON string representation of the documents hash
61
+ #
62
+ def to_json
63
+ @hash.to_json
64
+ end
65
+
66
+ # Build the documents hash from a JSON string
67
+ #
68
+ def json=(json)
69
+ @hash = JSON.parse(json)
70
+ end
71
+
72
+ def id
73
+ @id ||= @hash['_id']
74
+ @id ||= @path && File.read(@path.join('_id')).strip rescue nil
75
+ end
76
+
77
+ def rev
78
+ @rev ||= @hash['_rev']
79
+ @rev ||= @path && File.read(@path.join('_rev')).strip rescue nil
80
+ end
81
+
82
+ def rev=(value)
83
+ @rev = @hash['_rev'] = value
84
+ if @path
85
+ File.open(@path.join('_rev'), "w") { |file| file << value }
86
+ end
87
+ end
88
+
89
+ private
90
+
91
+ def read_file(filename)
92
+ if File.extname(filename) == '.erb'
93
+ ERB.new(File.read(filename)).result(binding)
94
+ else
95
+ File.read(filename)
96
+ end
97
+ end
98
+ end
99
+ end
data/lib/rid.rb CHANGED
@@ -1,43 +1,16 @@
1
+ require 'pathname'
2
+ require 'ostruct'
3
+
1
4
  require 'rubygems'
2
- require 'yaml'
5
+ require 'commander/import'
6
+ require 'filander'
7
+ require 'active_support/inflector'
3
8
  require 'json'
4
-
5
- module Rid
6
- CONFIG_FILENAME = ".ridrc"
7
-
8
- def self.root
9
- @root ||= find_root
10
- end
11
-
12
- def self.database
13
- @database ||= config["database"]
14
- end
15
-
16
- def self.id
17
- @id ||= File.read(File.join(root, '_id')).strip
18
- end
19
-
20
- def self.rev
21
- @rev ||= File.read(File.join(root, '_rev')).strip rescue nil
22
- end
23
-
24
- private
25
-
26
- def self.config
27
- @config ||= YAML.load(File.open config_file)
28
- end
29
-
30
- def self.config_file
31
- File.join root, CONFIG_FILENAME
32
- end
33
-
34
- def self.find_root
35
- cwd = Dir.pwd
36
- return cwd if File.exists?(File.join(cwd, CONFIG_FILENAME))
37
- Dir.chdir("..") do
38
- find_root unless cwd == Dir.pwd
39
- end
40
- rescue SystemCallError
41
- # could not chdir, no problem just return
42
- end
43
- end
9
+ require 'rest_client'
10
+
11
+ require 'rid/core_ext/hash'
12
+ require 'rid/attachments'
13
+ require 'rid/database'
14
+ require 'rid/document'
15
+ require 'rid/app'
16
+ require 'rid/commands'