spontaneous 0.2.0.alpha6 → 0.2.0.alpha7

Sign up to get free protection for your applications and to get access to all the features.
data/bin/spot CHANGED
@@ -30,4 +30,11 @@ end
30
30
 
31
31
  require 'spontaneous'
32
32
 
33
- Spontaneous::Cli::Root.start(ARGV)
33
+ begin
34
+ Spontaneous::Cli::Root.start(ARGV)
35
+ rescue Interrupt => e
36
+ puts "\nAbort..."
37
+ exit 1
38
+ rescue SystemExit => e
39
+ exit e.status
40
+ end
@@ -12,14 +12,21 @@ module Spontaneous::Cli
12
12
  default_task :site
13
13
 
14
14
  desc "site [DOMAIN]", "Generates a site skeleton. Usage: spot generate <site domain name>"
15
+
16
+ method_option :database, :type => :string, :default => "mysql", :aliases => "-d", :desc => "Database adapter"
17
+ method_option :user, :type => :string, :default => "root", :aliases => "-u", :desc => "Database admin user"
18
+ method_option :password, :type => :string, :default => "", :aliases => "-p", :desc => "Database admin user"
19
+
15
20
  def site(*args)
16
- require File.expand_path('../../../spontaneous', __FILE__)
17
- ::Spontaneous::Generators::Site.start(args)
21
+ # require "spontaneous"
22
+ ::Spontaneous::Generators::Site.start(ARGV.drop_while { |e| %w(generate site).include?(e) })
18
23
  end
19
24
 
20
25
  def method_missing(method, *args)
21
26
  if PublicSuffix.valid?(method.to_s)
27
+ puts method
22
28
  args.unshift(method.to_s)
29
+ ARGV.unshift("site")
23
30
  self.send(:site, *args)
24
31
  else
25
32
  super
@@ -1,5 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'etc'
4
+
3
5
  module Spontaneous::Cli
4
6
  class Init < ::Thor
5
7
  include Spontaneous::Cli::TaskUtils
@@ -10,39 +12,112 @@ module Spontaneous::Cli
10
12
  default_task :init
11
13
 
12
14
  desc :init, "Creates databases and initialises a new Spontaneous site"
15
+
16
+ method_option :user, :type => :string, :default => nil, :aliases => "-u", :desc => "Database admin user"
17
+ method_option :password, :type => :string, :default => "", :aliases => "-p", :desc => "Database admin password"
18
+ method_option :account, :type => :hash, :default => {}, :aliases => "-a", :desc => "Details of the root login"
19
+
13
20
  def init
14
21
  prepare :init
15
- site = ::Spontaneous::Site.instantiate(Dir.pwd, options.environment, :back)
16
- require File.expand_path('../../../spontaneous', __FILE__)
22
+
23
+ site = ::Spontaneous::Site.instantiate(Dir.pwd, options.environment, :console)
17
24
  Sequel.extension :migration
18
- connection_params = ::Spontaneous.db_settings
19
- connection_params[:user] = 'root'
20
- database = connection_params.delete(:database)
21
- password = connection_params.delete(:password)
22
- catch(:error) do
23
- Sequel.connect(connection_params) do |connection|
24
- ["", "_test"].map { |ext| "#{database}#{ext}"}.each do |db|
25
- begin
26
- say " >> Creating database `#{db}`"
27
- connection.run("CREATE DATABASE `#{db}` CHARACTER SET UTF8")
28
- rescue => e
29
- say " >>> Unable to create #{connection_params[:adapter]} database `#{db}`:\n > #{e}", :red
30
- # throw :error
31
- end
32
- begin
33
- connection.run("USE `#{db}`")
34
- connection.logger = nil
35
- say " >> Running migrations..."
36
- Sequel::Migrator.apply(connection, ::Spontaneous.gem_dir('db/migrations'))
37
- say " >> Done"
38
- rescue => e
39
- say " >>> Error running migrations on database `#{db}`:\n > #{e}", :red
40
- end
41
- end
25
+
26
+
27
+ database, admin_connection_params, site_connection_params = generate_connection_params
28
+
29
+ [database, "#{database}_test"].each do |db|
30
+ config = site_connection_params.merge(:database => db)
31
+ create(db, admin_connection_params, config)
32
+ migrate(db, admin_connection_params, config)
33
+ end
34
+
35
+ boot!
36
+
37
+ # Add a root user if this is a new site
38
+ insert_root_user if ::Spontaneous::Permissions::User.count == 0
39
+
40
+ end
41
+
42
+ protected
43
+
44
+ def insert_root_user
45
+ invoke "user:add", [], options.account
46
+ # Set up auto_login configuration with the name of the root user
47
+ # we've just created
48
+ root = ::Spontaneous::Permissions::User.first
49
+ config_path = "./config/environments/development.rb"
50
+ config = File.read(config_path, encoding: "UTF-8").
51
+ gsub(/__SPONTANEOUS_ROOT_USER_INSERT__/, root.login)
52
+ File.open(config_path, "w:UTF-8") do |file|
53
+ file.write(config)
54
+ end
55
+ end
56
+
57
+ def create(database, admin_config, site_config)
58
+ Sequel.connect(admin_config) do |connection|
59
+ begin
60
+ say " >> Creating database `#{site_config[:database]}`", :green
61
+ create_database(connection, site_config)
62
+ rescue => e
63
+ say " >>> Unable to create #{admin_config[:adapter]} database `#{site_config[:database]}`:\n > #{e}", :red
64
+ end
65
+ end
66
+ end
67
+
68
+ def migrate(database, admin_config, site_config)
69
+ Sequel.connect(admin_config.merge(:database => site_config[:database])) do |connection|
70
+ begin
71
+ connection.logger = nil
72
+ say " >> Running migrations..."
73
+ Sequel::Migrator.apply(connection, ::Spontaneous.gem_dir('db/migrations'))
74
+ say " >> Done"
75
+ rescue => e
76
+ say " >>> Error running migrations on database `#{site_config[:database]}`:\n > #{e}", :red
42
77
  end
43
- boot!
44
78
  end
45
79
  end
46
80
 
