fast_track 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,39 +1,41 @@
1
1
  # fast_track
2
2
 
3
- Create Rails apps quickly.
3
+ Create Rails apps quickly. So far the number of recipes we have is somewhat limited, but it will grow very soon,
4
+ and very fast.
4
5
 
5
- ## Status:
6
+ ## Install:
6
7
 
7
- Currently very alpha. Check out what's possible here:
8
+ fast_track is a tool for building Rails apps, so you don't need to add it to your Gemfile. Just install it as you
9
+ would any other gem:
8
10
 
9
11
  ```bash
10
- git clone git@github.com:EncomLabs/fast_track.git
11
- cd fast_track
12
+ gem install fast_track
12
13
  ```
13
14
 
14
- The executable `bin/track` is where all the magic happens for the moment.
15
-
16
15
  ## Examples:
17
16
 
17
+ Here's some examples of what fast_track can do so far. Note that this is actually a rather limited set of things
18
+ compared to what it will be actually capable of.
19
+
18
20
  ### Create an app with Devise + Cancan + Rolify
19
21
 
20
22
  ```bash
21
- ./bin/track --app whatever --tracks devise,cancan,rolify
23
+ track --app cool_site --tracks devise,cancan,rolify
22
24
  ```
23
25
 
24
26
  ### Same as above, but add Devise views
25
27
 
26
28
  ```bash
27
- ./bin/track --app whatever --tracks devise_with_views,cancan,rolify
29
+ ./bin/track --app cool_site --tracks devise_with_views,cancan,rolify
28
30
  ```
29
31
 
30
32
  ### Same as above, but with Twitter Bootstrap
31
33
 
32
34
  ```bash
33
- ./bin/track --app whatever --tracks twitter_bootstrap,devise_with_view,cancan,rolify
35
+ ./bin/track --app cool_site --tracks twitter_bootstrap,devise_with_view,cancan,rolify
34
36
  ```
35
37
 
36
- ## Why not use rails wizard / appscrolls / Rails app composer / some other Rails app builder ?
38
+ ## Why not use Rails Wizard / appscrolls / Rails app composer / some other Rails app builder ?
37
39
 
38
40
  In all the projects I've seen, most functionality is implemented in procedural scripts. They are not objects.
39
41
  In `fast_track`, all objects inherit from `Track`. Procedural is fine for quick scripts, but not for robust tools.
data/bin/track CHANGED
@@ -4,4 +4,5 @@ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
4
 
5
5
  require 'fast_track'
6
6
 
7
- FastTrack.new.start
7
+
8
+ FastTrack::Commands.start(ARGV)
data/fast_track.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["farleyknight@gmail.com"]
11
11
  spec.summary = %q{Create Rails apps quickly.}
12
12
  spec.description = %q{Leverage the Rails generator to architect new Rails apps with lots of default gems, templates, and other recipes, quickly.}
13
- spec.homepage = ""
13
+ spec.homepage = "http://fast-track.io"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -22,4 +22,8 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec"
24
24
  spec.add_development_dependency "gem-release"
25
+
26
+ spec.add_dependency "thor"
27
+ spec.add_dependency "rails"
28
+ spec.add_dependency "hooks"
25
29
  end
data/lib/fast_track.rb CHANGED
@@ -1,94 +1,48 @@
1
1
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
2
2
 
3
3
  require 'open-uri'
4
- require 'slop'
5
-
6
- require 'pry'
7
4
 
8
5
  require 'rails/generators'
9
6
  require 'rails/generators/rails/app/app_generator'
10
7
 
8
+ require 'fast_track/ext'
9
+ require 'fast_track/dsl'
11
10
  require 'fast_track/exceptions'
12
11
  require 'fast_track/config'
13
12
 
14
13
  require 'fast_track/track_methods'
15
14
  require 'fast_track/track'
16
15
 
16
+ require 'fast_track/commands'
17
17
  require 'fast_track/generator'
18
18
 
