suspenders 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -22,7 +22,7 @@ make the change in suspenders instead of your project. Note: If you don't
22
22
  have commit access to suspenders, create a github ticket and we'll review your
23
23
  suggestion.
24
24
 
25
- Once that's committed, you can pull into your project to get all the changes
25
+ Once that's committed, you can pull into your project to get all the changes
26
26
  that have been made in suspenders since your last pull:
27
27
 
28
28
  git pull suspenders master
@@ -63,6 +63,7 @@ Basic user auth:
63
63
 
64
64
  For testing:
65
65
 
66
+ rspec
66
67
  jferris-mocha (standard mocha plus test spies)
67
68
  factory_girl (fixture replacement for test data)
68
69
  shoulda (rails test helpers and context framework)
@@ -84,7 +85,7 @@ Initializers (in config/initializers)
84
85
 
85
86
  hoptoad.rb
86
87
  Get your API key at http://hoptoadapp.com
87
-
88
+
88
89
  requires.rb
89
90
  Automatically requires everything in
90
91
  lib/
@@ -95,7 +96,7 @@ Initializers (in config/initializers)
95
96
  time_formats.rb
96
97
  Two time formats are available by default, :short_date and :long_date.
97
98
  Add other time formats here.
98
-
99
+
99
100
  Rake Tasks
100
101
  ----------
101
102
 
@@ -104,25 +105,20 @@ Rake tasks are contained in the limerick_rake gem.
104
105
  bootstrap
105
106
  Provides rake tasks for loading data into the database. These are used for
106
107
  an initial application dataset needed for production.
107
-
108
+
108
109
  capistrano
109
110
  Standard capistrano deployment tasks
110
-
111
+
111
112
  Testing
112
113
  -------
113
114
 
114
- Testing is done utilizing Test::Unit, Shoulda, factory_girl, and mocha.
115
+ Testing is done utilizing RSpec, Shoulda, factory_girl, and mocha.
115
116
 
116
117
  factory_girl is a fixture replacement library, following the factory pattern.
117
118
  Place your factories in test/factories.rb. The fixture directory has been
118
119
  removed, as fixtures are not used.
119
120
 
120
- Shoulda is a pragmatic testing framework for TDD and BDD built on top of
121
- Test::Unit. A number of additional testing macros are provided in
122
- test/shoulda_macros:
123
-
124
- shoulda_have_form
125
- shoulda_paginate_collection
121
+ Shoulda matchers are used on top of RSpec.
126
122
 
127
123
  Timecop is used to freeze the time for the entire test suite. It is frozen to
128
124
  the value of Time.now; that is, the time that the tests suite starts running.
@@ -152,7 +148,7 @@ Setup your deployment environment by running:
152
148
  Deploy to the desired environment by running:
153
149
 
154
150
  cap ENVIRONMENT deploy
155
-
151
+
156
152
  The default environment for deploy is staging, to deploy to staging, just run:
157
153
 
158
154
  cap deploy
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'cucumber/rake/task'
4
4
  require 'date'
5
5
 
6
6
  TEST_PROJECT = 'test_project'
7
- SUSPENDERS_GEM_VERSION = '0.0.2'
7
+ SUSPENDERS_GEM_VERSION = '0.0.3'
8
8
 
9
9
  #############################################################################
10
10
  #
@@ -16,17 +16,18 @@ Cucumber::Rake::Task.new
16
16
 
17
17
  namespace :test do
18
18
  desc "A full suspenders app's test suite"
19
- task :full => ['generate:suspenders', 'generate:finish', 'cucumber', 'destroy:suspenders']
19
+ task :full => ['generate', 'cucumber', 'destroy:suspenders']
20
20
  end
21
21
 
22
+ task :generate => ['generate:finish']
22
23
  namespace :generate do
23
- desc 'Suspend a new project'
24
+ desc 'Suspend a new project. Pass REPO=... to change the Suspenders repo.'
24
25
  task :suspenders do
25
- sh './bin/suspenders', 'create', TEST_PROJECT
26
+ sh './bin/suspenders', 'create', TEST_PROJECT, ENV['REPO'].to_s
26
27
  end
27
28
 
28
29
  desc 'Finishing touches'
29
- task :finish do
30
+ task :finish => ['suspenders'] do
30
31
  open(File.join(TEST_PROJECT, 'config', 'environments', 'cucumber.rb'), 'a') do |f|
