primo 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
- pkg
1
+ pkg
2
+ .vagrant
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -1,18 +1,34 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- primo (0.0.5)
5
- gli
6
- parseconfig
4
+ primo (0.1.0)
5
+ commander
6
+ inifile
7
+ terminal-table
7
8
 
8
9
  GEM
9
10
  remote: http://rubygems.org/
10
11
  specs:
11
- gli (2.5.4)
12
- parseconfig (1.0.2)
12
+ commander (4.1.3)
13
+ highline (~> 1.6.11)
14
+ diff-lcs (1.1.3)
15
+ fakefs (0.4.2)
16
+ highline (1.6.15)
17
+ inifile (2.0.2)
18
+ rspec (2.12.0)
19
+ rspec-core (~> 2.12.0)
20
+ rspec-expectations (~> 2.12.0)
21
+ rspec-mocks (~> 2.12.0)
22
+ rspec-core (2.12.2)
23
+ rspec-expectations (2.12.1)
24
+ diff-lcs (~> 1.1.3)
25
+ rspec-mocks (2.12.2)
26
+ terminal-table (1.4.5)
13
27
 
14
28
  PLATFORMS
15
29
  ruby
16
30
 
17
31
  DEPENDENCIES
32
+ fakefs
18
33
  primo!
34
+ rspec
data/README.md CHANGED
@@ -2,54 +2,77 @@
2
2
 
3
3
  A configurable default Rails stack.
4
4
 