19
- # require 'fast_track/cancan'
20
- # require 'fast_track/rolify'
21
- # require 'fast_track/devise'
22
-
23
- # require 'fast_track/awesome_defaults'
24
- # require 'fast_track/twitter_bootstrap'
25
-
26
- # Load FastTrack tracks
27
- Dir[File.join(File.dirname(__FILE__), 'lib', 'tracks')].each do |file|
28
- load file
29
- end
30
-
31
- # Load local tracks
32
- Dir[File.join(File.expand_path("~/"), ".fast_track", "*.rb")].each do |file|
33
- load file
34
- end
35
-
36
- class FastTrack
37
- def initialize
38
- FastTrack.validate_options!
39
- end
40
-
41
- def app
42
- @app ||= Generator.new([FastTrack.app_name])
43
- end
44
-
45
- def start
46
- app.invoke
19
+ module FastTrack
20
+ class App
21
+ def initialize(app_name, tracks)
22
+ FastTrack.options[:tracks] = tracks
23
+ @app ||= FastTrack::Generator.new([app_name])
24
+ @app.invoke
25
+ end
47
26
  end
48
27
 
49
28
  class << self
50
29
  def options
51
- @opts
52
- end
53
-
54
- def app_name
55
- options[:app]
56
- end
57
-
58
- def make_tracks
59
- options[:tracks].map do |track|
60
- klass = FastTrack.const_get(track.camelize)
61
- if klass <= Track
62
- klass
63
- else
64
- raise TrackNotFound.new(klass.name)
65
- end
66
- end
30
+ @options ||= {}
67
31
  end
68
32
 
69
33
  def tracks
70
34
  @tracks ||= make_tracks
71
35
  end
72
36
 
73
- def validate_options!
74
- @opts ||= Slop.parse(ARGV || [], strict: true, arguments: true, help: true) do
75
- banner 'Usage: track --A [app] --T [tracks]'
76
-
77
- on 'A', 'app=', 'The application name'
78
- on 'T', 'tracks=', 'The tracks to run', as: Array
79
- end
80
-
81
- # TODO: Is there a Ruby gem that has the same functionality as ActiveModel::Validations
82
- # but doesn't require ActiveRecord?
83
- #
84
- # Because we should use that here..
85
-
86
- if @opts[:app].blank?
87
- raise "--app can't be blank!"
88
- end
37
+ def available_tracks
38
+ @available_tracks ||= {}
39
+ end
89
40
 
90
- if @opts[:tracks].blank?
91
- raise "--tracks can't be blank!"
41
+ def find_track(name)
42
+ if available_tracks[name].present?
43
+ available_tracks[name]
44
+ else
45
+ raise TrackNotFound.new(name)
92
46
  end
93
47
  end
94
48
 
@@ -103,5 +57,28 @@ class FastTrack
103
57
  def template_root
104
58
  File.join(File.expand_path(root), "lib", "templates")
105
59
  end
60
+
61
+ protected
62
+
63
+ def make_tracks
64
+ options[:tracks].map do |track|
65
+ klass = FastTrack.find_track(track)
66
+ if klass <= Track
67
+ klass
68
+ else
69
+ raise TrackNotFound.new(klass.name)
70
+ end
71
+ end
72
+ end
106
73
  end
107
74
  end