31
32
  f.puts "config.action_mailer.default_url_options = { :host => 'localhost:3000' }"
32
33
  end
@@ -42,6 +43,10 @@ end
42
43
  namespace :destroy do
43
44
  desc 'Remove a suspended project'
44
45
  task :suspenders do
46
+ FileUtils.cd TEST_PROJECT
47
+ sh "rake db:drop RAILS_ENV=development"
48
+ sh "rake db:drop RAILS_ENV=test"
49
+ FileUtils.cd '..'
45
50
  FileUtils.rm_rf TEST_PROJECT
46
51
  end
47
52
  end
data/bin/suspenders CHANGED
@@ -1,80 +1,23 @@
1
1
  #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'active_support'
4
- require 'pathname'
5
- require 'digest/md5'
6
2
 
7
- ### currently the only thing you can do is create. So we ignore the first argument
8
- project_name = ARGV[1]
9
- fail("Usage: #{File.basename(__FILE__)} create new_project_name") unless project_name
10
- fail("Project name must only contain [a-z0-9_]") unless project_name =~ /^[a-z0-9_]+$/
3
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/create")
4
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/errors")
11
5
 
12
- base_directory = Dir.pwd
13
- project_directory = File.join(base_directory, project_name)
14
- fail("Project directory (#{project_directory}) already exists") if File.exists?(project_directory)
6
+ include Suspenders::Errors
15
7
 
16
- template_url = "git://github.com/thoughtbot/suspenders.git"
17
- changeme = "CHANGEME"
18
- changesession = "CHANGESESSION"
19
-
20
- def run(cmd)
21
- puts "Running '#{cmd}'"
22
- out = `#{cmd}`
23
- if $? != 0
24
- fail "Command #{cmd} failed: #$?\n#{out}"
25
- end
26
- out
8
+ def usage
9
+ "Usage: #{File.basename(__FILE__)} create new_project_name"
27
10
  end
28
11
 
29
- def search_and_replace(file, search, replace)
30
- if File.file?(file)
31
- contents = File.read(file)
32
- if contents[search]
33
- puts "Replacing #{search} with #{replace} in #{file}"
34
- contents.gsub!(search, replace)
35
- File.open(file, "w") { |f| f << contents }
36
- end
12
+ case ARGV[0]
13
+ when 'create', '--create'
14
+ begin
15
+ Suspenders::Create.run!(ARGV[1], ARGV[2])
16
+ rescue Suspenders::InvalidInput => e
17
+ error_with_message(e.message)
37
18
  end
19
+ when 'help', '--help'
20
+ puts usage
21
+ else
22
+ error_with_message "Unknown subcommand: #{ARGV[0]}\n#{usage}"
38
23
  end
39
-
40
- def installed?(gem_name)
41
- installed_gems = Gem.source_index.find_name(gem_name)
42
- installed_gems.any?
43
- end
44
-
45
- run("mkdir #{project_directory}")
46
- Dir.chdir(project_directory) or fail("Couldn't change to #{project_directory}")
47
- run("git init")
48
- run("git remote add suspenders #{template_url}")
49
- run("git pull suspenders master")
50
-
51
- Dir.glob("#{project_directory}/**/*").each do |file|
52
- search_and_replace(file, changeme, project_name)
53
- end
54
-
55
- Dir.glob("#{project_directory}/**/session_store.rb").each do |file|
56
- datestring = Time.now.strftime("%j %U %w %A %B %d %Y %I %M %S %p %Z")
57
- search_and_replace(file, changesession, Digest::MD5.hexdigest("#{project_name} #{datestring}"))
58
- end
59
-
60
- run("git commit -a -m 'Initial commit'")
61
-
62
- # can't vendor nokogiri because it has native extensions
63
- unless installed?("nokogiri")
64
- run "sudo gem install nokogiri --version='1.4.0'"
65
- end
66
-
67
- # need RedCloth installed for clearance generators to run.
68
- unless installed?("RedCloth")
69
- run "sudo gem install RedCloth --version='4.2.2'"
70
- end
71
-
72
- run("script/generate clearance")
73
- run("script/generate clearance_features -f")
74
- run("script/generate clearance_views -f")
75
-
76
- run("git add .")
77
- run("git commit -m 'installed clearance'")
78
-
79
- puts
80
- puts "Now login to github and add a new project named '#{project_name.humanize.titleize}'"
@@ -1,7 +1,14 @@
1
1
  Feature: Rake works in the suspended project
