snfn 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ # gem "shoulda", ">= 0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.6.4"
12
+ # gem "rcov", ">= 0"
13
+ end
14
+
15
+ gem "thor"
data/Gemfile.lock ADDED
@@ -0,0 +1,18 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.4)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rake (0.9.2)
10
+ thor (0.14.6)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ bundler (~> 1.0.0)
17
+ jeweler (~> 1.6.4)
18
+ thor
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Zach Pendleton
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.mdown ADDED
@@ -0,0 +1,80 @@
1
+ # Snfn - A Sinatra application generator
2
+
3
+ Snfn is an opinionated generator for Sinatra projects. It
4
+ can be configured using the following options:
5
+
6
+ * -d : Database. Options are "postgres," "mysql," "sqlite",
7
+ and "mongo." Default is "sqlite."
8
+ * --redis : Include Redis configuration options.
9
+ * --no-database : Don't include any database config options.
10
+ * --no-heroku : Don't include Heroku config options.
11
+
12
+ ## Installation
13
+
14
+ gem install snfn
15
+
16
+ ## Example
17
+
18
+ Standard Heroku app, using sqlite for local development and
19
+ PostgreSQL for production.
20
+
21
+ snfn new my_app
22
+
23
+ App without Heroku options and mysql config.
24
+
25
+ snfn new my_app -d mysql --no-heroku
26
+
27
+ ## Architecture
28
+
29
+ The template autoloads files in config/initializers and
30
+ /lib. Database configuration options are stored in `config/db.yml`
31
+ and are loaded via `config/initializers/database.rb`.
32
+
33
+ Right now Snfn only supports Unicorn as a server, with the config
34
+ stored at config/unicorn.rb.
35
+
36
+ ## DB Setup
37
+
38
+ Sequel is used as an ORM for relational databases,
39
+ and migrations are stored in db/migrate. Migrations can be
40
+ run using the rake command `rake migrate`.
41
+
42
+ MongoMapper is used for Mongo apps, with the config options
43
+ stored in the same files as relational databases (`config/db.yml`
44
+ and `config/initializers/database.rb`).
45
+
46
+ ## Set up on Heroku
47
+
48
+ By default, Snfn creates an app with the proper options for deployment
49
+ on Heroku. To get Snfn up and running on Heroku:
50
+
51
+ 1. Install your gems with `bundle install`
52
+ 2. Create a new git repository: `git init .`
53
+ 3. Make your first commit: `git add .; git commit -m "initial commit"`
54
+ 4. Create a new heroku app: `bundle exec heroku create --stack cedar`
55
+ 5. Deploy the app: `git push heroku master`
56
+
57
+ ### Heroku Add-Ons
58
+
59
+ To use PostgreSQL, MongoDB, or Redis on Heroku, you'll need to add
60
+ the proper Heroku add-ons. The commands to do this are, respectively:
61
+
62
+ heroku addons:add shared_database # PostgreSQL
63
+ heroku addons:add mongolab:starter: # MongoDB
64
+ heroku addons:add redistogo:nano # Redis
65
+
66
+ ## Contributing to snfn
67
+
68
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
69
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
70
+ * Fork the project
71
+ * Start a feature/bugfix branch
72
+ * Commit and push until you are happy with your contribution
73
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
74
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
75
+
76
+ ## Copyright
77
+
78
+ Copyright (c) 2011 Zach Pendleton. See LICENSE.txt for
79
+ further details.
80
+
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "snfn"
18
+ gem.homepage = "http://github.com/zachpendleton/snfn"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{A Heroku-friendy Sinatra app generator}
21
+ gem.description = %Q{An app generator for Sinatra apps with an eye towards easy Heroku setup and deployment.}
22
+ gem.email = "zachpendleton@gmail.com"
23
+ gem.authors = ["Zach Pendleton"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "snfn #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/snfn ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
4
+ %w{rubygems extensions/string thor}.each do |lib|
5
+ require lib
6
+ end
7
+
8
+ class SnfnGenerator < Thor
9
+ include Thor::Actions
10
+
11
+ desc "new NAME", "Creates new Snfn application"
12
+ method_option :database, :aliases => "-d", :default => "postgres", :desc => "The type of database to use. Values are \"sqlite\", \"postgres\", \"mysql\", and \"mongo\". Default is \"postgres\"."
13
+ method_option :no_heroku, :type => :boolean, :desc => "Include Heroku configuration options."
14
+ method_option :no_database, :type => :boolean, :desc => "Do not use any database."
15
+ method_option :redis, :type => :boolean, :desc => "Include Redis configuration options."
16
+ def new(name)
17
+ @name = @app_path = name.file_name
18
+ @database = options[:database]
19
+ @no_database = options[:no_database]
20
+ @redis = options[:redis]
21
+ @no_heroku = options[:no_heroku]
22
+
23
+ create_directories
24
+ add_templates
25
+ end
26
+
27
+ def self.source_root
28
+ File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "templates"))
29
+ end
30
+
31
+ protected
32
+ def create_directories
33
+ %w{config/initializers db/migrate lib log tmp}.each do |dir|
34
+ add_app_directory dir
35
+ end
36
+
37
+ %w{public/css public/js public/img views}.each do |dir|
38
+ directory dir, File.join(@app_path, dir)
39
+ end
40
+ end
41
+
42
+ def add_templates
43
+ copy_template "app.rb", "#{@name}.rb"
44
+ copy_template "config.ru"
45
+ copy_template "Gemfile"
46
+ copy_static "Procfile" unless @no_heroku
47
+ copy_static "Rakefile"
48
+ copy_static "README.mdown"
49
+ copy_template "config/unicorn.rb"
50
+
51
+ copy_static "config/redis.yml" if @redis
52
+ copy_template "config/db.yml" unless @no_database
53
+ copy_template "config/initializers/database.rb"
54
+ end
55
+
56
+ def add_app_directory(name)
57
+ empty_directory(File.join(@app_path, name))
58
+ end
59
+
60
+ def copy_template(name, new_name = nil)
61
+ new_name ||= name
62
+ template name, File.join(@app_path, new_name)
63
+ end
64
+
65
+ def copy_static(name)
66
+ copy_file name, File.join(@app_path, name)
67
+ end
68
+ end
69
+
70
+ SnfnGenerator.start
71
+
@@ -0,0 +1,35 @@
1
+ module Snfn
2
+ module Extensions
3
+ module String
4
+ def camel_case
5
+ return self if !match(/_/)
6
+ altered_self = self.capitalize
7
+ altered_self.scan(/_[a-zA-Z]/).each do |match|
8
+ altered_self.gsub!(match, match[1].upcase)
9
+ end
10
+
11
+ altered_self
12
+ end
13
+
14
+ def camel_case!
15
+ self.replace camel_case
16
+ end
17
+
18
+ def file_name
19
+ return self if !match(/[A-Z]/)
20
+ altered_self = self.strip
21
+ altered_self.scan(/[A-Z]/).each do |match|
22
+ altered_self.gsub!(match, "_#{match.downcase}")
23
+ end
24
+
25
+ altered_self.sub(/^_/, "")
26
+ end
27
+
28
+ def file_name!
29
+ self.replace file_name
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ String.send(:include, Snfn::Extensions::String)
data/lib/snfn.rb ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,48 @@
1
+ source "http://rubygems.org"
2
+
3
+ # App Stack
4
+ <% if !@no_heroku -%>
5
+ gem "foreman"
6
+ gem "heroku"
7
+ <% end -%>
8
+ gem "sinatra"
9
+ gem "unicorn"
10
+
11
+ <% unless @no_database -%>
12
+ # Database Stack
13
+ <% unless @database == 'mongo' -%>
14
+ gem "sequel"
15
+ <% end -%>
16
+ <% if @database == "sqlite" -%>
17
+ <% if !@no_heroku -%>
18
+ group :development, :test do
19
+ gem "sqlite3"
20
+ end
21
+ <% else -%>
22
+ gem "sqlite3"
23
+ <% end -%>
24
+ <% elsif @database == "postgres" -%>
25
+ gem "pg"
26
+ <% elsif @database == "mysql" -%>
27
+ <% if !@no_heroku -%>
28
+ group :development, :test do
29
+ gem "mysql2"
30
+ end
31
+ <% else -%>
32
+ gem "mysql2"
33
+ <% end -%>
34
+ <% elsif @database == "mongo" -%>
35
+ gem "bson_ext"
36
+ gem "mongo_mapper"
37
+ <% end -%>
38
+ <% if !@no_heroku && @database != "postgres" && @database != "mongo" -%>
39
+ group :production do
40
+ gem "pg"
41
+ end
42
+ <% end -%>
43
+ <% if @redis -%>
44
+ # Redis
45
+ gem "redis"
46
+ <% end -%>
47
+ <% end -%>
48
+
@@ -0,0 +1 @@
1
+ web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
@@ -0,0 +1,60 @@
1
+ # Snfn - A Sinatra application generator
2
+
3
+ Snfn is an opinionated generator for Sinatra projects. It
4
+ can be configured using the following options:
5
+
6
+ * -d : Database. Options are "postgres," "mysql," "sqlite",
7
+ and "mongo." Default is "sqlite."
8
+ * --redis : Include Redis configuration options.
9
+ * --no-database : Don't include any database config options.
10
+ * --no-heroku : Don't include Heroku config options.
11
+
12
+ ## Example
13
+
14
+ Standard Heroku app, using sqlite for local development and
15
+ PostgreSQL for production.
16
+
17
+ snfn new my_app
18
+
19
+ App without Heroku options and mysql config.
20
+
21
+ snfn new my_app -d mysql --no-heroku
22
+
23
+ ## Architecture
24
+
25
+ The template autoloads files in config/initializers and
26
+ /lib. Database configuration options are stored in `config/db.yml`
27
+ and are loaded via `config/initializers/database.rb`.
28
+
29
+ Right now Snfn only supports Unicorn as a server, with the config
30
+ stored at config/unicorn.rb.
31
+
32
+ ## DB Setup
33
+
34
+ Sequel is used as an ORM for relational databases,
35
+ and migrations are stored in db/migrate. Migrations can be
36
+ run using the rake command `rake migrate`.
37
+
38
+ MongoMapper is used for Mongo apps, with the config options
39
+ stored in the same files as relational databases (`config/db.yml`
40
+ and `config/initializers/database.rb`).
41
+
42
+ ## Set up on Heroku
43
+
44
+ By default, Snfn creates an app with the proper options for deployment
45
+ on Heroku. To get Snfn up and running on Heroku:
46
+
47
+ 1. Install your gems with `bundle install`
48
+ 2. Create a new git repository: `git init .`
49
+ 3. Make your first commit: `git add .; git commit -m "initial commit"`
50
+ 4. Create a new heroku app: `bundle exec heroku create --stack cedar`
51
+ 5. Deploy the app: `git push heroku master`
52
+
53
+ ### Heroku Add-Ons
54
+
55
+ To use PostgreSQL, MongoDB, or Redis on Heroku, you'll need to add
56
+ the proper Heroku add-ons. The commands to do this are, respectively:
57
+
58
+ heroku addons:add shared_database # PostgreSQL
59
+ heroku addons:add mongolab:starter: # MongoDB
60
+ heroku addons:add redistogo:nano # Redis
@@ -0,0 +1,20 @@
1
+ %w{ rubygems bundler find}.each { |lib| require lib }
2
+
3
+ namespace :db do
4
+ desc "Run all migrations in db/migrate"
5
+ task :migrate => :connect do
6
+ Sequel.extension(:migration)
7
+ Sequel::Migrator.apply(DB, "db/migrate")
8
+ end
9
+
10
+ task :connect => :environment do
11
+ require "./config/initializers/database"
12
+ end
13
+ end
14
+
15
+ task :environment, [:env] do |cmd, args|
16
+ Bundler.require
17
+ ENV['RACK_ENV'] = args[:env] || "development"
18
+ Find.find("lib") { |f| require f unless f.match(/\/\..+$/) || File.directory?(f) }
19
+ end
20
+
@@ -0,0 +1,11 @@
1
+ class <%= @name.camel_case %> < Sinatra::Base
2
+
3
+ set :public => "public", :static => true
4
+
5
+ get "/" do
6
+ @version = RUBY_VERSION
7
+ @environment = ENV['RACK_ENV']
8
+
9
+ erb :welcome
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ # Sequel Database Configuration
2
+ <% if @database == "sqlite" %>
3
+ development: "sqlite://db/development.sqlite3"
4
+ test: "sqlite://db/test.sqlite3"
5
+ production: "sqlite://db/production.sqlite3"
6
+ <% elsif @database == "postgres" %>
7
+ development: "postgres://<%= `whoami`.chop %>@localhost/<%= @name %>_development"
8
+ test: "postgres://<%= `whoami`.chop %>@localhost/<%= @name %>_test"
9
+ production: "postgres://<%= `whoami`.chop %>@localhost/<%= @name %>_production"
10
+ <% elsif @database == "mysql" %>
11
+ development: "mysql2://<%= `whoami`.chop %>@localhost/<%= @name %>_development"
12
+ test: "mysql2://<%= `whoami`.chop %>@localhost/<%= @name %>_test"
13
+ production: "mysql2://<%= `whoami`.chop %>@localhost/<%= @name %>_production"
14
+ <% elsif @database == "mongo" %>
15
+ development:
16
+ host: localhost
17
+ port: 27017
18
+ database: <%= @name %>_development
19
+ username:
20
+ password:
21
+
22
+ test:
23
+ host: localhost
24
+ port: 27017
25
+ database: <%= @name %>_test
26
+ username:
27
+ password:
28
+
29
+ production:
30
+ host: localhost
31
+ port: 27017
32
+ database: <%= @name %>_production
33
+ username:
34
+ password:
35
+ <% end %>
@@ -0,0 +1,27 @@
1
+ <% unless @no_database -%>
2
+ settings = YAML::load_file("config/db.yml")
3
+ <% if @database != 'mongo' -%>
4
+ # Sequel Configuration
5
+ DB = Sequel.connect(<% if !@no_heroku %>ENV['DATABASE_URL'] || <% end %>settings[ENV['RACK_ENV']])
6
+ <% else -%>
7
+ # MongoMapper Configuration
8
+ <% if !@no_heroku -%>
9
+ settings[ENV['RACK_ENV']]["uri"] = ENV['MONGOLAB_URI']
10
+ <% end -%>
11
+ MongoMapper.config = settings
12
+ MongoMapper.connect(ENV['RACK_ENV'])
13
+ <% end -%>
14
+
15
+ <% end -%>
16
+ <% if @redis -%>
17
+ # Redis Configuration
18
+ if ENV['REDISTOGO_URL']
19
+ require "uri"
20
+ uri = URI.parse(ENV['REDISTOGO_URL'])
21
+ REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
22
+ else
23
+ redis_settings = YAML::load_file("config/redis.yml")
24
+ REDIS = Redis.new(redis_settings[ENV['RACK_ENV']])
25
+ end
26
+ <% end -%>
27
+
@@ -0,0 +1,14 @@
1
+ development:
2
+ host: localhost
3
+ port: 6387
4
+ password:
5
+
6
+ test:
7
+ host: localhost
8
+ port: 6387
9
+ password:
10
+
11
+ production:
12
+ host: localhost
13
+ port: 6387
14
+ password:
@@ -0,0 +1,12 @@
1
+ worker_processes 3
2
+ timeout 30
3
+
4
+ <% if @noheroku -%>
5
+ docroot = File.join(File.expand_path(File.dirname(__FILE__)), "..")
6
+
7
+ listen "#{docroot}/tmp/sockets/unicorn.sock"
8
+ pid "#{docroot}/tmp/pids/unicorn.pid"
9
+
10
+ stderr_path "#{docroot}/log/stderr.log"
11
+ stdout_path "#{docroot}/log/stdout.log"
12
+ <% end -%>
@@ -0,0 +1,15 @@
1
+ # Load path and gems/bundler
2
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
3
+ require "rubygems"
4
+ require "bundler"
5
+ Bundler.require
6
+
7
+ # Local config
8
+ require "find"
9
+ %w{config/initializers lib}.each do |load_path|
10
+ Find.find(load_path) { |f| require f unless f.match(/\/\..+$/) || File.directory?(f) }
11
+ end
12
+
13
+ # Load app
14
+ require "<%= @name %>"
15
+ run <%= @name.camel_case %>
@@ -0,0 +1,87 @@
1
+ @media screen {
2
+ /* --- Reset Styles --- */
3
+ * {
4
+ list-style: none;
5
+ margin: 0;
6
+ padding: 0;
7
+ }
8
+
9
+ html, body {
10
+ height: 100%;
11
+ width: 100%;
12
+ }
13
+
14
+ /* --- Welcome Page Styles --- */
15
+ body {
16
+ background: #eee;
17
+ color: #333;
18
+ font-family: Sans-Serif;
19
+ line-height: 18px;
20
+ }
21
+
22
+ .wrapper {
23
+ background: #fff;
24
+ -moz-box-shadow: 0 0 10px rgba(0,0,0,.3);
25
+ -webkit-box-shadow: 0 0 10px rgba(0,0,0,.3);
26
+ box-shadow: 0 0 10px rgba(0,0,0,.3);
27
+ margin: 20px auto;
28
+ padding: 18px;
29
+ width: 764px;
30
+ }
31
+
32
+ h1 {
33
+ font-size: 36px;
34
+ line-height: 54px;
35
+ }
36
+
37
+ h2 {
38
+ border-bottom: 2px solid #ccc;
39
+ font-size: 24px;
40
+ line-height: 36px;
41
+ margin-bottom: 16px;
42
+ }
43
+
44
+ h3 {
45
+ font-size: 18px;
46
+ line-height: 36px;
47
+ }
48
+
49
+ p {
50
+ margin-bottom: 18px;
51
+ }
52
+
53
+ .main {
54
+ overflow: hidden;
55
+ }
56
+
57
+ .content {
58
+ float: left;
59
+ width: 480px;
60
+ }
61
+
62
+ .sidebar {
63
+ background: #eee;
64
+ border: 1px solid #ccc;
65
+ float: right;
66
+ padding: 9px;
67
+ width: 240px;
68
+ }
69
+
70
+ .sidebar ul {
71
+ font-size: 14px;
72
+ }
73
+
74
+ .branding {
75
+ clear: both;
76
+ }
77
+
78
+ footer.branding {
79
+ border-top: 2px solid #ccc;
80
+ margin-top: 20px;
81
+ padding-top: 20px;
82
+ }
83
+ }
84
+
85
+ @media print {
86
+
87
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Application-specific JavaScript goes here.
3
+ *
4
+ */