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 +2 -1
- data/.rspec +1 -0
- data/Gemfile.lock +21 -5
- data/README.md +46 -23
- data/Rakefile +9 -1
- data/bin/primo +116 -18
- data/data/.primo +6 -7
- data/lib/primo.rb +27 -18
- data/lib/primo/config.rb +45 -0
- data/lib/primo/creator.rb +18 -0
- data/lib/primo/remote.rb +59 -0
- data/lib/primo/template.rb +53 -0
- data/lib/primo/version.rb +1 -1
- data/primo.gemspec +6 -2
- data/spec/primo/config_spec.rb +43 -0
- data/spec/primo/creator_spec.rb +24 -0
- data/spec/primo/remote_spec.rb +79 -0
- data/spec/primo/template_spec.rb +83 -0
- data/spec/spec_helper.rb +16 -0
- metadata +62 -7
- data/.rvmrc +0 -1
- data/templates/prime.rb +0 -58
- data/templates/rails.rb +0 -1
data/.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
pkg
|
1
|
+
pkg
|
2
|
+
.vagrant
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile.lock
CHANGED
@@ -1,18 +1,34 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
primo (0.0
|
5
|
-
|
6
|
-
|
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
|
-
|
12
|
-
|
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
|
-
|
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
|
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
|
-
##
|
15
|
+
## Requirements
|
14
16
|
|
15
|
-
|
17
|
+
* Rails
|
18
|
+
* Git
|
16
19
|
|
17
20
|
## Usage
|
18
21
|
|
19
22
|
### Basic
|
20
23
|
|
21
|
-
gem install
|
22
|
-
|
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
|
-
|
38
|
+
# add a new remote
|
39
|
+
$ primo remote add <name> <git url> #pulls the templates into ~/primo_remotes/<name>/
|
25
40
|
|
26
|
-
|
41
|
+
# list all remotes
|
42
|
+
$ primo remote list
|
27
43
|
|
28
|
-
|
44
|
+
# remove a remote
|
45
|
+
$ primo remote rm <name>
|
29
46
|
|
30
|
-
|
47
|
+
# update a remote by pulling in changes
|
48
|
+
$ primo remote pull <name>
|
31
49
|
|
32
|
-
|
50
|
+
To use templates and set a different default:
|
33
51
|
|
34
|
-
|
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
|
-
|
37
|
-
primo
|
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
|
-
|
64
|
+
# open a template in your editor
|
65
|
+
$ primo template open <name>
|
41
66
|
|
42
|
-
default
|
43
|
-
default
|
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
|
-
|
49
|
-
|
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
data/bin/primo
CHANGED
@@ -1,30 +1,128 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'primo'
|
3
|
-
require '
|
4
|
-
require '
|
3
|
+
require 'commander/import'
|
4
|
+
require 'terminal-table'
|
5
5
|
|
6
|
-
|
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
|
-
|
11
|
+
Primo.ensure_git_installed
|
12
|
+
Primo.ensure_rails_installed
|
13
|
+
Primo.ensure_initial_remote_pulled
|
9
14
|
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
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
|
data/data/.primo
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
|
2
|
-
default
|
1
|
+
[global]
|
2
|
+
# the default template
|
3
|
+
default = default-prime
|
3
4
|
|
4
|
-
|
5
|
-
# default
|
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
|
data/lib/primo.rb
CHANGED
@@ -1,30 +1,39 @@
|
|
1
|
-
require "
|
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
|
-
|
8
|
-
|
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.
|
12
|
-
|
13
|
-
|
14
|
-
|
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.
|
18
|
-
|
19
|
-
|
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.
|
23
|
-
|
24
|
-
|
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.
|
28
|
-
|
34
|
+
def self.initial_collection
|
35
|
+
@config[:remotes].keys.first
|
36
|
+
rescue
|
37
|
+
nil
|
29
38
|
end
|
30
39
|
end
|
data/lib/primo/config.rb
ADDED
@@ -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
|
data/lib/primo/remote.rb
ADDED
@@ -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
|
data/lib/primo/version.rb
CHANGED
data/primo.gemspec
CHANGED
@@ -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 '
|
21
|
-
s.add_dependency '
|
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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
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-
|
12
|
+
date: 2013-03-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
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:
|
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
|
-
- .
|
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
|
-
-
|
67
|
-
-
|
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
|
data/templates/prime.rb
DELETED
@@ -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"
|
data/templates/rails.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
# This doesn't do anything, and therfore runs a plain standard install
|