2
2
 
3
3
  Scenario: Running rake in the suspended project
4
- When I run the rake task "db:create:all"
4
+ When I drop and create the required databases
5
5
  And I run the rake task "db:migrate"
6
6
  And I run the rake task "cucumber"
7
7
  Then I see a successful response in the shell
8
+
9
+ Scenario: Making a spec then running rake
10
+ When I drop and create the required databases
11
+ And I generate "rspec_model post title:string"
12
+ And I run the rake task "db:migrate"
13
+ And I run the rake task "spec"
14
+ Then I see a successful response in the shell
@@ -4,6 +4,21 @@ When 'I run the rake task "$task_name"' do |task_name|
4
4
  end
5
5
  end
6
6
 
7
+ When 'I generate "$generator_with_args"' do |generator_with_args|
8
+ Dir.chdir('test_project') do
9
+ system("./script/generate #{generator_with_args}")
10
+ end
11
+ end
12
+
7
13
  Then 'I see a successful response in the shell' do
8
14
  $?.to_i.should == 0
9
15
  end
16
+
17
+ When 'I drop and create the required databases' do
18
+ Dir.chdir('test_project') do
19
+ system("rake db:drop RAILS_ENV=test")
20
+ system("rake db:drop")
21
+ system("rake db:create RAILS_ENV=test")
22
+ system("rake db:create")
23
+ end
24
+ end
data/lib/command.rb ADDED
@@ -0,0 +1,12 @@
1
+ # Methods needed to run a command.
2
+
3
+ module Suspenders
4
+ module Command
5
+ def run(cmd)
6
+ puts "Running '#{cmd}'"
7
+ out = `#{cmd}`
8
+ fail "Command #{cmd} failed: #$?\n#{out}" if $? != 0
9
+ out
10
+ end
11
+ end
12
+ end
data/lib/create.rb ADDED
@@ -0,0 +1,106 @@
1
+ # Methods needed to create a project.
2
+
3
+ require 'rubygems'
4
+ require 'digest/md5'
5
+ require File.expand_path(File.dirname(__FILE__) + "/errors")
6
+ require File.expand_path(File.dirname(__FILE__) + "/command")
7
+
8
+ module Suspenders
9
+ class Create
10
+ attr_accessor :project_name, :template_url, :project_directory
11
+ include Suspenders::Command
12
+
13
+ def self.run!(input_project_name, input_template_url)
14
+ creator = self.new(input_project_name, input_template_url)
15
+ creator.create_project!
16
+ end
17
+
18
+ def initialize(input_project_name, input_template_url)
19
+ @project_name = valid_project_name!(input_project_name)
20
+ @template_url, @project_directory = valid_template_url!(input_template_url, project_name)
21
+ end
22
+
23
+ def create_project!
24
+ run("mkdir #{project_directory}")
25
+ Dir.chdir(project_directory) or fail("Couldn't change to #{project_directory}")
26
+ run("git init")
27
+ run("git remote add suspenders #{template_url}")
28
+ run("git pull suspenders master")
29
+
30
+ Dir.glob("#{project_directory}/**/*.*").each do |file|
31
+ search_and_replace(file, changeme, project_name)
32
+ end
33
+
34
+ Dir.glob("#{project_directory}/**/session_store.rb").each do |file|
35
+ datestring = Time.now.strftime("%j %U %w %A %B %d %Y %I %M %S %p %Z")
36
+ search_and_replace(file, changesession, Digest::MD5.hexdigest("#{project_name} #{datestring}"))
37
+ end
38
+
39
+ run("git commit -a -m 'Initial commit'")
40
+
41
+ run("rake gems:refresh_specs")
42
+ run("rake db:create RAILS_ENV=development")
43
+ run("rake db:create RAILS_ENV=test")
44
+
45
+ run("script/generate clearance")
46
+ run("script/generate clearance_features -f")
47
+ run("script/generate clearance_views -f")
48
+
49
+ run("git add .")
50
+ run("git commit -m 'installed clearance'")
51
+
52
+ puts
53
+ puts "Now login to github and add a new project named '#{project_name}'"
54
+ end
55
+
56
+ private
57
+
58
+ def changeme
59
+ "CHANGEME"
60
+ end
61
+
62
+ def changesession
63
+ "CHANGESESSION"
64
+ end
65
+
66
+ def valid_project_name!(project_name)
67
+ unless project_name =~ /^[a-z0-9_]+$/
68
+ raise InvalidInput.new("Project name must only contain [a-z0-9_]")
69
+ else
70
+ project_name
71
+ end
72
+ end
73
+
74
+ def valid_template_url!(template_url, project_name)
75
+ base_directory = Dir.pwd
76
+ project_directory = File.join(base_directory, project_name)
77
+
78
+ # This is for the common case for the user's convenience; the race
79
+ # condition can still occur.
80
+ if File.exists?(project_directory)
81
+ raise InvalidInput.new("Project directory (#{project_directory}) already exists")
82
+ end
83
+
84
+ if template_url && !(template_url =~ /^ *$/)
85
+ [template_url, project_directory]
86
+ else
87
+ ["git://github.com/thoughtbot/suspenders.git", project_directory]
88
+ end
89
+ end
90
+
91
+ def search_and_replace(file, search, replace)
92
+ begin
93
+ contents = File.read(file)
94
+ if contents[search]
95
+ puts "Replacing #{search} with #{replace} in #{file}"
96
+ contents.gsub!(search, replace)
97
+ File.open(file, "w") { |f| f << contents }
98
+ end
99
+ rescue Errno::EISDIR => e
100
+ # This is fine, because Dir.glob can't select only files.
101
+ rescue Errno::ENOENT => e
102
+ fail "Attempted to perform a find-and-replace on a missing file: #{file}"
103
+ end
104
+ end
105
+ end
106
+ end
data/lib/errors.rb ADDED
@@ -0,0 +1,12 @@
1
+ # User errors
2
+
3
+ module Suspenders
4
+ class InvalidInput < Exception; end
5
+
6
+ module Errors
7
+ def error_with_message(msg)
8
+ STDERR.puts msg
9
+ exit 1
10
+ end
11
+ end
12
+ end
data/suspenders.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
 