75
+
76
+ # Load FastTrack tracks
77
+ Dir[File.join(File.dirname(__FILE__), 'tracks', "*.rb")].each do |file|
78
+ require file
79
+ end
80
+
81
+ # Load local tracks
82
+ Dir[File.join(File.expand_path("~/"), ".fast_track", "*.rb")].each do |file|
83
+ require file
84
+ end
@@ -0,0 +1,32 @@
1
+ require "thor"
2
+
3
+ module FastTrack
4
+ class Commands < Thor
5
+ desc "new APP_NAME", "Create a new Rails app, called APP_NAME"
6
+
7
+ method_option :tracks, {
8
+ :type => :array,
9
+ :aliases => "-T",
10
+ :desc => "Tracks to run with this app",
11
+ :required => true
12
+ }
13
+
14
+ def new_app(name)
15
+ FastTrack::App.new(name, options[:tracks])
16
+ end
17
+
18
+ desc "list", "List all available tracks, with descriptions"
19
+
20
+ def list
21
+ puts ""
22
+ puts "Available Tracks:"
23
+ puts ""
24
+ FastTrack::Track.descendants.each do |track|
25
+ unless track.name.blank?
26
+ puts "#{track.name.ljust(30)} -- #{track.description}"
27
+ end
28
+ end
29
+ puts ""
30
+ end
31
+ end
32
+ end
@@ -1,4 +1,4 @@
1
- class FastTrack
1
+ module FastTrack
2
2
  # TODO: This should take a YAML file and merge it with the defaults!
3
3
  class Config < Hash
4
4
  # TODO: This config file should have nested information for each
@@ -0,0 +1,14 @@
1
+ module FastTrack
2
+ module DSL
3
+ def track(*args, &block)
4
+ new_track = Class.new(FastTrack::Track, &block)
5
+ new_track.args = args
6
+
7
+ FastTrack.available_tracks[args.first] = new_track
8
+
9
+ new_track
10
+ end
11
+ end
12
+ end
13
+
14
+ extend FastTrack::DSL
@@ -1,4 +1,4 @@
1
- class FastTrack
1
+ module FastTrack
2
2
  class TrackNotFound < Exception
3
3
  def initialize(track_name)
4
4
  super("Could not find track #{track_name}! Please double-check the provided params.")
@@ -0,0 +1,5 @@
1
+ class Class
2
+ def descendants
3
+ ObjectSpace.each_object(::Class).select {|klass| klass < self }
4
+ end
5
+ end
@@ -1,4 +1,4 @@
1
- class FastTrack
1
+ module FastTrack
2
2
  class GemInstaller
3
3
  def run(generator)
4
4
  FastTrack.tracks.each do |klass|
@@ -19,6 +19,26 @@ class FastTrack
19
19
  end
20
20
  end
21
21
 
22
+ class AfterBundle
23
+ def run(generator)
24
+ FastTrack.tracks.each do |klass|
25
+ unless klass.after_bundle_block.blank?
26
+ generator.instance_eval(&klass.after_bundle_block)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class AfterMigrate
33
+ def run(generator)
34
+ FastTrack.tracks.each do |klass|
35
+ unless klass.after_migrate_block.blank?
36
+ generator.instance_eval(&klass.after_migrate_block)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
22
42
  class Runner
23
43
  def run(generator)
24
44
  FastTrack.tracks.each do |klass|
@@ -30,18 +50,24 @@ class FastTrack
30
50
  end
31
51
 
32
52
  class Generator < Rails::Generators::AppGenerator
33
- include TrackMethods
34
-
35
53
  source_root Rails::Generators::AppGenerator.source_root
36
54
 
37
- def fasttrack
55
+ def fast_track
38
56
  FastTrack::GemInstaller.new.run(self)
39
57
  run("bundle install")
58
+ FastTrack::AfterBundle.new.run(self)
40
59
 
41
60
  FastTrack::Runner.new.run(self)
42
61
 
43
62
  FastTrack::BeforeMigrate.new.run(self)
44
63
  rake("db:migrate")
64
+ FastTrack::AfterMigrate.new.run(self)
65
+ end
66
+
67
+ protected
68
+
69
+ def do_whatever
70
+ puts "Does thor call this?"
45
71
  end
46
72
  end
47
73
  end
@@ -1,5 +1,8 @@
1
- class FastTrack
1
+ require "hooks"
2
+
3
+ module FastTrack
2
4
  class Track
5
+ include Hooks
3
6
  include TrackMethods
4
7
 
5
8
  attr_accessor :generator
@@ -8,72 +11,105 @@ class FastTrack
8
11
  @generator = generator
9
12
  end
10
13
 