5
- Inspired by Steve Klabnik's article ["Rails has Two Default Stacks"](http://words.steveklabnik.com/rails-has-two-default-stacks) and the awesome Rails application templates.
5
+ This is a proof of concept and any feedback is welcome either on [GitHub](https://github.com/cbetta/primo/issues), [Twitter](http://twitter.com/cbetta), or [email](mailto:primo@cgb.im).
6
+
7
+ Inspired by Steve Klabnik's article ["Rails has Two Default Stacks"](http://words.steveklabnik.com/rails-has-two-default-stacks) and the awesome [Rails application templates](http://edgeguides.rubyonrails.org/rails_application_templates.html#gem-args).
6
8
 
7
9
  ## Why is this useful?
8
10
 
9
11
  Rails application templates are awesome, especially for hackers that often need to set up the same basic app, but also for companies that want to promote their best pratices. Sadly the ecosystem around them seems to be quite limited. Primo tries to solve this by adding a command line interface for defining your default template and share it with others.
10
12
 
11
- At the moment Primo allows you to run a Rails install with a template based on PostgreSQL/HAML/Rspec. It also allows you to specify your own default template in a .primo file.
13
+ At the moment Primo comes with [1 bundle of templates](https://github.com/cbetta/primo-templates) but it is relatively easy to add your own.
12
14
 
13
- ## What is next?
15
+ ## Requirements
14
16
 
15
- I have been thinking about a "template server" much like rubygems.org to allow people to upload/share their templates and reference them by name. I would love to know if this an idea worth exploring or just silly. [Join the discussion here](https://github.com/cbetta/primo/issues/2)
17
+ * Rails
18
+ * Git
16
19
 
17
20
  ## Usage
18
21
 
19
22
  ### Basic
20
23
 
21
- gem install rails
22
- gem install primo
24
+ $ gem install primo
25
+
26
+ $ primo new app_name #instead of "rails new app_name"
27
+
28
+ This generates a PostgreSQL/HAML/Rspec Rails app using [this admittedly very basic template](https://github.com/cbetta/primo-templates/blob/master/prime.rb).
29
+
30
+ You can specify a different template as follows
31
+
32
+ $ primo new app_name --template default-rails # this just runs a plain rails install
33
+
34
+ ### Advanced
35
+
36
+ Using a different template is easy. You can specify them any remote repository and bring in those templates.
23
37
 
24
- primo new app_name #instead of "rails new app_name"
38
+ # add a new remote
39
+ $ primo remote add <name> <git url> #pulls the templates into ~/primo_remotes/<name>/
25
40
 
26
- This generates a PostgreSQL/HAML/Rspec Rails app using [this admittedly very basic template](https://github.com/cbetta/primo/blob/master/templates/prime.rb).
41
+ # list all remotes
42
+ $ primo remote list
27
43
 
28
- Specify a different build in template (currently only 2) as follows
44
+ # remove a remote
45
+ $ primo remote rm <name>
29
46
 
30
- primo new app_name -t template_name
47
+ # update a remote by pulling in changes
48
+ $ primo remote pull <name>
31
49
 
32
- ### Specify default template
50
+ To use templates and set a different default:
33
51
 
34
- Using a different template is easy. You can specify them locally, remotely, or choose one of the [build in templates](https://github.com/cbetta/primo/blob/master/templates/) by name.
52
+ # list all templates in all pulled remotes
53
+ $ primo template list
54
+ +---------------+---------+-----------------------------------------------+
55
+ | Name | Remote | Path |
56
+ +---------------+---------+-----------------------------------------------+
57
+ | default-rails | default | /home/vagrant/.primo_remotes/default/rails.rb |
58
+ | default-prime | default | /home/vagrant/.primo_remotes/default/prime.rb |
59
+ +---------------+---------+-----------------------------------------------+
35
60
 
36
- primo default template_name # one of the provided templates
37
- primo default /local/path/to/template.rb # a full path (or relative to home) to the template file
38
- primo default http://remote.path/to/template.rb # a url pointing to a template file
61
+ # view a template content
62
+ $ primo template show <name>
39
63
 
40
- or edit `~/.primo`:
64
+ # open a template in your editor
65
+ $ primo template open <name>
41
66
 
42
- default="template_name"
43
- default="/local/path/to/template.rb"
44
- default="http://remote.path/to/template.rb"
45
-
46
- ## Todos
67
+ # set your default template to use when creating new projects
68
+ $ primo template default <name>
47
69
 
48
- * Add tests
49
- * Look into template server idea
70
+ # see your current default
71
+ $ primo template default
50
72
 
51
73
  ## Release notes
52
74
 
75
+ * **0.1.0** Changed syntax. Now uses infrastructure that supports remotes
53
76
  * **0.0.6** Allows for overriding of templates
54
77
  * **0.0.5** Adds option to set custom default
55
78
  * **0.0.4** Fixing template
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler/gem_tasks"
2
+
3
+ desc "Set up and run tests"
4
+ task :default => [:test]
5
+
6
+ desc "Run tests"
7
+ task :test do
8
+ sh "bundle exec rspec spec"
9
+ end
data/bin/primo CHANGED
@@ -1,30 +1,128 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'primo'
3
- require 'gli'
4
- require 'fileutils'
3
+ require 'commander/import'
4
+ require 'terminal-table'
5
5
 
6
- include GLI::App
6
+ program :name, 'Primo'
7
+ program :version, Primo::VERSION
8
+ program :description, 'A configurable default Rails stack using application templates'
9
+ program :help, "Author", "Cristiano Betta <cbetta@gmail.com>"
7
10
 
8
- program_desc 'A configurable default Rails stack using application templates'
11
+ Primo.ensure_git_installed
12
+ Primo.ensure_rails_installed
13
+ Primo.ensure_initial_remote_pulled
9
14
 
10
- flag [:t,:template], :default_value => Primo.current_template
15
+ command :"new" do |c|
16
+ c.syntax = 'primo new <name> [options]'
17
+ c.description = 'Creates a new Rails 3 application with the given name'
18
+ c.option '--template name', String, 'Override the default template and use the given template'
19
+ c.action do |args, options|
20
+ unless args.length == 1
21
+ command(:help).run("new")
22
+ else
23
+ options.default template: Primo::Template.default
24
+ Primo::Creator.new(options.template).create args.first
25
+ end
26
+ end
27
+ end
28
+
29
+ command :"template default" do |c|
30
+ c.syntax = 'primo template default <name>'
31
+ c.description = 'Sets the default template by name'
32
+
33
+ c.action do |args, options|
34
+ command(:help).run("templates default") if args.length > 1
35
+
36
+ if args.length == 1
37
+ list = Primo::Template.list.map {|template| template.display_name}
38
+ raise "No such template found" unless list.include? args.first
39
+ Primo::Template.default = args.first
40
+ else
41
+ puts Primo::Template.default
42
+ end
43
+ end
44
+ end
11
45
 
12
- desc 'Create a new Rails app'
13
- long_desc "Create a new Rails app using your default template"
14
- command :new do |c|
15
- c.action do |global_options,_,args|
16
- help_now!('Please specify name for your new Rails app') if args.length != 1
17
- Primo.create args.first, global_options[:template]
46
+ command :"template list" do |c|
47
+ c.syntax = 'primo template list'
48
+ c.description = 'Displays all know templates'
49
+
50
+ c.action do |args, options|
51
+ command(:help).run("template list") unless args.length == 0
52
+ list = Primo::Template.list.map {|template| [template.display_name, template.remote.name, template.expanded_filename]}
53
+ table = Terminal::Table.new :headings => ['Name', 'Remote', 'Path'], :rows => list
54
+ puts table
18
55
  end
19
56
  end
20
57
 
21
- desc 'Set default template'
22
- long_desc "Set the default Rails application template by name, path, or url."
23
- command :default do |c|
24
- c.action do |_,_,args|
25
- help_now!('Please specify a template by name, path or url') if args.length != 1
26
- Primo.default args.first
58
+ command :"template show" do |c|
59
+ c.syntax = 'primo template show <name>'
60
+ c.description = 'Outputs the template for inspection'
61
+
62
+ c.action do |args, options|
63
+ command(:help).run("template show") unless args.length == 1
64
+ puts Primo::Template.for(args.first).read
27
65
  end
28
66
  end
29
67
 
30
- exit run(ARGV)
68
+ command :"template open" do |c|
69
+ c.syntax = 'primo template open <name>'
70
+ c.description = 'Opens the template for inspection'
71
+
72
+ c.action do |args, options|
73
+ command(:help).run("template open") unless args.length == 1
74
+ `open #{Primo::Template.for(args.first).expanded_filename}`
75
+ end
76
+ end
77
+
78
+ command :"remote add" do |c|
79
+ c.syntax = 'primo remote add <name> <git-repo-url>'
80
+ c.description = 'Adds a new template remote repo and clones the contents locally'
81
+
82
+ c.action do |args, options|
83
+ command(:help).run("remote add") unless args.length == 2
84
+ Primo::Remote.new(*args).update
85
+ say "Added remote '#{args.first}' with url #{args.last}"
86
+ end
87
+ end
88
+
89
+ command :"remote pull" do |c|
90
+ c.syntax = 'primo remote pull <optional name>'
91
+ c.description = 'Update template remote repo'
92
+
93
+ c.action do |args, options|
94
+ command(:help).run("remote pull") if args.length > 1
95
+ if args.length == 1
96
+ Primo::Remote.new(args.first).update
97
+ puts "Updated remote `#{args.first}`"
98
+ else
99
+ Primo::Remote.list.each do |key, value|
100
+ Primo::Remote.new(key).update
101
+ puts "Updated remote `#{key}`"
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ command :"remote list" do |c|
108
+ c.syntax = 'primo remote list'
109
+ c.description = 'List know template remote repos'
110
+
111
+ c.action do |args, options|
112
+ command(:help).run("remote list") unless args.length == 0
113
+ list = Primo::Remote.list
114
+ table = Terminal::Table.new :headings => ['Name', 'URL'], :rows => list
115
+ puts table
116
+ end
117
+ end
118
+
119
+ command :"remote rm" do |c|
120
+ c.syntax = 'primo remote rm <name>'
121
+ c.description = 'Remove a named template remote'
122
+
123
+ c.action do |args, options|
124
+ command(:help).run("remote rm") unless args.length == 1
125
+ Primo::Remote.new(*args).remove
126
+ say "Removed remote '#{args.first}'"
127
+ end
128
+ end
@@ -1,8 +1,7 @@
1
- # Specify the default primo template to use for your Rails 3 apps
2
- default="prime"
1
+ [global]
2
+ # the default template
3
+ default = default-prime
3
4
 
4
- # Alternatively specify a local file
5
- # default="/local/path/to/template.rb"
6
-
7
- # Alternatively specify a URL
8
- # default="http://remote.path/to/template.rb"
5
+ [remotes]
6
+ # the default remotes for primo
7
+ default = git://github.com/cbetta/primo-templates.git
@@ -1,30 +1,39 @@
1
- require "parseconfig"
1
+ require "primo/version"
2
+ require "primo/config"
3
+ require "primo/remote"
4
+ require "primo/creator"
5
+ require "primo/template"
6
+ require 'rbconfig'
2
7
 
3
- class Primo
4
-
5
- CONFIG_FILE = File.expand_path('~/.primo').freeze
6
8
 
7
- def self.create name, template
8
- system "rails new #{name} -m #{path_for(template)}"
9
+ class Primo
10
+ def self.void
11
+ void ||= RbConfig::CONFIG['host_os'] =~ /msdos|mswin|djgpp|mingw/ ? 'NUL' : '/dev/null'
9
12
  end
10
13
 
11
- def self.default value
12
- ensure_config
13
- File.write CONFIG_FILE, File.read(CONFIG_FILE)
14
- .gsub(/^default *= *\S*/m, "default = '#{value}'")
14
+ def self.ensure_git_installed
15
+ return if system "git --version >>#{self.void} 2>&1"
16
+ puts "Please install Git before continuing"
17
+ exit(1)
15
18
  end
16
19
 
17
- def self.current_template
18
- ensure_config
19
- ParseConfig.new(CONFIG_FILE)["default"]
20
+ def self.ensure_rails_installed
21
+ return if system "git --version >>#{self.void} 2>&1"
22
+ puts "Please install Rails before continuing"
23
+ exit(1)
20
24
  end
21
25
 
22
- def self.path_for template
23
- return File.expand_path("templates/#{template}.rb") unless template =~ /\.rb$/i
24
- template
26
+ def self.ensure_initial_remote_pulled
27
+ unless Primo::Config.instance["post-install-processed"]
28
+ raise "No template collections specified in ~/.primo" unless self.initial_collection
29
+ Primo::Remote.new(self.initial_collection).update
30
+ Primo::Config.instance["post-install-processed"] = true
31
+ end
25
32
  end
26
33
 
27
- def self.ensure_config
28
- FileUtils.cp("data/.primo", CONFIG_FILE) unless File.exists?(CONFIG_FILE)
34
+ def self.initial_collection
35
+ @config[:remotes].keys.first
36
+ rescue
37
+ nil
29
38
  end
30
39
  end
@@ -0,0 +1,45 @@
1
+ require "singleton"
2
+ require "inifile"
3
+
4
+ class Primo
5
+ class Config
6
+ CONFIG_FILE = File.expand_path('~/.primo').freeze
7
+
8
+ attr_accessor :config
9
+
10
+ def self.instance
11
+ ensure_dot_file_created
12
+ @instance ||= Primo::Config.new
13
+ end
14
+
15
+ def initialize
16
+ load_config
17
+ end
18
+
19
+ def [] key
20
+ @config["global"][key]
21
+ end
22
+
23
+ def []= key,value
24
+ @config["global"][key] = value
25
+ save
26
+ end
27
+
28
+ def save
29
+ @config.write
30
+ end
31
+
32
+ private
33
+
34
+ def load_config
35
+ @config ||= IniFile.new(filename: CONFIG_FILE)
36
+ end
37
+
38
+ def self.ensure_dot_file_created
39
+ unless File.exists?(CONFIG_FILE)
40
+ FileUtils.cp("data/.primo", CONFIG_FILE)
41
+ @instance = nil
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,18 @@
1
+ class Primo
2
+ class Creator
3
+
4
+ def initialize template_name
5
+ @template_name = template_name
6
+ end
7
+
8
+ def create name
9
+ template.remote.ensure_cloned
10
+ system "rails new #{name} -m #{template.expanded_filename}"
11
+ end
12
+
13
+ def template
14
+ raise ArgumentError, "No such template found (#{@template_name})" unless Primo::Template.exists? @template_name
15
+ @template ||= Primo::Template.for(@template_name)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,59 @@
1
+ class Primo
2
+ class Remote
3
+ DIRECTORY = File.expand_path('~/.primo_remotes').freeze
4
+
5
+ def self.list
6
+ Primo::Config.instance.config[:remotes]
7
+ end
8
+
9
+ attr_accessor :name, :url
10
+
11
+ def initialize name, url = nil
12
+ @name = name
13
+ @url = url || Primo::Config.instance.config[:remotes][name]
14
+ ensure_saved
15
+ end
16
+
17
+ def templates
18
+ template_names.map {|name| Primo::Template.new(name, self)}
19
+ end
20
+
21
+ def update
22
+ ensure_cloned
23
+ system "cd #{directory}; git fetch -q && git reset --hard origin/master -q"
24
+ end
25
+
26
+ def remove
27
+ Primo::Config.instance.config[:remotes].delete(name)
28
+ Primo::Config.instance.save
29
+ FileUtils.rm_rf directory
30
+ end
31
+
32
+ def directory
33
+ "#{DIRECTORY}/#{name}"
34
+ end
35
+
36
+ def ensure_cloned
37
+ unless File.exists? "#{directory}/.git"
38
+ system "git clone #{url} #{directory} -q"
39
+ end
40
+ rescue
41
+ raise "Could not load templates from #{url}"
42
+ end
43
+
44
+ private
45
+
46
+ def ensure_saved
47
+ if !Primo::Config.instance.config[:remotes][name] && url
48
+ Primo::Config.instance.config[:remotes][name] = url
49
+ Primo::Config.instance.save
50
+ end
51
+ end
52
+
53
+ def template_names
54
+ Dir.entries(directory).select do |filename|
55
+ filename =~ /\.rb$/
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,53 @@
1
+ class Primo
2
+ class Template
3
+
4
+ attr_accessor :filename, :remote
5
+
6
+ def self.for display_name
7
+ remote_name, name = display_name.split("-")
8
+ remote = Primo::Remote.new(remote_name)
9
+ filename = "#{name}.rb"
10
+ Primo::Template.new filename, remote
11
+ end
12
+
13
+ def self.list
14
+ Primo::Remote.list.map do |name, url|
15
+ Primo::Remote.new(name).templates
16
+ end.flatten
17
+ end
18
+
19
+ def self.exists? display_name
20
+ Primo::Template.list.map{|tp| tp.display_name}.include? display_name
21
+ end
22
+
23
+ def self.default
24
+ Primo::Config.instance["default"]
25
+ end
26
+
27
+ def self.default= value
28
+ raise ArgumentError, "No such template found" unless Primo::Template.exists?(value)
29
+ Primo::Config.instance["default"] = value
30
+ end
31
+
32
+ def initialize filename, remote
33
+ @filename = filename
34
+ @remote = remote
35
+ end
36
+
37
+ def display_name
38
+ "#{remote.name}-#{name}"
39
+ end
40
+
41
+ def name
42
+ filename[0..-4]
43
+ end
44
+
45
+ def expanded_filename
46
+ "#{Primo::Remote::DIRECTORY}/#{remote.name}/#{filename}"
47
+ end
48
+
49
+ def read
50
+ File.read(expanded_filename)
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  class Primo
2
- VERSION = "0.0.6" unless defined? Primo::VERSION
2
+ VERSION = "0.1.0" unless defined? Primo::VERSION
3
3
  end
@@ -13,10 +13,14 @@ Gem::Specification.new do |s|
13
13
  s.license = 'MIT'
14
14
 
15
15
  s.files = `git ls-files`.split("\n")
16
+ s.files.reject! {|fn| ["Vagrantfile"].include?(fn) }
16
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
19
  s.require_paths = ["lib"]
19
20
 
20
- s.add_dependency 'gli'
21
- s.add_dependency 'parseconfig'
21
+ s.add_dependency 'commander'
22
+ s.add_dependency 'inifile'
23
+ s.add_dependency 'terminal-table'
24
+ s.add_development_dependency "rspec"
25
+ s.add_development_dependency "fakefs"
22
26
  end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ describe Primo::Config do
4
+
5
+ describe ".instance" do
6
+ it "should create the config file when needed" do
7
+ Primo::Config.instance
8
+ expect(File.exists?(Primo::Config::CONFIG_FILE)).to be_true
9
+ end
10
+
11
+ it "should not create the config file twice" do
12
+ Primo::Config.instance
13
+ created_at = File.new(Primo::Config::CONFIG_FILE).mtime
14
+ Primo::Config.instance
15
+ expect(File.new(Primo::Config::CONFIG_FILE).mtime).to be == created_at
16
+ end
17
+ end
18
+
19
+ describe "#[]" do
20
+ it "should return the right value" do
21
+ Primo::Config.instance["foo"] = "bar"
22
+ expect(Primo::Config.instance["foo"]).to be == "bar"
23
+ end
24
+ end
25
+
26
+ describe "#[]=" do
27
+ it "should save the config to file" do
28
+ Primo::Config.instance
29
+ created_at = File.new(Primo::Config::CONFIG_FILE).mtime
30
+ Primo::Config.instance["foo"] = "bar"
31
+ expect(File.new(Primo::Config::CONFIG_FILE).mtime).not_to be == created_at
32
+ end
33
+ end
34
+
35
+ describe "#save" do
36
+ it "should save the config to file" do
37
+ Primo::Config.instance
38
+ created_at = File.new(Primo::Config::CONFIG_FILE).mtime
39
+ Primo::Config.instance.save
40
+ expect(File.new(Primo::Config::CONFIG_FILE).mtime).not_to be == created_at
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe Primo::Creator do
4
+
5
+
6
+ describe "#create" do
7
+ before :each do
8
+ Primo::Template.stub(:list).and_return([Primo::Template.for("default-rails")])
9
+ end
10
+
11
+ it "should create a rails install with the given name and template" do
12
+ creator = Primo::Creator.new("default-rails")
13
+ creator.template.remote.stub(:system)
14
+ creator.should_receive(:system).with(/rails new my_app -m .*default\/rails.rb/)
15
+ creator.create("my_app")
16
+ end
17
+
18
+ it "should ensure the template exists" do
19
+ creator = Primo::Creator.new("foo-bar")
20
+ expect(->{creator.create("my_app")}).to raise_error(ArgumentError)
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,79 @@
1
+ require "spec_helper"
2
+
3
+ describe Primo::Remote do
4
+
5
+ before :each do
6
+ data = File.read("data/.primo")
7
+ FakeFS.activate!
8
+ FileUtils.mkdir_p "data"
9
+ File.open("data/.primo", 'w') { |file| file.write(data) }
10
+ end
11
+
12
+ after :each do
13
+ FakeFS::FileSystem.clear
14
+ FakeFS.deactivate!
15
+ end
16
+
17
+ describe ".list" do
18
+ it "should return the currently loaded remotes" do
19
+ expect(Primo::Remote.list).to be == {"default"=>"git://github.com/cbetta/primo-templates.git"}
20
+ end
21
+ end
22
+
23
+ describe "#initialize" do
24
+ it "should save the remote in the config if it isn't already" do
25
+ git_url = "git://github.com/cbetta/primo-templates.git"
26
+ expect(Primo::Config.instance.config[:remotes]["test"]).to be_nil
27
+ Primo::Remote.new("test", git_url)
28
+ expect(Primo::Config.instance.config[:remotes]["test"]).to be == git_url
29
+ end
30
+ end
31
+
32
+ describe "#templates" do
33
+ before do
34
+ remote = Primo::Remote::DIRECTORY + "/default"
35
+ FileUtils.mkdir_p remote
36
+ FileUtils.touch "#{remote}/foobar.rb"
37
+ FileUtils.touch "#{remote}/barbaz.rb"
38
+ FileUtils.touch "#{remote}/README.md"
39
+ end
40
+
41
+ it "should return a list of templates for the remote" do
42
+ templates = Primo::Remote.new("default").templates
43
+ expect(templates).to have(2).templates
44
+ templates.each do |template|
45
+ expect(["foobar", "barbaz"]).to include(template.name)
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#update" do
51
+ it "should only update the repo the second time" do
52
+ remote = Primo::Remote.new("default")
53
+ File.should_receive(:exists?).and_return(true)
54
+ remote.should_receive("system").once
55
+ remote.update
56
+ end
57
+
58
+ it "should clone the repo on first load" do
59
+ remote = Primo::Remote.new("default")
60
+ remote.should_receive("system").twice
61
+ remote.update
62
+ end
63
+ end
64
+
65
+ describe "#remove" do
66
+ it "should remove the cloned repo" do
67
+ remote = Primo::Remote.new("default")
68
+ FileUtils.should_receive(:rm_rf).with(remote.directory)
69
+ remote.remove
70
+ end
71
+
72
+ it "should remove the remote from the config" do
73
+ remote = Primo::Remote.new("default")
74
+ FileUtils.stub(:rm_rf)
75
+ remote.remove
76
+ expect(Primo::Remote.list).to be_empty
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,83 @@
1
+ require "spec_helper"
2
+
3
+ describe Primo::Template do
4
+
5
+ describe ".for" do
6
+ it "should initialize a template with the right name and remote" do
7
+ template = Primo::Template.for "foo-bar"
8
+ expect(template.filename).to be == "bar.rb"
9
+ expect(template.remote.name).to be == "foo"
10
+ end
11
+ end
12
+
13
+ describe ".list" do
14
+ it "should return a list of templates for every configured remote" do
15
+ FileUtils.mkdir_p("#{Primo::Remote::DIRECTORY}/default")
16
+ FileUtils.touch "#{Primo::Remote::DIRECTORY}/default/foobar.rb"
17
+ FileUtils.mkdir_p("#{Primo::Remote::DIRECTORY}/foo")
18
+ FileUtils.touch "#{Primo::Remote::DIRECTORY}/foo/bar.rb"
19
+ Primo::Config.instance.config[:remotes]["foo"] = "some_url"
20
+ expect(Primo::Template.list).to have(2).item
21
+ end
22
+ end
23
+
24
+ context "with an instance" do
25
+
26
+ before :each do
27
+ @template = Primo::Template.new "bar.rb", Primo::Remote.new("foo")
28
+ end
29
+
30
+ describe "#initialize" do
31
+ it "should set the filename and the remote" do
32
+ expect(@template.filename).to be == "bar.rb"
33
+ expect(@template.remote.name).to be == "foo"
34
+ end
35
+ end
36
+
37
+ describe "#display_name" do
38
+ it "should return the display name" do
39
+ expect(@template.display_name).to be == "foo-bar"
40
+ end
41
+ end
42
+
43
+ describe "#name" do
44
+ it "should return the template name" do
45
+ expect(@template.name).to be == "bar"
46
+ end
47
+ end
48
+
49
+ describe "#expanded_filename" do
50
+ it "should return the template's full filename" do
51
+ expect(@template.expanded_filename).to be == File.expand_path("~/.primo_remotes/foo/bar.rb")
52
+ end
53
+ end
54
+
55
+ describe "#default" do
56
+ before do
57
+ Primo::Template.should_receive(:list).and_return([Primo::Template.for("default-rails")])
58
+ end
59
+
60
+ it "should set the default" do
61
+ expect(Primo::Template.default).not_to be == "default-rails"
62
+ Primo::Template.default = "default-rails"
63
+ expect(Primo::Template.default).to be == "default-rails"
64
+ end
65
+
66
+ it "should error if the default template doesn't exist" do
67
+ expect(-> {Primo::Template.default = "default-foo"}).to raise_error(ArgumentError)
68
+ end
69
+ end
70
+
71
+ describe "#read" do
72
+
73
+ before do
74
+ FileUtils.mkdir_p("#{Primo::Remote::DIRECTORY}/#{@template.remote.name}")
75
+ File.open(@template.expanded_filename, 'w') { |file| file.write("FOOBAR") }
76
+ end
77
+
78
+ it "should return the template content" do
79
+ expect(@template.read).to be == "FOOBAR"
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,16 @@
1
+ require "primo"
2
+ require "fakefs/safe"
3
+
4
+ RSpec.configure do |config|
5
+ config.before :each do
6
+ data = File.read("data/.primo")
7
+ FakeFS.activate!
8
+ FileUtils.mkdir_p "data"
9
+ File.open("data/.primo", 'w') { |file| file.write(data) }
10
+ end
11
+
12
+ config.after :each do
13
+ FakeFS::FileSystem.clear
14
+ FakeFS.deactivate!
15
+ end
16
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,10 +9,10 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-29 00:00:00.000000000 Z
12
+ date: 2013-03-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: gli
15
+ name: commander
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
@@ -28,7 +28,7 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
- name: parseconfig
31
+ name: inifile
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
@@ -43,6 +43,54 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: terminal-table
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: fakefs
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
46
94
  description: A configurable default Rails stack using application templates
47
95
  email:
48
96
  - cbetta@gmail.com
@@ -52,7 +100,7 @@ extensions: []
52
100
  extra_rdoc_files: []
53
101
  files:
54
102
  - .gitignore
55
- - .rvmrc
103
+ - .rspec
56
104
  - Gemfile
57
105
  - Gemfile.lock
58
106
  - LICENSE
@@ -61,10 +109,17 @@ files:
61
109
  - bin/primo
62
110
  - data/.primo
63
111
  - lib/primo.rb
112
+ - lib/primo/config.rb
113
+ - lib/primo/creator.rb
114
+ - lib/primo/remote.rb
115
+ - lib/primo/template.rb
64
116
  - lib/primo/version.rb
65
117
  - primo.gemspec
66
- - templates/prime.rb
67
- - templates/rails.rb
118
+ - spec/primo/config_spec.rb
119
+ - spec/primo/creator_spec.rb
120
+ - spec/primo/remote_spec.rb
121
+ - spec/primo/template_spec.rb
122
+ - spec/spec_helper.rb
68
123
  homepage: http://github.com/cbetta/primo
69
124
  licenses:
70
125
  - MIT
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm use 1.9.3@primo --create
@@ -1,58 +0,0 @@
1
- # Setup PG
2
- gsub_file "Gemfile", "gem 'sqlite3'", "gem 'pg'"
3
-
4
- database_config = <<-EOF
5
- development:
6
- adapter: postgresql
7
- encoding: unicode
8
- database: #{app_name}_dev
9
-
10
- test:
11
- adapter: postgresql
12
- encoding: unicode
13
- database: #{app_name}_test
14
- EOF
15
-
16
- remove_file "config/database.yml"
17
- file "config/database.yml", database_config
18
- file "config/database.yml.example", database_config
19
-
20
- # Setup HAML
21
- gem "haml"
22
- gem_group :development do
23
- gem "haml-rails"
24
- end
25
-
26
- remove_file "app/views/layouts/application.html.erb"
27
- file "app/views/layouts/application.html.haml", <<-EOF
28
- !!!
29
- %html
30
- %head
31
- %title #{app_name.humanize}
32
- = stylesheet_link_tag :application, media: "all"
33
- = javascript_include_tag :application
34
- = csrf_meta_tags
35
- %body
36
- = yield
37
- EOF
38
-
39
- # Setup Rspec
40
- gem_group :development, :test do
41
- gem "rspec-rails"
42
- end
43
-
44
- run "rm -rf test"
45
- run "rm -rf autotest"
46
-
47
- # Specify generators
48
- application <<-EOF
49
- config.generators do |g|
50
- g.template_engine :haml
51
- g.test_framework :rspec
52
- end
53
- EOF
54
-
55
- # Finalize setup
56
-
57
- run "bundle"
58
- run "rails generate rspec:install"
@@ -1 +0,0 @@
1
- # This doesn't do anything, and therfore runs a plain standard install