sinator 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/CHANGELOG.md +46 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +33 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +126 -0
  9. data/bin/sinator +5 -0
  10. data/lib/sinator/command.rb +61 -0
  11. data/lib/sinator/generator.rb +106 -0
  12. data/lib/sinator/templates/Gemfile.erb +15 -0
  13. data/lib/sinator/templates/Rakefile.erb +33 -0
  14. data/lib/sinator/templates/app/routes/home.erb +6 -0
  15. data/lib/sinator/templates/app/views/home/index.erb +1 -0
  16. data/lib/sinator/templates/app/views/layout.erb +21 -0
  17. data/lib/sinator/templates/app.erb +71 -0
  18. data/lib/sinator/templates/assets/javascripts/app.js +2 -0
  19. data/lib/sinator/templates/assets/javascripts/main.js +1 -0
  20. data/lib/sinator/templates/assets/javascripts/plugins.js +24 -0
  21. data/lib/sinator/templates/assets/stylesheets/app.css.scss +1 -0
  22. data/lib/sinator/templates/assets/stylesheets/main.css.scss +8 -0
  23. data/lib/sinator/templates/config/application.rb +7 -0
  24. data/lib/sinator/templates/config/boot.rb +10 -0
  25. data/lib/sinator/templates/config/database.yml +8 -0
  26. data/lib/sinator/templates/config/puma/development.erb +7 -0
  27. data/lib/sinator/templates/config/puma/production.erb +16 -0
  28. data/lib/sinator/templates/config.ru.erb +5 -0
  29. data/lib/sinator/templates/db/migrations/000_example.rb +12 -0
  30. data/lib/sinator/templates/public/404.html +60 -0
  31. data/lib/sinator/templates/public/apple-touch-icon.png +0 -0
  32. data/lib/sinator/templates/public/browserconfig.xml +12 -0
  33. data/lib/sinator/templates/public/crossdomain.xml +15 -0
  34. data/lib/sinator/templates/public/favicon.ico +0 -0
  35. data/lib/sinator/templates/public/humans.txt +15 -0
  36. data/lib/sinator/templates/public/robots.txt +5 -0
  37. data/lib/sinator/templates/public/tile-wide.png +0 -0
  38. data/lib/sinator/templates/public/tile.png +0 -0
  39. data/lib/sinator/version.rb +3 -0
  40. data/lib/sinator.rb +1 -0
  41. data/sinator.gemspec +19 -0
  42. data/spec/fixtures/app_routes_home.txt +6 -0
  43. data/spec/fixtures/config/puma/development.txt +7 -0
  44. data/spec/fixtures/config/puma/production.txt +16 -0
  45. data/spec/fixtures/config_ru.txt +5 -0
  46. data/spec/fixtures/with_db/app.txt +50 -0
  47. data/spec/fixtures/with_db/gemfile.txt +13 -0
  48. data/spec/fixtures/with_db/rakefile.txt +32 -0
  49. data/spec/fixtures/without_db/app.txt +31 -0
  50. data/spec/fixtures/without_db/gemfile.txt +11 -0
  51. data/spec/fixtures/without_db/rakefile.txt +15 -0
  52. data/spec/helpers/generator.rb +46 -0
  53. data/spec/sinator/command_spec.rb +70 -0
  54. data/spec/sinator/generator_spec.rb +184 -0
  55. data/spec/sinator_spec.rb +1 -0
  56. data/spec/spec_helper.rb +29 -0
  57. metadata +128 -0