6
6
  s.name = 'suspenders'
7
- s.version = '0.0.2'
8
- s.date = '2010-05-14'
7
+ s.version = '0.0.3'
8
+ s.date = '2010-07-13'
9
9
 
10
10
  s.summary = "Generate a Rails app using thoughtbot's best practices."
11
11
  s.description = <<-HERE
@@ -26,6 +26,9 @@ rush to build something amazing; don't use it if you like missing deadlines.
26
26
 
27
27
  s.add_development_dependency('cucumber', [">= 0.6.2"])
28
28
 
29
+ s.add_dependency('nokogiri', '1.4.0')
30
+ s.add_dependency('RedCloth', '4.2.2')
31
+
29
32
  # = MANIFEST =
30
33
  s.files = %w[
31
34
  LICENSE
@@ -35,6 +38,9 @@ rush to build something amazing; don't use it if you like missing deadlines.
35
38
  features/rake_clean.feature
36
39
  features/step_definitions/shell.rb
37
40
  features/support/env.rb
41
+ lib/command.rb
42
+ lib/create.rb
43
+ lib/errors.rb
38
44
  suspenders.gemspec
39
45
  ]
40
46
  # = MANIFEST =
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Mike Burns
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-14 00:00:00 -04:00
17
+ date: 2010-07-13 00:00:00 -04:00
18
18
  default_executable: suspenders
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -31,6 +31,34 @@ dependencies:
31
31
  version: 0.6.2
32
32
  type: :development
33
33
  version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: nokogiri
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 4
44
+ - 0
45
+ version: 1.4.0
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: RedCloth
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 4
57
+ - 2
58
+ - 2
59
+ version: 4.2.2
60
+ type: :runtime
61
+ version_requirements: *id003
34
62
  description: |
35
63
  Suspenders is a base Rails project that you can upgrade. It is used by
36
64
  thoughtbot to get a jump start on a working app. Use Suspenders if you're in a
@@ -52,6 +80,9 @@ files:
52
80
  - features/rake_clean.feature
53
81
  - features/step_definitions/shell.rb
54
82
  - features/support/env.rb
83
+ - lib/command.rb
84
+ - lib/create.rb
85
+ - lib/errors.rb
55
86
  - suspenders.gemspec
56
87
  has_rdoc: true
57
88
  homepage: http://github.com/thoughtbot/suspenders-gem