81
+ # Converts the site db parameters into 'admin' connection using the provided
82
+ # db credentials and the necessary :database settings
83
+ def generate_connection_params
84
+ site_connection_params = ::Spontaneous.db_settings
85
+ connection_params = site_connection_params.dup
86
+ connection_params[:user] = options.user unless options.user.blank?
87
+ connection_params[:password] = options.password unless options.password.blank?
88
+
89
+ database = connection_params.delete(:database)
90
+ case connection_params[:adapter]
91
+ when /mysql/
92
+ when /postgres/
93
+ # postgres requires that you connect to a db.
94
+ # "postgres" is guaranteed to exist
95
+ connection_params[:database] = "postgres"
96
+ end
97
+ [database, connection_params, site_connection_params]
98
+ end
99
+
100
+ def create_database(connection, config)
101
+ commands = case connection.database_type
102
+ when :postgres
103
+ [
104
+ [%(CREATE ROLE "#{config[:user]}" LOGIN PASSWORD '#{config[:password]}'), false],
105
+ [%(CREATE DATABASE "#{config[:database]}" TEMPLATE=template0 ENCODING='UTF8' OWNER="#{config[:user]}"), true]
106
+ ]
107
+ when :mysql
108
+ host = config[:host].blank? ? "" : "@#{config[:host]}"
109
+ [
110
+ ["CREATE DATABASE `#{config[:database]}` CHARACTER SET UTF8", true],
111
+ ["GRANT ALL ON `#{config[:database]}`.* TO `#{config[:user]}`#{host} IDENTIFIED BY '#{config[:password]}'", false]
112
+ ]
113
+ end
114
+ commands.each do |command, raise_error|
115
+ begin
116
+ connection.run(command)
117
+ rescue => e
118
+ raise e if raise_error
119
+ end
120
+ end
121
+ end
47
122
  end # Init
48
123
  end # Spontaneous::Cli
@@ -2,8 +2,7 @@
2
2
 
3
3
  # require 'spontaneous'
4
4
  require 'simultaneous'
5
- require 'foreman'
6
- require 'foreman/engine'
5
+ require 'foreman/engine/cli'
7
6
 
8
7
  module Spontaneous
9
8
  module Cli
@@ -17,15 +16,14 @@ module Spontaneous
17
16
 
18
17
  desc "start", "Starts Spontaneous in development mode"
19
18
  def start