@@ -0,0 +1,16 @@
1
+ environment 'production'
2
+ bind 'unix:///path/to/shared/tmp/sockets/puma.sock'
3
+ pidfile '/path/to/shared/tmp/pids/puma.pid'
4
+ ctl_socket = '/path/to/shared/tmp/sockets/pumactl.sock'
5
+ state_path '/path/to/shared/tmp/sockets/puma.state'
6
+ activate_control_app 'unix:///path/to/shared/tmp/sockets/pumactl.sock'
7
+ daemonize
8
+ quiet
9
+
10
+ threads 5, 5
11
+ workers 2
12
+ preload_app!
13
+
14
+ before_fork do
15
+ <%= @app_class_name %>::DB.disconnect if defined?(<%= @app_class_name %>::DB)
16
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path('../config/boot.rb', __FILE__)
2
+ require Sinator::ROOT + '/<%= @app_name %>'
3
+ require Sinator::ROOT + '/config/application'
4
+
5
+ run <%= @app_class_name %>
@@ -0,0 +1,12 @@
1
+ # http://sequel.jeremyevans.net/rdoc/files/doc/migration_rdoc.html
2
+
3
+ # Sequel.migration do
4
+ # up do
5
+ # add_column :artists, :location, String
6
+ # from(:artists).update(:location=>'Sacramento')
7
+ # end
8
+ #
9
+ # down do
10
+ # drop_column :artists, :location
11
+ # end
12
+ # end
@@ -0,0 +1,60 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Page Not Found</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <style>
8
+
9
+ * {
10
+ line-height: 1.2;
11
+ margin: 0;
12
+ }
13
+
14
+ html {
15
+ color: #888;
16
+ display: table;
17
+ font-family: sans-serif;
18
+ height: 100%;
19
+ text-align: center;
20
+ width: 100%;
21
+ }
22
+
23
+ body {
24
+ display: table-cell;
25
+ vertical-align: middle;
26
+ margin: 2em auto;
27
+ }
28
+
29
+ h1 {
30
+ color: #555;
31
+ font-size: 2em;
32
+ font-weight: 400;
33
+ }
34
+
35
+ p {
36
+ margin: 0 auto;
37
+ width: 280px;
38
+ }
39
+
40
+ @media only screen and (max-width: 280px) {
41
+
42
+ body, p {
43
+ width: 95%;
44
+ }
45
+
46
+ h1 {
47
+ font-size: 1.5em;
48
+ margin: 0 0 0.3em;
49
+ }
50
+
51
+ }
52
+
53
+ </style>
54
+ </head>
55
+ <body>
56
+ <h1>Page Not Found</h1>
57
+ <p>Sorry, but the page you were trying to view does not exist.</p>
58
+ </body>
59
+ </html>
60
+ <!-- IE needs 512+ bytes: http://blogs.msdn.com/b/ieinternals/archive/2010/08/19/http-error-pages-in-internet-explorer.aspx -->
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Please read: http://msdn.microsoft.com/en-us/library/ie/dn455106.aspx -->
3
+ <browserconfig>
4
+ <msapplication>
5
+ <tile>
6
+ <square70x70logo src="tile.png"/>
7
+ <square150x150logo src="tile.png"/>
8
+ <wide310x150logo src="tile-wide.png"/>
9
+ <square310x310logo src="tile.png"/>
10
+ </tile>
11
+ </msapplication>
12
+ </browserconfig>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
3
+ <cross-domain-policy>
4
+ <!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
5
+
6
+ <!-- Most restrictive policy: -->
7
+ <site-control permitted-cross-domain-policies="none"/>
8
+
9
+ <!-- Least restrictive policy: -->
10
+ <!--
11
+ <site-control permitted-cross-domain-policies="all"/>
12
+ <allow-access-from domain="*" to-ports="*" secure="false"/>
13
+ <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
14
+ -->
15
+ </cross-domain-policy>
@@ -0,0 +1,15 @@
1
+ # humanstxt.org/
2
+ # The humans responsible & technology colophon
3
+
4
+ # TEAM
5
+
6
+ <name> -- <role> -- <twitter>
7
+
8
+ # THANKS
9
+
10
+ <name>
11
+
12
+ # TECHNOLOGY COLOPHON
13
+
14
+ HTML5, CSS3
15
+ jQuery, Modernizr
@@ -0,0 +1,5 @@
1
+ # www.robotstxt.org/
2
+
3
+ # Allow crawling of all content
4
+ User-agent: *
5
+ Disallow:
@@ -0,0 +1,3 @@
1
+ module Sinator
2
+ VERSION = '3.0.0'
3
+ end
data/lib/sinator.rb ADDED
@@ -0,0 +1 @@
1
+ # :)
data/sinator.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ require_relative 'lib/sinator/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'sinator'
5
+ s.version = Sinator::VERSION
6
+ s.date = Date.today.to_s
7
+ s.summary = "Sinatra application boilerplate generator"
8
+ s.description = "Sinator provides generator and contains minimal configuration to develop application with Sinatra"
9
+ s.author = 'Kunto Aji Kristianto'
10
+ s.email = 'kuntoaji@kaklabs.com'
11
+ s.files = `git ls-files -z`.split("\x0")
12
+ s.executables << 'sinator'
13
+ s.homepage = 'http://github.com/kuntoaji/sinator'
14
+ s.license = 'MIT'
15
+
16
+ s.required_ruby_version = '>= 2.1'
17
+ s.add_development_dependency 'bundler', '~> 1.7'
18
+ s.add_development_dependency 'rspec', '3.2.0'
19
+ end
@@ -0,0 +1,6 @@
1
+ class MyApp
2
+ get '/' do
3
+ @home = "Hello World from app/routes/home.rb"
4
+ erb :"home/index"
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ threads 4, 4
2
+ workers 2
3
+ preload_app!
4
+
5
+ before_fork do
6
+ MyApp::DB.disconnect if defined?(MyApp::DB)
7
+ end
@@ -0,0 +1,16 @@
1
+ environment 'production'
2
+ bind 'unix:///path/to/shared/tmp/sockets/puma.sock'
3
+ pidfile '/path/to/shared/tmp/pids/puma.pid'
4
+ ctl_socket = '/path/to/shared/tmp/sockets/pumactl.sock'
5
+ state_path '/path/to/shared/tmp/sockets/puma.state'
6
+ activate_control_app 'unix:///path/to/shared/tmp/sockets/pumactl.sock'
7
+ daemonize
8
+ quiet
9
+
10
+ threads 5, 5
11
+ workers 2
12
+ preload_app!
13
+
14
+ before_fork do
15
+ MyApp::DB.disconnect if defined?(MyApp::DB)
16
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path('../config/boot.rb', __FILE__)
2
+ require Sinator::ROOT + '/my_app'
3
+ require Sinator::ROOT + '/config/application'
4
+
5
+ run MyApp
@@ -0,0 +1,50 @@
1
+ require 'yaml'
2
+
3
+ class MyApp < Sinatra::Application
4
+ use Rack::Session::EncryptedCookie,
5
+ secret: 'supersecretcookiefromgenerator'
6
+
7
+ set :app_file, __FILE__
8
+ set :server, :puma
9
+ set :views, Proc.new { File.join(root, "app/views") }
10
+ set :assets, Sprockets::Environment.new
11
+ set :assets_manifest, %w(app.js app.css)
12
+ use Rack::Csrf, raise: true
13
+
14
+ configure do
15
+ Sequel::Database.extension :pagination
16
+ Sequel::Model.plugin :timestamps
17
+ Sequel::Model.plugin :auto_validations,
18
+ not_null: :presence, unique_opts: { only_if_modified: true }
19
+
20
+ assets.append_path 'assets/stylesheets'
21
+ assets.append_path 'assets/javascripts'
22
+ end
23
+
24
+ configure :development do
25
+ require 'sinatra/reloader'
26
+ require 'logger'
27
+
28
+ register Sinatra::Reloader
29
+ Sequel.connect YAML.load_file(File.expand_path("../config/database.yml", __FILE__))['development'],
30
+ loggers: [Logger.new($stdout)]
31
+
32
+ get '/assets/*' do
33
+ env['PATH_INFO'].sub!('/assets', '')
34
+ settings.assets.call(env)
35
+ end
36
+ end
37
+
38
+ configure :test do
39
+ Sequel.connect YAML.load_file(File.expand_path("../config/database.yml", __FILE__))['test']
40
+ end
41
+
42
+ configure :production do
43
+ # Serve assets via Nginx or Apache
44
+ disable :static
45
+
46
+ assets.js_compressor = :uglify
47
+ assets.css_compressor = :sass
48
+ Sequel.connect YAML.load_file(File.expand_path("../config/database.yml", __FILE__))['production']
49
+ end
50
+ end
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sinatra', '2.0.0'
4
+ gem 'sinatra-contrib', '2.0.0', require: false
5
+ gem 'encrypted_cookie', '0.0.5'
6
+ gem 'rack_csrf', '2.6.0', require: 'rack/csrf'
7
+ gem 'puma', '3.11.0'
8
+ gem 'tux', '0.3.0', require: false
9
+ gem 'uglifier', '4.1.3', require: false
10
+ gem 'sass', '3.5.5', require: false
11
+ gem 'sprockets', '3.7.1'
12
+ gem 'sequel', '5.4.0'
13
+ gem 'sequel_pg', '1.8.1', require: 'sequel'
@@ -0,0 +1,32 @@
1
+ require_relative 'config/boot'
2
+ require_relative 'my_app'
3
+
4
+ namespace :assets do
5
+ desc "Precompile assets"
6
+ task :precompile do
7
+ manifest = ::Sprockets::Manifest.new(MyApp.assets.index, "#{MyApp.public_folder}/assets")
8
+ manifest.compile(MyApp.assets_manifest)
9
+ end
10
+
11
+ desc "Clean assets"
12
+ task :clean do
13
+ FileUtils.rm_rf("#{MyApp.public_folder}/assets")
14
+ end
15
+ end
16
+
17
+ namespace :db do
18
+ desc "Run migrations"
19
+ task :migrate, [:version] do |t, args|
20
+ Sequel.extension :migration
21
+ db = Sequel.connect(YAML.load_file("#{Sinator::ROOT}/config/database.yml")[ENV['APP_ENV']])
22
+ migration_path = "#{Sinator::ROOT}/db/migrations"
23
+
24
+ if args[:version]
25
+ puts "Migrating to version #{args[:version]}"
26
+ Sequel::Migrator.run(db, migration_path, target: args[:version].to_i)
27
+ else
28
+ puts "Migrating to latest"
29
+ Sequel::Migrator.run(db, migration_path)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ class MyApp < Sinatra::Application
2
+ use Rack::Session::EncryptedCookie,
3
+ secret: 'supersecretcookiefromgenerator'
4
+
5
+ set :app_file, __FILE__
6
+ set :server, :puma
7
+ set :views, Proc.new { File.join(root, "app/views") }
8
+ set :assets, Sprockets::Environment.new
9
+ set :assets_manifest, %w(app.js app.css)
10
+ use Rack::Csrf, raise: true
11
+
12
+ configure do
13
+ assets.append_path 'assets/stylesheets'
14
+ assets.append_path 'assets/javascripts'
15
+ end
16
+
17
+ configure :development do
18
+ get '/assets/*' do
19
+ env['PATH_INFO'].sub!('/assets', '')
20
+ settings.assets.call(env)
21
+ end
22
+ end
23
+
24
+ configure :production do
25
+ # Serve assets via Nginx or Apache
26
+ disable :static
27
+
28
+ assets.js_compressor = :uglify
29
+ assets.css_compressor = :sass
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sinatra', '2.0.0'
4
+ gem 'sinatra-contrib', '2.0.0', require: false
5
+ gem 'encrypted_cookie', '0.0.5'
6
+ gem 'rack_csrf', '2.6.0', require: 'rack/csrf'
7
+ gem 'puma', '3.11.0'
8
+ gem 'tux', '0.3.0', require: false
9
+ gem 'uglifier', '4.1.3', require: false
10
+ gem 'sass', '3.5.5', require: false
11
+ gem 'sprockets', '3.7.1'
@@ -0,0 +1,15 @@
1
+ require_relative 'config/boot'
2
+ require_relative 'my_app'
3
+
4
+ namespace :assets do
5
+ desc "Precompile assets"
6
+ task :precompile do
7
+ manifest = ::Sprockets::Manifest.new(MyApp.assets.index, "#{MyApp.public_folder}/assets")
8
+ manifest.compile(MyApp.assets_manifest)
9
+ end
10
+
11
+ desc "Clean assets"
12
+ task :clean do
13
+ FileUtils.rm_rf("#{MyApp.public_folder}/assets")
14
+ end
15
+ end
@@ -0,0 +1,46 @@
1
+ module Helper
2
+ module Generator
3
+ def expect_file_eq(file, expected_file)
4
+ file_content = File.read(file)
5
+ expected_file_content = File.read(expected_file)
6
+
7
+ expect(File.exists?(file)).to be_truthy
8
+ expect(file_content).to eq(expected_file_content)
9
+ end
10
+
11
+ def expected_default_files(target_dir, expected_value)
12
+ config_dir = "#{target_dir}/config"
13
+ assets_dir = "#{target_dir}/assets"
14
+ public_dir = "#{target_dir}/public"
15
+ boot = "#{config_dir}/boot.rb"
16
+ application = "#{config_dir}/application.rb"
17
+
18
+ app_dir = "#{target_dir}/app"
19
+ routes_dir = "#{target_dir}/app/routes"
20
+ views_dir = "#{target_dir}/app/views"
21
+ layout = "#{target_dir}/app/views/layout.erb"
22
+ home_index = "#{target_dir}/app/views/home/index.erb"
23
+
24
+ expect(File.exists?(config_dir)).to eq(expected_value)
25
+ expect(File.exists?("#{config_dir}/boot.rb")).to eq(expected_value)
26
+ expect(File.exists?("#{config_dir}/application.rb")).to eq(expected_value)
27
+ expect(File.exists?(assets_dir)).to eq(expected_value)
28
+ expect(File.exists?(public_dir)).to eq(expected_value)
29
+
30
+ expect(Dir.exists?(app_dir)).to eq(expected_value)
31
+ expect(Dir.exists?(routes_dir)).to eq(expected_value)
32
+ expect(Dir.exists?(views_dir)).to eq(expected_value)
33
+ expect(File.exists?(layout)).to eq(expected_value)
34
+ expect(File.exists?(home_index)).to eq(expected_value)
35
+ end
36
+
37
+ def expected_generated_files_with_db(target_dir, expected_value)
38
+ sample_migration = "#{target_dir}/db/migrations/000_example.rb"
39
+
40
+ expect(Dir.exists?("#{target_dir}/app/models")).to eq(expected_value)
41
+ expect(File.exists?("#{target_dir}/config/database.yml")).to eq(expected_value)
42
+ expect(File.exists?(sample_migration)).to eq(expected_value)
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,70 @@
1
+ require_relative '../../lib/sinator/command'
2
+
3
+ describe Sinator::Command do
4
+
5
+ describe "parse" do
6
+ def remove_existing_app_if_exists
7
+ FileUtils.rm_r "my_app" if Dir.exists?("my_app")
8
+ FileUtils.rm_r "/tmp/my_app" if Dir.exists?("/tmp/my_app")
9
+ end
10
+
11
+ before do
12
+ remove_existing_app_if_exists
13
+ end
14
+
15
+ after :all do
16
+ remove_existing_app_if_exists
17
+ end
18
+
19
+ it "has --help option" do
20
+ help = Sinator::Command.parse %w(--help)
21
+
22
+ expect(help).to include "Usage: sinator [options]"
23
+ expect(help).to include "Print this help"
24
+ end
25
+
26
+ it "has --version option" do
27
+ version = Sinator::Command.parse %w(--version)
28
+
29
+ expect(version).to include Sinator::VERSION
30
+ end
31
+
32
+ it "has --name option as required option to generate application" do
33
+ app = Sinator::Command.parse %w(--name my_app)
34
+
35
+ expect(app).to include "my_app is successfully generated"
36
+ end
37
+
38
+ it "has --target option as target directory" do
39
+ app = Sinator::Command.parse %w(-n my_app --target /tmp)
40
+
41
+ expect(app).to include "my_app is successfully generated in /tmp"
42
+ expect(Dir.exists?("/tmp/my_app")).to be_truthy
43
+ end
44
+
45
+ it "has --database option" do
46
+ app = Sinator::Command.parse %w(-n my_app --target /tmp -d)
47
+
48
+ expect(app).to include "my_app is successfully generated in /tmp"
49
+ expect(Dir.exists?("/tmp/my_app/db")).to be_truthy
50
+ end
51
+
52
+ context "when has no --name option and only --target option" do
53
+ it "does nothing" do
54
+ app = Sinator::Command.parse %w(--target /tmp/sinator)
55
+
56
+ expect(app).to be_nil
57
+ end
58
+ end
59
+
60
+ context "when has no option" do
61
+ it "uses --help option by default" do
62
+ help = Sinator::Command.parse []
63
+
64
+ expect(help).to include "Usage: sinator [options]"
65
+ expect(help).to include "Print this help"
66
+ end
67
+ end
68
+ end
69
+
70
+ end