11
- # Describe a Gemfile using `gem` and `gem_group`
12
- def self.gemfile(&block)
13
- @gemfile_block = block
14
- end
15
-
16
- def self.gemfile_block
17
- @gemfile_block
18
- end
19
-
20
- # Tasks before migration
21
- def self.before_migrate(&block)
22
- @before_migrate_block = block
23
- end
24
-
25
- def self.before_migrate_block
26
- @before_migrate_block
27
- end
28
-
29
- # If you need to get the base-level generator object, it's
30
- # available here.
31
- def g
32
- generator
33
- end
34
-
35
- # Add a gem
36
- #
37
- # TODO: Find a way to consolidate all gems at once, so we only have to run
38
- # `bundle install` once.
39
- def gem(*args)
40
- g.gem(*args)
41
- end
42
-
43
- # Run rake
44
- def rake(*args)
45
- g.rake(*args)
46
- end
47
-
48
- # Run any command
49
- def run(*args)
50
- g.run(*args)
51
- end
52
-
53
- alias :bundle_install! :bundle_install
54
-
55
- def generate(*args)
56
- g.generate(*args)
57
- end
58
-
59
- # Add a route to config/routes.rb
60
- def route(*args)
61
- g.route(*args)
62
- end
63
-
64
- # Add a file
65
- def create_file(*args)
66
- g.create_file(*args)
67
- end
68
-
69
- # Create a gem group
70
- def gem_group(*args, &block)
71
- generator.gem_group(*args, &block)
72
- end
73
-
74
- # Read a file from the templates directory
75
- def read_file(file_name)
76
- File.read(File.join(FastTrack.template_root, template_directory, file_name))
14
+ class << self
15
+ def args=(other)
16
+ @args = other
17
+ end
18
+
19
+ def args
20
+ @args || []
21
+ end
22
+
23
+ def name_from_args
24
+ if args.length == 1
25
+ @args.first
26
+ end
27
+ end
28
+
29
+ def name(name = nil)
30
+ if name.blank?
31
+ # @name || name_from_args || ""
32
+ name_from_args || ""
33
+ else
34
+ @name = name
35
+ end
36
+ end
37
+
38
+ def description(arg = nil)
39
+ if arg.blank?
40
+ @description
41
+ else
42
+ @description = arg
43
+ end
44
+ end
45
+
46
+ alias :desc :description
47
+
48
+ # The required tracks this track needs.
49
+ def requires(*args)
50
+ if args.blank?
51
+ @requires
52
+ else
53
+ @requires = args
54
+ end
55
+ end
56
+
57
+ def rubygem(name)
58
+ @rubygem = name
59
+ end
60
+
61
+ def tutorial_url(url)
62
+ @tutorial_urls ||= []
63
+ @tutorial_urls << url
64
+ end
65
+
66
+ def github_url(url)
67
+ @github_url = url
68
+ end
69
+
70
+ def github_description(description)
71
+ @github_description = description
72
+ end
73
+
74
+ # Describe a Gemfile using `gem` and `gem_group`
75
+ def gemfile(&block)
76
+ @gemfile_block = block
77
+ end
78
+
79
+ def gemfile_block
80
+ @gemfile_block
81
+ end
82
+
83
+ # Tasks before migration
84
+ def before_migrate(&block)
85
+ @before_migrate_block = block
86
+ end
87
+
88
+ def before_migrate_block
89
+ @before_migrate_block
90
+ end
91
+
92
+ alias :before_migration :before_migrate
93
+
94
+ # Tasks before migration
95
+ def after_migrate(&block)
96
+ @after_migrate_block = block
97
+ end
98
+
99
+ def after_migrate_block
100
+ @after_migrate_block
101
+ end
102
+
103
+ alias :after_migration :after_migrate
104
+
105
+ # After bundle
106
+ def after_bundle(&block)
107
+ @after_bundle_block = block
108
+ end
109
+
110
+ def after_bundle_block
111
+ @after_bundle_block
112
+ end
77
113
  end
78
114
  end
79
115
  end