20
- # I can do this programatically in the latest version of Foreman
21
- File.open(".Procfile", 'wb') do |procfile|
22
- procfile.write(%(back: #{binary} server back --root=#{options.site}\n))
23
- procfile.write(%(front: #{binary} server front --root=#{options.site}\n))
24
- procfile.write(%(simultaneous: #{binary} server simultaneous --root=#{options.site}\n))
25
- procfile.flush
26
- engine = ::Foreman::Engine.new(procfile.path)
27
- engine.start
19
+ root = File.expand_path(options.site)
20
+ engine = ::Foreman::Engine::CLI.new(root: options.site)
21
+
22
+ %w(back front publish).each do |process|
23
+ engine.register(process, "#{binary} server #{process} --root=#{root}")
28
24
  end
25
+
26
+ engine.start
29
27
  end
30
28
 
31
29
  desc "front", "Starts Spontaneous in front/public mode"
@@ -49,15 +47,13 @@ module Spontaneous
49
47
  def simultaneous
50
48
  prepare! :start
51
49
  connection = options[:connection] || ::Spontaneous.config.simultaneous_connection
52
- fork {
53
- ENV.delete("BUNDLE_GEMFILE")
54
- puts("#{Simultaneous.server_binary} -c #{connection} --debug")
55
- exec("#{Simultaneous.server_binary} -c #{connection} --debug")
56
- # sleep 10
57
- }
58
- Process.wait
50
+ exec({"BUNDLE_GEMFILE" => nil}, "#{Simultaneous.server_binary} -c #{connection} --debug")
59
51
  end
60
52
 
53
+ # A shorter name for the 'simultaneous' task is useful (Foreman appends
54
+ # it to each line of output)
55
+ map %w(bg publish) => :simultaneous
56
+
61
57
  private
62
58
 
63
59
  def binary
@@ -3,11 +3,11 @@ module ::Spontaneous
3
3
  module Cli
4
4
  class User < ::Thor
5
5
  include Spontaneous::Cli::TaskUtils
6
- # namespace :user
7
6
 
7
+ namespace :user
8
8
  default_task :add
9
9
 
10
- desc "#{namespace}:add", "Add a new user"
10
+ desc "add", "Add a new user"
11
11
 
12
12
  method_option :login, :type => :string, :aliases => "-l",
13
13
  :desc => "The user's login -- must be unique"
@@ -15,91 +15,160 @@ module ::Spontaneous
15
15
  :desc => "The user's name"
16
16
  method_option :email, :type => :string, :aliases => "-e",
17
17
  :desc => "The user's email address"
18
- method_option :passwd, :type => :string, :aliases => ["-p", "--password"],
18
+ method_option :password, :type => :string, :aliases => ["-p", "--passwd"],
19
19
  :desc => "The user's password"
20
20
  method_option :level, :type => :string, :aliases => "-a",
21
21
  :desc => "The user's access level"
22
22
 
23
23
  def add
24
- prepare :adduser, :console
25
- boot!
24
+ prepare! :adduser, :console
25
+
26
26
  users = ::Spontaneous::Permissions::User.count
27
- attrs = {}
28
- width = 14
29
- valid_login = /^[a-z0-9_]{3,}$/
30
- levels = ::Spontaneous::Permissions::UserLevel.all.map(&:to_s)
31
- level = nil
27
+
28
+ defaults = find_defaults(users)
32
29
 
33
30
  say("\nAll fields are required:\n", :green)
34
- if options.login
35
- attrs[:login] = options.login
36
- say "Login : ".rjust(width, " ")+" ", :white
37
- say options.login, :green
31
+
32
+ attrs, level = ask_user_details(defaults, users)
33
+
34
+ user = ::Spontaneous::Permissions::User.new(attrs)
35
+
36
+ if user.save
37
+ user.update(:level => level)
38
+ say("\nUser '#{user.login}' created with level '#{user.level}'", :green)
38
39
  else
39
- begin
40
- attrs[:login] = ask "Login : ".rjust(width, " ")
41
- say("Login must consist of at least 3 letters, numbers and underscores", :red) unless valid_login === attrs[:login]
42
- end while attrs[:login] !~ valid_login
40
+ errors = user.errors.map do | a, e |
41
+ " - #{a.to_s.capitalize} #{e.first} #{attrs[a].inspect}"
42
+ end.join("\n")
43
+ say("\nUnable to create user:\n"+errors, :red)
44
+ exit 127
43
45
  end
46
+ end
47
+
48
+
49
+ desc "list", "List the current users"
50
+ method_option :bare, :type => :boolean, :default => false, :aliases => %w(-b),
51
+ :desc => "Remove descriptive text from result"
52
+ def list
53
+ prepare! :listusers, :console
54
+ user_table(::Spontaneous::Permissions::User.all, options.bare)
55
+ end
44
56
 
45
- attrs[:name] = options.name || ask("Name : ".rjust(width, " "))
46
57
 
47
- if options.name
48
- say "Name : ".rjust(width, " ")+" ", :white
49
- say options.name, :green
58
+ desc "authenticate LOGIN PASSWORD", "Test a user/password combination"
59
+ method_option :bare, :type => :boolean, :default => false, :aliases => %w(-b),
60
+ :desc => "Remove descriptive text from result"
61
+
62
+ def authenticate(login, password)
63
+ prepare! :user_authenticate, :console
64
+ key = Spontaneous::Permissions::User.authenticate login, password
65
+ if key
66
+ say "\nAuthentication successful for user '#{login}'", :green unless options.bare
67
+ user_table([key.user], options.bare)
68
+ else
69
+ say "\nInvalid username & password combination", :red
70
+ exit 127
50
71
  end
72
+ end
73
+
74
+ protected
75
+
76
+ def user_table(users, hide_headers = false)
77
+ columns = [:login, :name, :email, :level]
78
+ users = ::Spontaneous::Permissions::User.all.map { |user|
79
+ columns.map { |column| user.send(column) }
80
+ }
81
+ users.unshift columns.map { |c| c.to_s.capitalize } unless hide_headers
82
+ puts "\n" unless hide_headers
83
+ print_table(users, indent: (hide_headers ? 0 : 2))
84
+ puts "\n"
85
+ end
51
86
 
52
- attrs[:email] = options.email || ask("Email : ".rjust(width, " "))
87
+ def find_defaults(existing_user_count)
88
+ return {} if existing_user_count > 0
53
89
 
54
- if options.email
55
- say "Email : ".rjust(width, " ")+" ", :white
56
- say options.email, :green
90
+ require 'etc'
91
+
92
+ defaults = { login: Etc.getlogin }
93
+ git_installed = Kernel.system "which git > /dev/null 2>&1"
94
+
95
+ if git_installed
96
+ defaults[:email] = `git config --get user.email`.chomp
97
+ defaults[:name] = `git config --get user.name`.chomp
57
98
  end
99
+ defaults
100
+ end
58
101
 
59
- if options.passwd
60
- attrs[:password] = options.passwd
61
- say "Password : ".rjust(width, " ")+" ", :white
62
- say options.passwd, :green
102
+ def prompt(attribute, default = nil, width = 14)
103
+ prompt = (attribute.to_s.capitalize).rjust(width, " ")
104
+ prompt << " :"
105
+ prompt << %( [#{default}]) if default
106
+ prompt
107
+ end
108
+
109
+ def request(attribute, default, value = nil)
110
+ if value
111
+ say prompt(attribute)+" ", :white
112
+ say value, :green
113
+ return value
63
114
  else
115
+ if block_given?
116
+ return yield
117
+ else
118
+ return ask_with_default(attribute, default)
119
+ end
120
+ end
121
+ end
122
+
123
+ def ask_with_default(attribute, default = nil)
124
+ result = ask(prompt(attribute, default))
125
+ return default if default && result == ""
126
+ result
127
+ end
128
+
129
+ def ask_user_details(defaults = {}, users)
130
+ attrs = {}
131
+ level = nil
132
+ width = 14
133
+ valid_login = /^[a-z0-9_]{3,}$/
134
+ levels = ::Spontaneous::Permissions::UserLevel.all.map(&:to_s)
135
+
136
+ attrs[:login] = request(:login, defaults[:login], options.login) do
64
137
  begin
65
- attrs[:password] = ask "Password : ".rjust(width, " ")
66
- say("Password must be at least 6 characters long", :red) unless attrs[:password].length > 5
67
- end while attrs[:password].length < 6
138
+ login = ask_with_default(:login, defaults[:login])
139
+ say("Login must consist of at least 3 letters, numbers and underscores", :red) unless valid_login === login
140
+ end while login !~ valid_login
141
+ login
68
142
  end
69
143
 
144
+ attrs[:name] = request(:name, defaults[:name], options.name)
145
+ attrs[:email] = request(:email, defaults[:email], options.email)
146
+ attrs[:password] = request(:password, nil, options.password) do
147
+ begin
148
+ passwd = ask_with_default(:password)
149
+ say("Password must be at least 6 characters long", :red) unless passwd.length > 5
150
+ end while passwd.length < 6
151
+ passwd
152
+ end
70
153
 
71
154
  if users == 0
72
155
  level = "root"
73
156
  else
74
- if options.level
75
- level = options.level
76
- say "User level : ".rjust(width, " ")+" ", :white
77
- say options.level, :green
78
- unless levels.include?(level)
79
- say("\nInvalid level '#{level}'", :red)
80
- say("Valid levels are: #{levels.join(", ")}", :red)
81
- exit 127
82
- end
83
- else
157
+ level = options.level
158
+ unless level.blank? or levels.include?(level)
159
+ say("\nInvalid level '#{level}'", :red)
160
+ say("Valid levels are: #{levels.join(", ")}", :red)
161
+ exit 127
162
+ end
163
+ level = request(:level, nil, level) do
84
164
  begin
85
- level = ask("User level [#{levels.join(', ')}] : ")
165
+ level = ask(prompt("User level")+ " [#{levels.join(', ')}]")
86
166
  say("Invalid level '#{level}'", :red) unless levels.include?(level)
87
167
  end while !levels.include?(level)
168
+ level
88
169
  end
89
170
  end
90
-
91
- user = ::Spontaneous::Permissions::User.new(attrs)
92
-
93
- if user.save
94
- user.update(:level => level)
95
- say("\nUser '#{user.login}' created with level '#{user.level}'", :green)
96
- else
97
- errors = user.errors.map do | a, e |
98
- " - '#{a.to_s.capitalize}' #{e.first}"
99
- end.join("\n")
100
- say("\nInvalid user details:\n"+errors, :red)
101
- exit 127
102
- end
171
+ [attrs, level]
103
172
  end
104
173
  end
105
174
  end
@@ -12,7 +12,7 @@ module Spontaneous
12
12
  "#{basename} #{task.formatted_usage(self, true, subcommand)}"
13
13
  end
14
14
  end
15
- base.class_option :site, :type => :string, :aliases => ["-s", "--root"], :desc => "Site root dir"
15
+ base.class_option :site, :type => :string, :aliases => ["-s", "--root"], :default => ".", :desc => "Site root dir"
16
16
  base.class_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development, :desc => "Spontaneous Environment"
17
17
  base.class_option :mode, :type => :string, :aliases => "-m", :default => :back, :desc => "Spontaneous mode ('front' or 'back')"
18
18
  base.class_option :help, :type => :boolean, :desc => "Show help usage"
@@ -113,6 +113,8 @@ module Spontaneous
113
113
  ::Launchy.open("http://localhost:#{::Spontaneous::Site.config.port}/@spontaneous")
114
114
  end
115
115
 
116
+ map %w(--version -v) => :version
117
+
116
118
  desc :version, "Show the version of Spontaneous in use"
117
119
  def version
118
120
  require "spontaneous/version"
@@ -1,6 +1,5 @@
1
1
  log/*
2
2
  tmp/*
3
3
  cache/*
4
- .Procfile
5
4
  .irb_history
6
5
 
@@ -1,8 +1,11 @@
1
1
  source :rubygems
2
2
 
3
- ## choose your poison:
4
- # gem 'pg', '~> 0.14.0'
5
- gem 'mysql2', '~> 0.3'
3
+ # You can either fix the version of Spontaneous that this site uses
4
+ gem 'spontaneous', '~> <%= Spontaneous::VERSION %>'
5
+ # Or point it at a git repository to use the cutting edge or your custom version
6
+ # gem 'spontaneous', :git => "https://github.com/SpontaneousCMS/spontaneous.git"
7
+
8
+ gem '<%= @database[:gem].name %>', '<%= @database[:gem].requirement %>'
6
9
 
7
10
  # Deploy with Capistrano
8
11
  gem 'capistrano', '~> 2.9'
@@ -13,12 +16,6 @@ gem 'capistrano', '~> 2.9'
13
16
  #gem 'xapian-full', "~> 1.2.3"
14
17
  #gem 'xapian-fu', "~> 1.3"
15
18
 
16
- ## TODO: replace this path based gem with a version once the gem is live
17
- #gem 'spontaneous', '<%= Spontaneous::VERSION %>'
18
-
19
- gem 'spontaneous', :git => "git://github.com/SpontaneousCMS/spontaneous.git"
20
- gem 'simultaneous', :git => "git://github.com/SpontaneousCMS/simultaneous.git"
21
-
22
19
  # group :production do
23
20
  # gem 'thin', '~> 1.3.1'
24
21
  # gem 'unicorn', '~> 4.2'
@@ -1,5 +1,5 @@
1
1
  SPOT_ENV = (ENV["SPOT_ENV"] ||= ENV["RACK_ENV"] ||= "development").to_sym unless defined?(SPOT_ENV)
2
- SPOT_MODE = (ENV["SPOT_MODE"] ||= "back").to_sym unless defined?(SPOT_MODE)
2
+ SPOT_MODE = (ENV["SPOT_MODE"] ||= "console").to_sym unless defined?(SPOT_MODE)
3
3
 
4
4
  Encoding.default_external = Encoding::UTF_8 if defined?(Encoding)
5
5
 
@@ -10,10 +10,4 @@ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
10
10
 
11
11
  Bundler.require(:default, SPOT_ENV, SPOT_MODE)
12
12
 
13
- # TODO: configuration of template engine
14
- # so, remove this require and move the template init into part of the ::load! method
15
- # using config settings to determine engine
16
- require 'cutaneous'
17
-
18
13
  Spontaneous.init(:environment => SPOT_ENV, :mode => SPOT_MODE)
19
-
@@ -1,9 +1,12 @@
1
1
  ---
2
2
  :development: &defaults
3
- :adapter: mysql2
3
+ :adapter: <%= @database[:adapter] %>
4
4
  :database: <%= @site_name %>
5
- :user: root
6
- :host: localhost
5
+ :user: <%= @database[:user] %>
6
+ :password: <%= @database[:password] %>
7
+ <% unless (host = @database[:host]).blank? -%>
8
+ :host: <%= host %>
9
+ <% end %>
7
10
 
8
11
  :test:
9
12
  <<: *defaults
@@ -13,7 +16,7 @@
13
16
  <<: *defaults
14
17
  :database: <%= @site_name %>
15
18
  :user: <%= @site_name %>
16
- :password: passw0rd
19
+ :password: <%= @database[:password] %>
17
20
 
18
21
  :rake:
19
22
  <<: *defaults
@@ -6,12 +6,21 @@ simultaneous_connection "/tmp/simultaneous.<%= @site_name %>.sock"
6
6
  # ensures that schema classes are reloaded with every request
7
7
  reload_classes true
8
8
 
9
+ # This provides you with login-less access to the CMS interface while in
10
+ # development mode. Change this value to automatically login as a different
11
+ # user or comment it out to reproduce the production environment.
12
+ # DO NOT set this value in production.
13
+ auto_login '__SPONTANEOUS_ROOT_USER_INSERT__'
14
+
9
15
  host 'localhost'
10
16
 
17
+ # This sets the port that the editing interface runs under
11
18
  back do
12
- port 2011
19
+ port 2011
13
20
  end
14
21
 
22
+ # This sets the port that the published/live version of the development
23
+ # site runs under.
15
24
  front do
16
- port 2012
25
+ port 2012
17
26
  end
@@ -6,7 +6,9 @@ module Spontaneous
6
6
  module Generators
7
7
  class Site < Thor::Group
8
8
  def self.available_dbs
9
- %w(mysql postgres)
9
+ { "mysql" => { :gem => "mysql2", :adapter => "mysql2" },
10
+ "postgresql" => { :gem => "pg", :adapter => "postgres" },
11
+ "postgres" => { :gem => "pg", :adapter => "postgres" } }
10
12
  end
11
13
 
12
14
  def self.source_root; File.expand_path(File.dirname(__FILE__) + "/site"); end
@@ -14,20 +16,27 @@ module Spontaneous
14
16
 
15
17
  include Thor::Actions
16
18
 
19
+ argument :domain, :type => :string, :desc => "The domain name of the site to generate"
20
+
17
21
  class_option :root, :desc => "The root destination", :aliases => '-r', :default => ".", :type => :string
18
- class_option :database, :desc => "The database to use ('mysql' (default) or 'postgres')", :aliases => '-d', :default => "mysql", :type => :string
19
- class_option :dbpwd, :desc => "The password for the database root user", :aliases => '-p', :default => "", :type => :string
22
+ class_option :database, :desc => "The database to use ('mysql' (default) or 'postgres')", :aliases => %w(-d --db), :default => "mysql", :type => :string
23
+ class_option :user, :desc => "The database account to use", :aliases => '-u', :default => "root", :type => :string
24
+ class_option :password, :desc => "The password for the database user", :aliases => %w(-p), :default => "", :type => :string
25
+ class_option :host, :desc => "The database host", :aliases => %w(-h), :default => "", :type => :string
20
26
 
21
- argument :domain, :type => :string, :desc => "The domain name of the site to generate"
22
27
 
23
28
  desc "Generates a new site for DOMAIN"
24
29
  def create_site
25
- if self.class.available_dbs.include?(options.database)
30
+ if self.class.available_dbs.keys.include?(options.database)
31
+ spec = Gem::Specification.load(File.expand_path("../../../../spontaneous.gemspec", __FILE__))
32
+ adapter = self.class.available_dbs[options.database]
33
+ adapter_dependency = spec.development_dependencies.detect { |dependency| dependency.name == adapter[:gem] }
26
34
  @valid = true
27
35
  say "Generating '#{domain}'...", :bold
28
36
  @domain = domain
29
37
  @site_name = domain.to_s.gsub(/\./, "_")
30
38
  @username = domain.split(/\./).first
39
+ @database = { :user => options.user, :adapter => adapter[:adapter], :gem => adapter_dependency, :password => options.password, :host => options.host }
31
40
  self.destination_root = options[:root]
32
41
  empty_directory(@site_name)
33
42
  self.destination_root = self.destination_root / @site_name
@@ -49,7 +58,7 @@ module Spontaneous
49
58
  template "lib/tasks/site.rake.tt", "lib/tasks/#{@site_name}.rake"
50
59
  else
51
60
  @valid = false
52
- say "Invalid database selection '#{options.database}'. Valid options are: #{available_dbs.join(', ')}", :red
61
+ say "Invalid database selection '#{options.database}'. Valid options are: #{self.class.available_dbs.keys.join(', ')}", :red
53
62
  end
54
63
  end
55
64
 
@@ -1,26 +1,26 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'oj'
3
+ require 'yajl'
4
4
 
5
- Oj.default_options = {
6
- mode: :compat
7
- } if defined?(Oj)
5
+ Oj.default_options = { mode: :compat } if defined?(Oj)
8
6
 
9
7
  module Spontaneous
10
8
  module JSON
11
- module OjParser
12
- def parse(json_string)
13
- ::Oj.load(json_string, symbol_keys: true)
14
- rescue
15
- nil
16
- end
9
+ if defined?(::Oj)
10
+ module OjParser
11
+ def parse(json_string)
12
+ ::Oj.load(json_string, symbol_keys: true)
13
+ rescue
14
+ nil
15
+ end
17
16
 
18
- def encode(object)
19
- ::Oj.dump(object)
17
+ def encode(object)
18
+ ::Oj.dump(object)
19
+ end
20
20
  end
21
21
  end
22
22
 
23
- if defined?(Yajl)
23
+ if defined?(::Yajl)
24
24
  module YajlParser
25
25
  def parser
26
26
  Yajl::Parser.new(:symbolize_keys => true)
@@ -41,7 +41,7 @@ module Spontaneous
41
41
  end
42
42
  end
43
43
 
44
- extend OjParser
44
+ extend const_get ["OjParser", "YajlParser"].detect { |m| const_defined?(m) }
45
45
 
46
46
  def parse_json(json_string)
47
47
  Spontaneous::JSON.parse(json_string)
@@ -20,7 +20,7 @@ module Spontaneous
20
20
  end
21
21
 
22
22
  def self.register_task
23
- publish_binary = spot_binary + " site:publish"
23
+ publish_binary = spot_binary + " site publish"
24
24
  site_root = Pathname.new(Spontaneous.root).expand_path.to_s
25
25
  niceness = S.config.publish_niceness || 15
26
26
  logfile = "#{site_root}/log/publish.log"
@@ -254,8 +254,8 @@ module Spontaneous
254
254
  Content.db.transaction {
255
255
  dataset = lock ? Content.for_update : Content
256
256
  content = dataset.first(:id => params[:id])
257
- content.current_editor = user
258
257
  halt 404 if content.nil?
258
+ content.current_editor = user
259
259
  if box_id = Spontaneous.schema.uids[params[:box_id]]
260
260
  box = content.boxes.detect { |b| b.schema_id == box_id }
261
261
  yield(content, box)
@@ -4,14 +4,14 @@ Sequel.extension :inflector
4
4
 
5
5
  require 'sequel/plugins/serialization'
6
6
 
7
- # Sequel::Plugins::Serialization.register_format(
8
- # :yajl,
9
- # lambda { |v| Yajl::Encoder.new.encode(v) },
10
- # lambda { |v| Yajl::Parser.new(:symbolize_keys => true).parse(v) }
11
- # )
12
7
  Sequel::Plugins::Serialization.register_format(
13
8
  :ojson,
14
- lambda { |v| Oj.dump(v) },
15
- lambda { |v| Oj.load(v, symbol_keys: true) }
9
+ lambda { |v| Yajl::Encoder.new.encode(v) },
10
+ lambda { |v| Yajl::Parser.new(:symbolize_keys => true).parse(v) }
16
11
  )
12
+ # Sequel::Plugins::Serialization.register_format(
13
+ # :ojson,
14
+ # lambda { |v| Oj.dump(v) },
15
+ # lambda { |v| Oj.load(v, symbol_keys: true) }
16
+ # )
17
17
 
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Spontaneous
4
- VERSION = "0.2.0.alpha6"
4
+ VERSION = "0.2.0.alpha7"
5
5
  GEM = false
6
6
  end
data/spontaneous.gemspec CHANGED
@@ -14,8 +14,8 @@ Gem::Specification.new do |s|
14
14
  ## If your rubyforge_project name is different, then edit it and comment out
15
15
  ## the sub! line in the Rakefile
16
16
  s.name = 'spontaneous'
17
- s.version = '0.2.0.alpha6'
18
- s.date = '2012-10-17'
17
+ s.version = '0.2.0.alpha7'
18
+ s.date = '2012-11-01'
19
19
  s.rubyforge_project = 'spontaneous'
20
20
 
21
21
  ## Make sure your summary is short. The description may be as long
@@ -49,14 +49,13 @@ Gem::Specification.new do |s|
49
49
  ## List your runtime dependencies here. Runtime dependencies are those
50
50
  ## that are needed for an end user to actually USE your code.
51
51
  s.add_dependency('activesupport', ["~> 3.2.0"])
52
- s.add_dependency('i18n', ["~> 0.6.0"]) # this is an undeclared activesupport dependency
53
52
  s.add_dependency('base58', ["~> 0.1.0"])
54
53
  s.add_dependency('bundler', ["> 1.0.15"])
55
54
  s.add_dependency('coffee-script', ["~> 2.2.0"])
56
55
  s.add_dependency('cutaneous', ["~> 0.1.3"])
57
56
  s.add_dependency('erubis', ["~> 2.6"])
58
57
  s.add_dependency('fog', ["~> 1.6.0"])
59
- s.add_dependency('foreman', ["~> 0.22.0"])
58
+ s.add_dependency('foreman', ["~> 0.60.2"])
60
59
  s.add_dependency('kramdown', ["~> 0.14.0"])
61
60
  s.add_dependency('launchy', ["~> 2.1.2"])
62
61
  s.add_dependency('mini_magick', ["~> 3.3"])
@@ -78,7 +77,7 @@ Gem::Specification.new do |s|
78
77
  s.add_dependency('thin', ["~> 1.2"])
79
78
  s.add_dependency('thor', ["~> 0.16.0"])
80
79
  s.add_dependency('uglifier', ["~> 1.3.0"])
81
- s.add_dependency('oj', ["~> 1.4"])
80
+ s.add_dependency('yajl-ruby', ["~> 1.1.0"])
82
81
 
83
82
  ## List your development dependencies here. Development dependencies are
84
83
  ## those that are only needed during development
@@ -2,30 +2,188 @@
2
2
 
3
3
  require File.expand_path('../../test_integration_helper', __FILE__)
4
4
 
5
- describe "Installation" do
6
- def system(command)
7
- puts "SYSTEM #{command.inspect}"
8
- Kernel.system command
5
+ require 'open3'
6
+ require 'expect'
7
+ require 'yaml'
8
+ require 'etc'
9
+ require 'bundler'
10
+
11
+ ENV["DB"] ||= "mysql"
12
+ ENV["DB_USER"] ||= "root"
13
+
14
+ puts "--- Testing against db #{ENV["DB"]} (#{ENV["DB_USER"]})"
15
+
16
+ $_pwd = Dir.pwd
17
+
18
+ # Test both the currently released gem and the development version
19
+ # This is mostly about dependencies
20
+ if ENV["GEM_SOURCE"] == "rubygems"
21
+ $_gem = "spontaneous"
22
+ else
23
+ system "rm -rf pkg && rake gem:build"
24
+ $_gem = File.expand_path(Dir["pkg/*.gem"].last)
25
+ end
26
+
27
+ $_root = Dir.mktmpdir
28
+ Dir.chdir($_root)
29
+
30
+
31
+ class SpontaneousInstallationTest < OrderedTestCase
32
+
33
+ def self.before_suite
9
34
  end
10
35
 
11
- before do
12
- @root = Dir.mktmpdir
13
- Dir.chdir(@root)
14
- puts "root.before"
36
+ def self.after_suite
37
+ Kernel.system "gem uninstall -a -x -I spontaneous"
38
+ Dir.chdir($_pwd)
39
+ FileUtils.rm_r($_root)
15
40
  end
16
41
 
17
- describe "when starting with a base system" do
18
- before do
19
- puts "describe.before"
42
+ def system(command, env = {})
43
+ Bundler.with_clean_env do
44
+ puts "$ #{command}" #if $DEBUG
45
+ Open3.popen3(env, command) do |stdin, stdout, stderr, wait_thread|
46
+ out = stdout.read.chomp
47
+ err = stderr.read.chomp
48
+ sts = wait_thread.value
49
+ [sts, out, err]
50
+ end
20
51
  end
52
+ end
21
53
 
22
- it "will allow the installation of the spontaneous gem" do
23
- assert_raises "Precondition failed, spontaneous gem is already installed", Gem::LoadError do
24
- Gem::Specification.find_by_name("spontaneous")
25
- end
26
- system "gem install spontaneous --prerelease --no-rdoc --no-ri"
27
- spec = Gem::Specification.find_by_name("spontaneous")
28
- asssert_instance_of Gem::Specification, spec, "spontaneous gem should have been installed"
54
+ def existing_databases(database = ENV["DB"])
55
+ case database
56
+ when "postgres"
57
+ status, out, _ = system "psql -t -l -U #{ENV["DB_USER"]}"
58
+ databases = out.split("\n").map { |line| line.split("|").first.strip }
59
+ when "mysql"
60
+ status, out, _ = system "mysql -u #{ENV["DB_USER"]} --skip-column-names -e 'show databases'"
61
+ databases = out.split("\n").map { |line| line.strip }
62
+ end
63
+ end
64
+
65
+ def setup
66
+ @account = {
67
+ :login => Etc.getlogin,
68
+ :password => "0123456789",
69
+ :name => "A User",
70
+ :email => "auser@example.com"
71
+ }
72
+ end
73
+
74
+ def test_step_001__gem_installation
75
+ assert_raises "Precondition failed, spontaneous gem is already installed", Gem::LoadError do
76
+ Gem::Specification.find_by_name("spontaneous")
77
+ end
78
+ system "gem install #{$_gem} --no-rdoc --no-ri"
79
+ Gem.refresh
80
+ @spec = Gem::Specification.find_by_name("spontaneous")
81
+ assert_instance_of Gem::Specification, @spec, "spontaneous gem should have been installed"
82
+ end
83
+
84
+
85
+ def test_step_002__spontaneous_version
86
+ @spec = Gem::Specification.find_by_name("spontaneous")
87
+ %w(version --version -v).each do |opt|
88
+ status, version, _ = system "spot #{opt}"
89
+ assert status.exitstatus == 0, "Expected status of 0 but got #{status.exitstatus}"
90
+ assert_match /#{@spec.version.to_s}/, version, "Got an incorrect version #{version.inspect} for spontaneous"
91
+ end
92
+ end
93
+
94
+ def test_step_003__valid_site_creation
95
+ domain = "example.org"
96
+ refute File.exist?("example_org"), "Precondition failed, site directory should not exist"
97
+ status, output, err = system "spot generate --database=#{ENV["DB"]} --user=#{ENV["DB_USER"]} --host=#{ENV["DB_HOST"]} #{domain}"
98
+ assert status.exitstatus == 0, "Expected status of 0 but got #{status.exitstatus}"
99
+ assert File.exist?("example_org"), "Site directory should exist after generation step"
100
+ Dir.chdir("example_org")
101
+ assert File.exist?("Gemfile")
102
+ assert File.exist?("config/schema.yml")
103
+ end
104
+
105
+ def test_step_004__bundler_should_install_dependencies
106
+ ENV["BUNDLE_GEMFILE"] = File.expand_path("Gemfile")
107
+ status, output, err = system "bundle install --without development test", { "BUNDLE_GEMFILE" => ENV["BUNDLE_GEMFILE"] }
108
+ puts output
109
+ assert status.exitstatus == 0, "Bundler failed to run #{err.inspect}"
110
+ end
111
+
112
+ def test_step_005__site_initialization_should_run
113
+ cmd = "spot init --user=#{ENV['DB_USER']} "
114
+ cmd << "--account login:#{@account[:login]} email:#{@account[:email]} name:'#{@account[:name]}' password:#{@account[:password]}"
115
+ status, out, err = system cmd, { "BUNDLE_GEMFILE" => ENV["BUNDLE_GEMFILE"] }
116
+ puts out
117
+ puts err
118
+ unless status.exitstatus == 0
119
+ fail "init task failed with error"
120
+ end
121
+ end
122
+
123
+ def test_step_006__site_initialization_should_create_databases
124
+ db_config = YAML.load_file("config/database.yml")
125
+ assert existing_databases.include?(db_config[:development][:database]),
126
+ "Database '#{db_config[:development][:database]}' should have been created"
127
+ end
128
+
129
+ def test_step_007__site_initialization_should_run_migrations
130
+ %w(example_org example_org_test).each do |db|
131
+ tables = case ENV["DB"]
132
+ when "postgres"
133
+ status, out, _ = system "psql -t -U #{ENV["DB_USER"]} -d #{db} -c '\\dt'"
134
+ out.split("\n").map { |line| line.split("|")[1].strip }
135
+ when "mysql"
136
+ status, out, _ = system "mysql -u #{ENV["DB_USER"]} --skip-column-names -e 'show tables' #{db}"
137
+ out.split("\n").map { |line| line.strip }
138
+ end
139
+ expected = %w(content spontaneous_users spontaneous_state)
140
+ assert (expected & tables) == expected, "Migration has not created expected tables: #{tables}"
29
141
  end
30
142
  end
143
+
144
+ def select_users
145
+ status, out, _ = system "spot user list --bare", { "BUNDLE_GEMFILE" => ENV["BUNDLE_GEMFILE"] }
146
+ assert status.exitstatus == 0, "Failed to list users"
147
+ parse_user_list(out)
148
+ end
149
+
150
+ def parse_user_list(output)
151
+ users = output.strip.split("\n").map { |line| line.split(/ {2,}/).map(&:strip) }
152
+ end
153
+
154
+ def test_step_008__site_initialization_should_add_root_user
155
+ status, out, _ = system "spot user list --bare", { "BUNDLE_GEMFILE" => ENV["BUNDLE_GEMFILE"] }
156
+ assert status.exitstatus == 0, "Failed to list users"
157
+ users = select_users
158
+ assert users.length == 1, "Site initialization should have created a single user not #{users.length}"
159
+ login, name, email, level = users.first
160
+ assert login == @account[:login], "Incorrect login #{login}"
161
+ assert name == @account[:name], "Incorrect name #{name}"
162
+ assert email == @account[:email], "Incorrect email #{email}"
163
+ assert level == "root", "Incorrect level #{email}"
164
+ end
165
+
166
+ def test_step_009__site_initialization_should_not_add_root_user_if_exists
167
+ users = select_users.length
168
+ assert users == 1, "Precondition failed. There should only be 1 user"
169
+ cmd = "spot init --user=#{ENV['DB_USER']}"
170
+ status, out, _ = system cmd, { "BUNDLE_GEMFILE" => ENV["BUNDLE_GEMFILE"] }
171
+ users = select_users.length
172
+ assert users == 1, "Re-running the 'init' command shouldn't add another user"
173
+ end
174
+
175
+ def test_step_010__site_initialization_should_use_correct_password
176
+ status, out, _ = system "spot user authenticate #{@account[:login]} #{@account[:password]} --bare", { "BUNDLE_GEMFILE" => ENV["BUNDLE_GEMFILE"] }
177
+ assert status.exitstatus == 0, "Failed to authenticate root user"
178
+ users = parse_user_list(out)
179
+ assert users.length == 1, "Site initialization should have created a single user not #{users.length}"
180
+ assert users.first.first == @account[:login]
181
+ end
182
+
183
+ def test_step_011__site_initialization_should_append_auto_login_config
184
+ config = File.read("config/environments/development.rb")
185
+ assert_match /^\s*auto_login +('|")#{@account[:login]}\1/, config,
186
+ "Config should include auto_login for '#{@account[:login]}'"
187
+ end
31
188
  end
189
+
@@ -1,9 +1,50 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  # Helpers for integration tests
4
+ require "rbconfig"
4
5
  require "rubygems"
5
- require "bundler/setup"
6
- require "minitest/spec"
6
+
7
+ # 1.9.2's minitest is way out of date
8
+ if RUBY_VERSION < "1.9.3"
9
+ gem "minitest"
10
+ end
11
+
12
+ require "minitest/unit"
7
13
  require "minitest/autorun"
8
- require 'tmpdir'
9
- require 'pp'
14
+ require "tmpdir"
15
+ require "pp"
16
+
17
+
18
+ # A test case that reproduces the actions of a user and hence need to run in order
19
+ # I.e. I don't suck thank you very much
20
+ class OrderedRunner < MiniTest::Unit
21
+ def before_suites
22
+ end
23
+
24
+ def after_suites
25
+ end
26
+
27
+ def _run_suites(suites, type)
28
+ begin
29
+ before_suites
30
+ super(suites, type)
31
+ ensure
32
+ after_suites
33
+ end
34
+ end
35
+
36
+ def _run_suite(suite, type)
37
+ begin
38
+ suite.before_suite if suite.respond_to?(:before_suite)
39
+ super(suite, type)
40
+ ensure
41
+ suite.after_suite if suite.respond_to?(:after_suite)
42
+ end
43
+ end
44
+ end
45
+
46
+ MiniTest::Unit.runner = OrderedRunner.new
47
+
48
+ class OrderedTestCase < MiniTest::Unit::TestCase
49
+ i_suck_and_my_tests_are_order_dependent!
50
+ end
@@ -26,6 +26,11 @@ class GeneratorsTest < MiniTest::Spec
26
26
  }
27
27
  end
28
28
 
29
+ def database_config(path)
30
+ path = File.join(@tmp, path, "config/database.yml")
31
+ YAML.load_file(path)
32
+ end
33
+
29
34
  attr_reader :site_root
30
35
 
31
36
  context "Site generator" do
@@ -75,8 +80,63 @@ class GeneratorsTest < MiniTest::Spec
75
80
  assert File.read(site_root / '.gitignore') =~ /cache\/\*/
76
81
  assert File.read(site_root / 'schema/piece.rb') =~ /class Piece < Spontaneous::Piece/
77
82
  end
78
- should "accept domain names starting with numbers"
79
- should "accept domain names containing dashes"
83
+
84
+ should "specify the current version of spontaneous as the dependency" do
85
+ generate(:site, "example.com", "--root=#{@tmp}")
86
+ site_root = File.join(@tmp, 'example_com')
87
+ gemfile = File.read(File.join(site_root, "Gemfile"))
88
+ gemfile.should =~ /^gem 'spontaneous', +'~> *#{Spontaneous::VERSION}'$/
89
+ end
90
+
91
+ should "correctly configure the site for a 'mysql' database" do
92
+ site_root = File.join(@tmp, 'example_com')
93
+ generate(:site, "example.com", "--root=#{@tmp}", "--database=mysql", "--host=127.0.0.1")
94
+ gemfile = File.read(File.join(site_root, "Gemfile"))
95
+ gemfile.should =~ /^gem 'mysql2'/
96
+ config = database_config("example_com")
97
+ [:development, :test, :production].each do |environment|
98
+ config[environment][:adapter].should == "mysql2"
99
+ config[environment][:database].should =~ /^example_com(_test)?/
100
+ # db connections seem to work if you exclude the host
101
+ config[environment][:host].should == "127.0.0.1"
102
+ end
103
+ end
104
+
105
+ should "correctly configure the site for a 'postgresql' database" do
106
+ site_root = File.join(@tmp, 'example_com')
107
+ generate(:site, "example.com", "--root=#{@tmp}", "--database=postgresql", "--host=")
108
+ gemfile = File.read(File.join(site_root, "Gemfile"))
109
+ gemfile.should =~ /^gem 'pg'/
110
+ config = database_config("example_com")
111
+ [:development, :test, :production].each do |environment|
112
+ config[environment][:adapter].should == "postgres"
113
+ config[environment][:database].should =~ /^example_com(_test)?/
114
+ config[environment].key?(:host).should be_false
115
+ end
116
+ end
117
+
118
+ should "correctly configure the site for a 'postgres' database" do
119
+ site_root = File.join(@tmp, 'example_com')
120
+ generate(:site, "example.com", "--root=#{@tmp}", "--database=postgres")
121
+ gemfile = File.read(File.join(site_root, "Gemfile"))
122
+ gemfile.should =~ /^gem 'pg'/
123
+ config = database_config("example_com")
124
+ [:development, :test, :production].each do |environment|
125
+ config[environment][:adapter].should == "postgres"
126
+ end
127
+ end
128
+
129
+ should "include specified connection params in the generated database config" do
130
+ site_root = File.join(@tmp, 'example_com')
131
+ generate(:site, "example.com", "--root=#{@tmp}", "--database=postgres", "--user=spontaneous", "--password=s3cret")
132
+ gemfile = File.read(File.join(site_root, "Gemfile"))
133
+ gemfile.should =~ /^gem 'pg'/
134
+ config = database_config("example_com")
135
+ [:development, :test].each do |environment|
136
+ config[environment][:user].should == "spontaneous"
137
+ config[environment][:password].should == "s3cret"
138
+ end
139
+ end
80
140
  end
81
141
 
82
142
  context "Page generator" do
@@ -84,6 +144,7 @@ class GeneratorsTest < MiniTest::Spec
84
144
  generate(:site, "example.com", "--root=#{@tmp}")
85
145
  @site_root = File.join(@tmp, 'example_com')
86
146
  end
147
+
87
148
  should "create a page class and associated templates" do
88
149
  %w(large_page LargePage).each do |name|
89
150
  generate(:page, name, "--root=#{site_root}")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spontaneous
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.alpha6
4
+ version: 0.2.0.alpha7
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-17 00:00:00.000000000 Z
12
+ date: 2012-11-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -27,22 +27,6 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: 3.2.0
30
- - !ruby/object:Gem::Dependency
31
- name: i18n
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ~>
36
- - !ruby/object:Gem::Version
37
- version: 0.6.0
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 0.6.0
46
30
  - !ruby/object:Gem::Dependency
47
31
  name: base58
48
32
  requirement: !ruby/object:Gem::Requirement
@@ -146,7 +130,7 @@ dependencies:
146
130
  requirements:
147
131
  - - ~>
148
132
  - !ruby/object:Gem::Version
149
- version: 0.22.0
133
+ version: 0.60.2
150
134
  type: :runtime
151
135
  prerelease: false
152
136
  version_requirements: !ruby/object:Gem::Requirement
@@ -154,7 +138,7 @@ dependencies:
154
138
  requirements:
155
139
  - - ~>
156
140
  - !ruby/object:Gem::Version
157
- version: 0.22.0
141
+ version: 0.60.2
158
142
  - !ruby/object:Gem::Dependency
159
143
  name: kramdown
160
144
  requirement: !ruby/object:Gem::Requirement
@@ -492,13 +476,13 @@ dependencies:
492
476
  - !ruby/object:Gem::Version
493
477
  version: 1.3.0
494
478
  - !ruby/object:Gem::Dependency
495
- name: oj
479
+ name: yajl-ruby
496
480
  requirement: !ruby/object:Gem::Requirement
497
481
  none: false
498
482
  requirements:
499
483
  - - ~>
500
484
  - !ruby/object:Gem::Version
501
- version: '1.4'
485
+ version: 1.1.0
502
486
  type: :runtime
503
487
  prerelease: false
504
488
  version_requirements: !ruby/object:Gem::Requirement
@@ -506,7 +490,7 @@ dependencies:
506
490
  requirements:
507
491
  - - ~>
508
492
  - !ruby/object:Gem::Version
509
- version: '1.4'
493
+ version: 1.1.0
510
494
  - !ruby/object:Gem::Dependency
511
495
  name: minitest
512
496
  requirement: !ruby/object:Gem::Requirement