captify 0.2.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +24 -2
  3. data/README.rdoc +3 -12
  4. data/Rakefile +7 -0
  5. data/VERSION +1 -1
  6. data/bin/captify +2 -50
  7. data/captify.gemspec +42 -3
  8. data/lib/captify.rb +25 -0
  9. data/lib/captify/cli.rb +59 -0
  10. data/lib/captify/runner.rb +31 -0
  11. data/lib/captify/template.rb +19 -61
  12. data/lib/captify/template_bundle.rb +38 -0
  13. data/lib/captify/template_loader.rb +46 -0
  14. data/lib/captify/template_registrar.rb +44 -0
  15. data/spec/captify/cli_spec.rb +45 -0
  16. data/spec/captify/runner_spec.rb +52 -0
  17. data/spec/captify/template_bundle_spec.rb +30 -0
  18. data/spec/captify/template_loader_spec.rb +57 -0
  19. data/spec/captify/template_registrar_spec.rb +46 -0
  20. data/spec/captify/template_spec.rb +60 -0
  21. data/spec/captify_spec.rb +18 -0
  22. data/spec/data/files/Gemfile.test_captify +2 -0
  23. data/spec/data/files/Gemfile.test_captify.lock +34 -0
  24. data/spec/data/files/load_path/not-template/lib/not_template.rb +0 -0
  25. data/spec/data/files/load_path/template-without-lib/template_bundle.rb +1 -0
  26. data/spec/data/files/load_path/template1/lib/template_bundle.rb +1 -0
  27. data/spec/data/files/load_path/template2/lib/template_bundle.rb +1 -0
  28. data/spec/data/files/rubygems/gems/not-template-1.0.0/lib/not_template.rb +0 -0
  29. data/spec/data/files/rubygems/gems/template1-1.0.0/lib/template_bundle.rb +1 -0
  30. data/spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy.rb +0 -0
  31. data/spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy/production.rb +0 -0
  32. data/spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy/staging.rb +0 -0
  33. data/spec/data/files/rubygems/gems/template1-1.0.0/templates/sinatra-base/config/deploy.rb +0 -0
  34. data/spec/data/files/rubygems/gems/template2-1.0.0/lib/template_bundle.rb +1 -0
  35. data/spec/data/files/rubygems/specifications/not-template-1.0.0.gemspec +15 -0
  36. data/spec/data/files/rubygems/specifications/template1-1.0.0.gemspec +15 -0
  37. data/spec/data/files/rubygems/specifications/template2-1.0.0.gemspec +15 -0
  38. data/spec/helper.rb +20 -0
  39. metadata +81 -3
data/Gemfile CHANGED
@@ -6,4 +6,7 @@ group :development do
6
6
  gem "rdoc", "~> 3.12"
7
7
  gem "bundler", "~> 1.0.0"
8
8
  gem "jeweler", "~> 1.8.3"
9
+ gem "minitest", "~> 3.2.0"
10
+ gem "debugger"
11
+ gem "debugger-pry", :require => "debugger/pry"
9
12
  end
@@ -7,14 +7,28 @@ GEM
7
7
  net-sftp (>= 2.0.0)
8
8
  net-ssh (>= 2.0.14)
9
9
  net-ssh-gateway (>= 1.1.0)
10
+ coderay (1.0.7)
11
+ columnize (0.3.6)
12
+ debugger (1.1.4)
13
+ columnize (>= 0.3.1)
14
+ debugger-linecache (~> 1.1.1)
15
+ debugger-ruby_core_source (~> 1.1.3)
16
+ debugger-linecache (1.1.2)
17
+ debugger-ruby_core_source (>= 1.1.1)
18
+ debugger-pry (0.1.1)
19
+ debugger (~> 1)
20
+ pry (>= 0.9.9)
21
+ debugger-ruby_core_source (1.1.3)
10
22
  git (1.2.5)
11
- highline (1.6.12)
12
- jeweler (1.8.3)
23
+ highline (1.6.13)
24
+ jeweler (1.8.4)
13
25
  bundler (~> 1.0)
14
26
  git (>= 1.2.5)
15
27
  rake
16
28
  rdoc
17
29
  json (1.7.3)
30
+ method_source (0.7.1)
31
+ minitest (3.2.0)
18
32
  net-scp (1.0.4)
19
33
  net-ssh (>= 1.99.1)
20
34
  net-sftp (2.0.5)
@@ -22,9 +36,14 @@ GEM
22
36
  net-ssh (2.5.2)
23
37
  net-ssh-gateway (1.1.0)
24
38
  net-ssh (>= 1.99.1)
39
+ pry (0.9.9.6)
40
+ coderay (~> 1.0.5)
41
+ method_source (~> 0.7.1)
42
+ slop (>= 2.4.4, < 3)
25
43
  rake (0.9.2.2)
26
44
  rdoc (3.12)
27
45
  json (~> 1.4)
46
+ slop (2.4.4)
28
47
 
29
48
  PLATFORMS
30
49
  ruby
@@ -32,5 +51,8 @@ PLATFORMS
32
51
  DEPENDENCIES
33
52
  bundler (~> 1.0.0)
34
53
  capistrano
54
+ debugger
55
+ debugger-pry
35
56
  jeweler (~> 1.8.3)
57
+ minitest (~> 3.2.0)
36
58
  rdoc (~> 3.12)
@@ -1,7 +1,7 @@
1
1
  = captify
2
2
 
3
3
  == Install
4
- gem install capistrano-templates # default template is stored in this gem
4
+ gem install capistrano-templates # default template stored in this gem
5
5
 
6
6
  For bundler, add this to your Gemfile:
7
7
 
@@ -9,21 +9,12 @@ For bundler, add this to your Gemfile:
9
9
 
10
10
  == Usage
11
11
  cd my_project
12
- bundle exec captify . # use default template: rails-basic
12
+ captify -t rails-base . # use default template: rails-basic
13
13
 
14
14
  It will:
15
15
 
16
16
  1. Run capify.
17
- 2. Overwrite Capistrano files with default template: rails-basic
18
-
19
- To use a different template:
20
-
21
- cd my_project
22
- bundle exec captify -t sinatra-basic .
23
-
24
- === How to load a template gem without bundler?
25
- cd my_project
26
- captify -g capistrano-templates -t rails-basic .
17
+ 2. Overwrite Capistrano files with template: rails-base (see capistrnao-templates[https://github.com/teohm/capistrano-templates]).
27
18
 
28
19
  === See also
29
20
  captify -h
data/Rakefile CHANGED
@@ -27,6 +27,13 @@ Jeweler::RubygemsDotOrgTasks.new
27
27
 
28
28
  task :default => :test
29
29
 
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'spec'
33
+ test.pattern = 'spec/**/*_spec.rb'
34
+ test.verbose = true
35
+ end
36
+
30
37
  require 'rdoc/task'
31
38
  Rake::RDocTask.new do |rdoc|
32
39
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 1.0.0
@@ -1,53 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'captify/template'
4
- require 'optparse'
3
+ require 'captify'
4
+ Captify.run
5
5
 
6
- template_name = 'rails-basic'
7
-
8
- opts = OptionParser.new do |opts|
9
- opts.banner = "Usage: captify [options] directory"
10
-
11
- opts.separator ""
12
- opts.separator "Options:"
13
-
14
- opts.on("-t", "--template TEMPLATE_NAME",
15
- "Specify the template to be used") do |template|
16
- template_name = template
17
- end
18
-
19
- opts.on_tail("-h", "--help", "Show this message") do
20
- puts opts
21
- exit
22
- end
23
- end
24
-
25
- opts.parse!(ARGV)
26
-
27
-
28
- Captify::Template.load_all
29
-
30
- if ARGV.empty?
31
- abort "Please specify the directory to captify, e.g. `#{File.basename($0)} .'\n\n#{opts}"
32
- elsif !File.exists?(ARGV.first)
33
- abort "`#{ARGV.first}' does not exist.\n\n#{opts}"
34
- elsif !File.directory?(ARGV.first)
35
- abort "`#{ARGV.first}' is not a directory.\n\n#{opts}"
36
- elsif ARGV.length > 1
37
- abort "Too many arguments; please specify only the directory to captify.\n\n#{opts}"
38
- end
39
-
40
- base_dir = ARGV.first
41
-
42
- file_paths = Captify::Template.template_files(template_name)
43
-
44
- puts `capify #{base_dir}`
45
-
46
- file_paths.each do |src_path|
47
- dest_path = src_path.split( "#{template_name}" ).last
48
- dest_dir = File.dirname(dest_path)
49
- puts "[captify] Overwrite file '#{base_dir}#{dest_path}'"
50
- `mkdir -p \"#{base_dir}#{dest_dir}\" && cp \"#{src_path}\" \"#{base_dir}#{dest_path}\"`
51
- end
52
-
53
- puts "[captify] Done!"
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "captify"
8
- s.version = "0.2.2"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Huiming Teo"]
12
- s.date = "2012-06-12"
12
+ s.date = "2012-07-16"
13
13
  s.description = "Capistrano capify with canned templates."
14
14
  s.email = "teohuiming@gmail.com"
15
15
  s.executables = ["captify"]
@@ -27,7 +27,37 @@ Gem::Specification.new do |s|
27
27
  "VERSION",
28
28
  "bin/captify",
29
29
  "captify.gemspec",
30
- "lib/captify/template.rb"
30
+ "lib/captify.rb",
31
+ "lib/captify/cli.rb",
32
+ "lib/captify/runner.rb",
33
+ "lib/captify/template.rb",
34
+ "lib/captify/template_bundle.rb",
35
+ "lib/captify/template_loader.rb",
36
+ "lib/captify/template_registrar.rb",
37
+ "spec/captify/cli_spec.rb",
38
+ "spec/captify/runner_spec.rb",
39
+ "spec/captify/template_bundle_spec.rb",
40
+ "spec/captify/template_loader_spec.rb",
41
+ "spec/captify/template_registrar_spec.rb",
42
+ "spec/captify/template_spec.rb",
43
+ "spec/captify_spec.rb",
44
+ "spec/data/files/Gemfile.test_captify",
45
+ "spec/data/files/Gemfile.test_captify.lock",
46
+ "spec/data/files/load_path/not-template/lib/not_template.rb",
47
+ "spec/data/files/load_path/template-without-lib/template_bundle.rb",
48
+ "spec/data/files/load_path/template1/lib/template_bundle.rb",
49
+ "spec/data/files/load_path/template2/lib/template_bundle.rb",
50
+ "spec/data/files/rubygems/gems/not-template-1.0.0/lib/not_template.rb",
51
+ "spec/data/files/rubygems/gems/template1-1.0.0/lib/template_bundle.rb",
52
+ "spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy.rb",
53
+ "spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy/production.rb",
54
+ "spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy/staging.rb",
55
+ "spec/data/files/rubygems/gems/template1-1.0.0/templates/sinatra-base/config/deploy.rb",
56
+ "spec/data/files/rubygems/gems/template2-1.0.0/lib/template_bundle.rb",
57
+ "spec/data/files/rubygems/specifications/not-template-1.0.0.gemspec",
58
+ "spec/data/files/rubygems/specifications/template1-1.0.0.gemspec",
59
+ "spec/data/files/rubygems/specifications/template2-1.0.0.gemspec",
60
+ "spec/helper.rb"
31
61
  ]
32
62
  s.homepage = "http://github.com/teohm/captify"
33
63
  s.licenses = ["MIT"]
@@ -43,17 +73,26 @@ Gem::Specification.new do |s|
43
73
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
44
74
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
45
75
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
76
+ s.add_development_dependency(%q<minitest>, ["~> 3.2.0"])
77
+ s.add_development_dependency(%q<debugger>, [">= 0"])
78
+ s.add_development_dependency(%q<debugger-pry>, [">= 0"])
46
79
  else
47
80
  s.add_dependency(%q<capistrano>, [">= 0"])
48
81
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
49
82
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
50
83
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
84
+ s.add_dependency(%q<minitest>, ["~> 3.2.0"])
85
+ s.add_dependency(%q<debugger>, [">= 0"])
86
+ s.add_dependency(%q<debugger-pry>, [">= 0"])
51
87
  end
52
88
  else
53
89
  s.add_dependency(%q<capistrano>, [">= 0"])
54
90
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
55
91
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
56
92
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
93
+ s.add_dependency(%q<minitest>, ["~> 3.2.0"])
94
+ s.add_dependency(%q<debugger>, [">= 0"])
95
+ s.add_dependency(%q<debugger-pry>, [">= 0"])
57
96
  end
58
97
  end
59
98
 
@@ -0,0 +1,25 @@
1
+ require 'captify/cli'
2
+ require 'captify/template_loader'
3
+ require 'captify/template_registrar'
4
+ require 'captify/template'
5
+ require 'captify/template_bundle'
6
+ require 'captify/runner'
7
+
8
+ module Captify
9
+ def self.run(argv=ARGV, env=ENV)
10
+ opts = Cli.new.parse_argv argv
11
+
12
+ puts `capify #{opts[:target_dir]}`
13
+
14
+ begin
15
+ Runner.new.run(
16
+ opts.delete(:template_name) || ENV['CAPTIFY_TEMPLATE'],
17
+ opts.delete(:target_dir),
18
+ opts
19
+ )
20
+ rescue ArgumentError => ex
21
+ puts ex.message
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,59 @@
1
+ module Captify
2
+
3
+ # Capture inputs from command line interface.
4
+ #
5
+ class Cli
6
+
7
+ def initialize(kernel=Kernel)
8
+ @kernel = kernel
9
+ end
10
+
11
+ def parse_argv(argv)
12
+ options = {}
13
+ argv = argv.clone
14
+ parse_options! argv, options
15
+ parse_target_dir! argv, options
16
+ return options
17
+ rescue AbortException => ex
18
+ @kernel.abort "#{ex.message}"
19
+ rescue ExitException => ex
20
+ @kernel.puts "#{ex.message}"
21
+ @kernel.exit
22
+ end
23
+
24
+ private
25
+
26
+ class AbortException < StandardError; end
27
+ class ExitException < StandardError; end
28
+
29
+ def parse_target_dir!(argv, options)
30
+ if argv.empty?
31
+ raise AbortException, "Please specify a target dir."
32
+ elsif argv.length > 1
33
+ raise AbortException, "Too many target dirs; please specify only the dir to captify."
34
+ end
35
+
36
+ options[:target_dir] = argv.delete_at(0)
37
+ end
38
+
39
+ def parse_options!(argv, options)
40
+ opts = OptionParser.new do |opts|
41
+ opts.banner = "Usage: captify [options] directory"
42
+ opts.separator ""
43
+ opts.separator "Options:"
44
+ opts.on("-t", "--template TEMPLATE_NAME",
45
+ "Specify the template to be used") do |template|
46
+ options[:template_name] = template
47
+ end
48
+ opts.on_tail("-h", "--help", "Show this message") do
49
+ raise ExitException, opts.help
50
+ end
51
+ end
52
+ opts.parse! argv
53
+ return opts.help
54
+ rescue OptionParser::InvalidOption => ex
55
+ raise AbortException, "#{ex.message}\n\n#{opts.help}"
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,31 @@
1
+ module Captify
2
+ class Runner
3
+
4
+ def initialize(template_loader=TemplateLoader.new, kernel=Kernel)
5
+ @template_loader = template_loader
6
+ @kernel = kernel
7
+ @default_options = {:load_path_only => false}
8
+ end
9
+
10
+ def run(template_name, target_dir, options={})
11
+ raise ArgumentError, "'#{target_dir}' does not exist." unless File.exist? target_dir
12
+ raise ArgumentError, "'#{target_dir}' is not a directory." unless File.directory? target_dir
13
+
14
+ options = @default_options.merge(options)
15
+
16
+ @template_loader.reload! options[:load_path_only]
17
+
18
+ template = @template_loader.find(template_name)
19
+ unless template
20
+ raise ArgumentError, "template not found: '#{template_name}'"
21
+ end
22
+
23
+ @kernel.puts "[apply] template '#{template_name}'"
24
+
25
+ logs = template.apply_to(target_dir)
26
+ logs.each{|msg| @kernel.puts msg}
27
+
28
+ @kernel.puts "[done] captified!"
29
+ end
30
+ end
31
+ end
@@ -1,73 +1,31 @@
1
1
  module Captify
2
2
  class Template
3
+ attr_accessor :name, :base_dir, :files
3
4
 
4
- def self.find_files_in_load_path(glob)
5
- $LOAD_PATH.map { |load_path|
6
- Dir["#{File.expand_path glob, load_path}#{Gem.suffix_pattern}"]
7
- }.flatten.select { |file| File.file? file.untaint }
8
- end
9
-
10
- def self.find_files_in_latest_gems(glob, prelease=false)
11
- Gem::Specification.latest_specs(:prelease => prelease).map { |spec|
12
- spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
13
- }.flatten
14
- end
15
-
16
- def self.find_latest_files(glob, check_load_path=true)
17
- files = []
18
- files = find_files_in_load_path(glob) if check_load_path
19
- files.concat find_files_in_latest_gems(glob)
20
- return files
21
- end
22
-
23
- def self.load_all
24
- find_latest_files('captify_template').each do |path|
25
- load path if File.exist? path
26
- end
27
- end
28
-
29
- def self.template_files(template_name)
30
- @@templates ||= {}
31
- @@templates.fetch(template_name, [])
32
- end
5
+ def apply_to(target_dir)
6
+ msg = []
7
+ files.each do |file|
8
+ target_file = File.join(target_dir, file)
9
+ prefix = File.exist?(target_file) ? "[overwrite]" : '[add]'
33
10
 
34
- protected
11
+ FileUtils.mkdir_p File.dirname(target_file)
12
+ FileUtils.cp File.join(base_dir, file), target_file
35
13
 
36
- def self.inherited(subclass)
37
- file_path = extract_file_path caller
38
- templates_path = get_templates_path file_path
39
- dirs = find_all_template_dir templates_path
40
-
41
- @@templates ||= {}
42
- dirs.each do |dir|
43
- name, files = extract_template_name_and_files dir
44
- if @@templates[name].nil?
45
- @@templates[name] = files
46
- else
47
- puts "[captify] warn: template `#{name}' already loaded, ignore `#{file_path}'"
48
- end
14
+ msg << "#{prefix} writing '#{target_file}'"
49
15
  end
16
+ return msg
50
17
  end
51
18
 
52
- def self.extract_template_name_and_files(dir)
53
- name = File.basename dir
54
- files = Dir[ File.join(dir, '**', '*') ]
55
- files = files.select{|path| File.file? path}
56
-
57
- [name, files]
58
- end
59
-
60
- def self.extract_file_path(caller_value)
61
- caller_value.first[/^[^:]+/]
62
- end
19
+ def self.load_from_path(path)
20
+ return nil unless File.exists? path
63
21
 
64
- def self.get_templates_path(file_path)
65
- File.realdirpath File.join(File.dirname(file_path), '..', 'templates')
66
- end
67
-
68
- def self.find_all_template_dir(templates_path)
69
- Dir[ File.join(templates_path, '*') ]
22
+ self.new.tap do |t|
23
+ t.name = File.basename path
24
+ t.base_dir = path
25
+ t.files = Dir[ File.join(path, '**', '*') ].
26
+ select{|item| File.file? item}.
27
+ map{|file| file.sub(path+"/", '')}
28
+ end
70
29
  end
71
30
  end
72
31
  end
73
-
@@ -0,0 +1,38 @@
1
+ require 'captify/template_registrar'
2
+
3
+ module Captify
4
+ class TemplateBundle
5
+ def self.register
6
+ templates_path = find_templates_path(file_path(Kernel.caller.first))
7
+ TemplateRegistrar.instance.register_templates_in_dir templates_path
8
+ end
9
+
10
+ def self.find_templates_path(caller_file_path, root="/")
11
+ base_path = find_base_path(caller_file_path, root)
12
+ File.join(base_path, 'templates')
13
+ end
14
+
15
+ def self.find_base_path(caller_file_path, root="/")
16
+ base_path = File.dirname(File.expand_path(caller_file_path))
17
+ default_base_path = base_path
18
+
19
+ while base_path && File.directory?(base_path) && !File.exist?(File.join(base_path,'lib'))
20
+ parent = File.dirname base_path
21
+ if parent == root
22
+ base_path = default_base_path
23
+ break
24
+ end
25
+ base_path = parent
26
+ end
27
+
28
+ return base_path
29
+ end
30
+
31
+ private
32
+
33
+ def self.file_path(call_stack_item)
34
+ extract_file = /^[^:]+/
35
+ File.expand_path call_stack_item[extract_file]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,46 @@
1
+ module Captify
2
+ class TemplateLoader
3
+
4
+ def initialize(opts={})
5
+ @file_name_pattern = opts.fetch(:file_name_pattern, 'template_bundle')
6
+ @file_suffix_pattern = opts.fetch(:file_suffix_pattern, Gem.suffix_pattern)
7
+
8
+ @load_path = opts.fetch(:load_path, $LOAD_PATH)
9
+ @gem_spec = opts.fetch(:gem_spec, Gem::Specification)
10
+ @kernel = opts.fetch(:kernel, Kernel)
11
+ @file = opts.fetch(:file, File)
12
+ end
13
+
14
+ def reload!(load_path_only=false)
15
+ latest_files(@file_name_pattern, load_path_only).each do |path|
16
+ @kernel.load path if @file.exist? path
17
+ end
18
+ end
19
+
20
+ def find(template_name)
21
+ Captify::TemplateRegistrar.instance.find template_name
22
+ end
23
+
24
+ private
25
+
26
+ def latest_files(glob, load_path_only)
27
+ files = []
28
+ files.concat find_load_path_files(glob)
29
+ files.concat find_latest_gem_files(glob) unless load_path_only
30
+ return files
31
+ end
32
+
33
+ def find_load_path_files(glob)
34
+ @load_path.map { |load_path|
35
+ Dir["#{@file.expand_path glob, load_path}#{@file_suffix_pattern}"]
36
+ }.flatten.select { |file| @file.file? file.untaint }
37
+ end
38
+
39
+ def find_latest_gem_files(glob)
40
+ @gem_spec.latest_specs.map { |spec|
41
+ spec.matches_for_glob("#{glob}#{@file_suffix_pattern}")
42
+ }.flatten
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,44 @@
1
+ require 'captify/template'
2
+
3
+ module Captify
4
+ class TemplateRegistrar
5
+
6
+ def initialize(template_builder=Captify::Template)
7
+ @template_builder = template_builder
8
+ @templates = {}
9
+ end
10
+
11
+ @@instance = TemplateRegistrar.new
12
+
13
+ def self.instance
14
+ @@instance
15
+ end
16
+
17
+ def register_templates_in_dir(root_dir)
18
+ template_dirs(root_dir).each do |dir|
19
+ if template = @template_builder.load_from_path(dir)
20
+ register template
21
+ end
22
+ end
23
+ end
24
+
25
+ def template_count
26
+ @templates.count
27
+ end
28
+
29
+ def register(template)
30
+ @templates[template.name] = template unless @templates.key? template.name
31
+ end
32
+
33
+ def find(template_name)
34
+ @templates[template_name]
35
+ end
36
+
37
+ private
38
+
39
+ def template_dirs(root_path)
40
+ Dir[ File.join(File.expand_path(root_path), '*') ]
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,45 @@
1
+ require 'helper'
2
+
3
+ describe Captify::Cli do
4
+ before do
5
+ @kernel = MiniTest::Mock.new
6
+ @cli = Captify::Cli.new(@kernel)
7
+ end
8
+ describe "Parse options" do
9
+ it "parses all options" do
10
+ opts = @cli.parse_argv %w(-t rails-base .)
11
+ opts.must_equal(
12
+ :target_dir => '.',
13
+ :template_name => 'rails-base'
14
+ )
15
+ end
16
+ it "without template_name" do
17
+ opts = @cli.parse_argv %w(.)
18
+ opts.must_equal(
19
+ :target_dir => '.'
20
+ )
21
+ end
22
+ end
23
+
24
+ describe "Exit exceptions" do
25
+ it "exits when display help" do
26
+ @kernel.expect :puts, nil, [String]
27
+ @kernel.expect :exit, nil, []
28
+ @cli.parse_argv %w(-h)
29
+ @kernel.verify
30
+ end
31
+ end
32
+
33
+ describe "Abort exceptions" do
34
+ it "aborts when missing target dir" do
35
+ @kernel.expect :abort, nil, ["Please specify a target dir."]
36
+ @cli.parse_argv %w(-t rails-base)
37
+ @kernel.verify
38
+ end
39
+ it "aborts when more than one target dir" do
40
+ @kernel.expect :abort, nil, ["Too many target dirs; please specify only the dir to captify."]
41
+ @cli.parse_argv %w(-t rails-base dir1 dir2)
42
+ @kernel.verify
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ require 'helper'
2
+ require 'tmpdir'
3
+
4
+ describe Captify::Runner do
5
+ FILES_DIR = 'spec/data/files'
6
+ LOAD_PATH_DIR = "#{FILES_DIR}/load_path"
7
+ RUBYGEMS_DIR = "#{FILES_DIR}/rubygems"
8
+
9
+ before do
10
+ load_path = [ ]
11
+ gem_spec = Object.new
12
+ def gem_spec.latest_specs
13
+ [ Gem::Specification.load("#{RUBYGEMS_DIR}/specifications/template1-1.0.0.gemspec") ]
14
+ end
15
+
16
+ kernel = Object.new
17
+ def kernel.puts(msg)
18
+ end
19
+
20
+ @runner = Captify::Runner.new(
21
+ Captify::TemplateLoader.new(
22
+ :load_path => load_path,
23
+ :gem_spec => gem_spec
24
+ ),
25
+ kernel
26
+ )
27
+ end
28
+
29
+ it "can captify the target dir" do
30
+ Dir.mktmpdir do |temp_dir|
31
+ @runner.run('rails-base', temp_dir,
32
+ :load_path_only => false,
33
+ :force => false
34
+ )
35
+ File.exist?(File.join(temp_dir, 'config/deploy.rb')).must_equal true
36
+ File.exist?(File.join(temp_dir, 'config/deploy/staging.rb')).must_equal true
37
+ File.exist?(File.join(temp_dir, 'config/deploy/production.rb')).must_equal true
38
+ end
39
+ end
40
+
41
+ it "can handle when template not found" do
42
+ lambda { @runner.run('not-exist', 'not-exist') }.must_raise ArgumentError
43
+ end
44
+
45
+ it "throws error when target dir not exists" do
46
+ lambda { @runner.run('rails-base', 'not-exist') }.must_raise ArgumentError
47
+ end
48
+
49
+ it "throws error when target dir is not a directory" do
50
+ lambda { @runner.run('rails-base', __FILE__) }.must_raise ArgumentError
51
+ end
52
+ end
@@ -0,0 +1,30 @@
1
+ require 'helper'
2
+
3
+ describe Captify::TemplateBundle do
4
+
5
+ describe "Subclass Captify::Template" do
6
+ it "finds templates/ dir in root path" do
7
+ caller_file_path = File.expand_path('spec/data/files/rubygems/gems/template1-1.0.0/lib/template_bundle.rb')
8
+ path = Captify::TemplateBundle.find_templates_path(caller_file_path, File.expand_path('.'))
9
+ path.must_equal File.expand_path('spec/data/files/rubygems/gems/template1-1.0.0/templates')
10
+ end
11
+
12
+ it "treats template_bundle.rb parent dir as root path if cannot find lib/ dir" do
13
+ caller_file_path = File.expand_path 'spec/data/files/load_path/template-without-lib/template_bundle.rb'
14
+ path = Captify::TemplateBundle.find_templates_path(caller_file_path, File.expand_path('.'))
15
+ path.must_equal File.expand_path('spec/data/files/load_path/template-without-lib/templates')
16
+ end
17
+
18
+ it "passes dirname correctly into Template Registrar." do
19
+ received_path = ""
20
+ Captify::TemplateRegistrar.instance.stub :register_templates_in_dir,
21
+ lambda{|path| received_path = path} do
22
+
23
+ load 'spec/data/files/load_path/template1/lib/template_bundle.rb'
24
+
25
+ end
26
+ received_path.must_equal File.expand_path('spec/data/files/load_path/template1/templates')
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,57 @@
1
+ require 'helper'
2
+
3
+ describe Captify::TemplateLoader do
4
+
5
+ before do
6
+ @file_dir = 'spec/data/files'
7
+ @load_path_dir = "#{@file_dir}/load_path"
8
+ @rubygems_dir = "#{@file_dir}/rubygems"
9
+
10
+ @load_path = [
11
+ "#{@load_path_dir}/template1/lib",
12
+ "#{@load_path_dir}/template2/lib",
13
+ "#{@load_path_dir}/not-template/lib"
14
+ ]
15
+ @gem_spec = MiniTest::Mock.new
16
+ @gem_spec.expect :latest_specs, [
17
+ Gem::Specification.load("#{@rubygems_dir}/specifications/template1-1.0.0.gemspec"),
18
+ Gem::Specification.load("#{@rubygems_dir}/specifications/template2-1.0.0.gemspec"),
19
+ Gem::Specification.load("#{@rubygems_dir}/specifications/not-template-1.0.0.gemspec")
20
+ ]
21
+ @kernel = MiniTest::Mock.new
22
+
23
+ @loader = Captify::TemplateLoader.new(
24
+ :load_path => @load_path,
25
+ :gem_spec => @gem_spec,
26
+ :kernel => @kernel)
27
+ end
28
+
29
+ it "can load captify_template.rb from load paths, then from latest gems." do
30
+ [
31
+ "#{@load_path_dir}/template1",
32
+ "#{@load_path_dir}/template2",
33
+ "#{@rubygems_dir}/gems/template1-1.0.0",
34
+ "#{@rubygems_dir}/gems/template2-1.0.0"
35
+ ].each do |path|
36
+ @kernel.expect :load, nil, [File.expand_path("#{path}/lib/template_bundle.rb")]
37
+ end
38
+
39
+ @loader.reload!
40
+
41
+ @kernel.verify
42
+ end
43
+
44
+ it "can load captify_template.rb from load paths only." do
45
+ load_path_only = true
46
+ [
47
+ "#{@load_path_dir}/template1",
48
+ "#{@load_path_dir}/template2"
49
+ ].each do |path|
50
+ @kernel.expect :load, nil, [File.expand_path("#{path}/lib/template_bundle.rb")]
51
+ end
52
+
53
+ @loader.reload! load_path_only
54
+
55
+ @kernel.verify
56
+ end
57
+ end
@@ -0,0 +1,46 @@
1
+ require 'helper'
2
+
3
+ describe "Register template" do
4
+
5
+ it "can register all templates under templates/" do
6
+
7
+ templates_path = 'spec/data/files/rubygems/gems/template1-1.0.0/templates'
8
+ template_builder = MiniTest::Mock.new
9
+ registrar = Captify::TemplateRegistrar.new(template_builder)
10
+
11
+ fake_template1 = Captify::Template.new.tap do |t|
12
+ t.name = 'rails-base'
13
+ end
14
+ fake_template2 = Captify::Template.new.tap do |t|
15
+ t.name = 'sinatra-base'
16
+ end
17
+ fake_template3 = Captify::Template.new.tap do |t|
18
+ t.name = 'no-file'
19
+ end
20
+ template_builder.expect :load_from_path, fake_template3,
21
+ [File.expand_path(File.join(templates_path, 'no-file'))]
22
+ template_builder.expect :load_from_path, fake_template1,
23
+ [File.expand_path(File.join(templates_path, 'rails-base'))]
24
+ template_builder.expect :load_from_path, fake_template2,
25
+ [File.expand_path(File.join(templates_path, 'sinatra-base'))]
26
+
27
+ registrar.register_templates_in_dir templates_path
28
+
29
+ template_builder.verify
30
+ registrar.template_count.must_equal 3
31
+ registrar.find('rails-base').must_be_same_as fake_template1
32
+ registrar.find('sinatra-base').must_be_same_as fake_template2
33
+ registrar.find('no-file').must_be_same_as fake_template3
34
+ end
35
+
36
+ it "can handle when templates/ does not exist." do
37
+
38
+ templates_path = 'spec/data/files/rubygems/gems/template2-1.0.0/templates'
39
+ registrar = Captify::TemplateRegistrar.new
40
+
41
+ registrar.register_templates_in_dir templates_path
42
+
43
+ registrar.template_count.must_equal 0
44
+ end
45
+
46
+ end
@@ -0,0 +1,60 @@
1
+ require 'helper'
2
+ require 'tmpdir'
3
+
4
+ describe Captify::Template do
5
+ it "can create new template by parsing a dir path." do
6
+ template_path = 'spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base'
7
+
8
+ template = Captify::Template.load_from_path template_path
9
+
10
+ template.name.must_equal "rails-base"
11
+ template.base_dir.must_equal template_path
12
+ template.files.sort.must_equal [
13
+ 'config/deploy.rb',
14
+ 'config/deploy/staging.rb',
15
+ 'config/deploy/production.rb'
16
+ ].sort
17
+ end
18
+
19
+ it "can handle when template dir path empty." do
20
+ template_path = 'spec/data/files/rubygems/gems/template1-1.0.0/templates/no-file'
21
+
22
+ template = Captify::Template.load_from_path template_path
23
+
24
+ template.name.must_equal "no-file"
25
+ template.base_dir.must_equal template_path
26
+ template.files.must_equal []
27
+ end
28
+
29
+ it "can apply template to target dir" do
30
+ template_path = 'spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base'
31
+ template = Captify::Template.load_from_path template_path
32
+
33
+ Dir.mktmpdir do |temp_dir|
34
+ template.apply_to temp_dir
35
+
36
+ File.file?(File.join(temp_dir, 'config/deploy.rb')).must_equal true
37
+ File.file?(File.join(temp_dir, 'config/deploy/staging.rb')).must_equal true
38
+ File.file?(File.join(temp_dir, 'config/deploy/production.rb')).must_equal true
39
+ end
40
+ end
41
+
42
+ it "always overwrites existing files in target dir" do
43
+ template_path = 'spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base'
44
+ template = Captify::Template.load_from_path template_path
45
+
46
+ Dir.mktmpdir do |temp_dir|
47
+
48
+ deploy_rb = File.join(temp_dir, 'config/deploy.rb')
49
+ FileUtils.mkdir_p File.dirname(deploy_rb)
50
+ File.open(deploy_rb, 'w') {|f| f.write("test") }
51
+
52
+ template.apply_to temp_dir
53
+
54
+ File.open(deploy_rb) {|f| f.read }.wont_equal "test"
55
+ File.file?(File.join(temp_dir, 'config/deploy.rb')).must_equal true
56
+ File.file?(File.join(temp_dir, 'config/deploy/staging.rb')).must_equal true
57
+ File.file?(File.join(temp_dir, 'config/deploy/production.rb')).must_equal true
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,18 @@
1
+ require 'helper'
2
+ require 'tmpdir'
3
+
4
+ describe Captify do
5
+ it "can run captify" do
6
+ Dir.mktmpdir do |tmp_dir|
7
+ ENV['CAPTIFY_TEMPLATE'] = 'rails-base'
8
+ ENV['BUNDLE_GEMFILE'] = 'spec/data/files/Gemfile.test_captify'
9
+
10
+ `bundle exec ./bin/captify #{tmp_dir}`
11
+
12
+ File.exist?(File.join(tmp_dir, 'Capfile')).must_equal true
13
+ File.exist?(File.join(tmp_dir, 'config/deploy.rb')).must_equal true
14
+ File.exist?(File.join(tmp_dir, 'config/deploy/staging.rb')).must_equal true
15
+ File.exist?(File.join(tmp_dir, 'config/deploy/production.rb')).must_equal true
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,2 @@
1
+ gem 'template2-1.0.0', '1.0.0', :path => 'rubygems/gems/template1-1.0.0'
2
+ gem 'captify', :path => '../../..'
@@ -0,0 +1,34 @@
1
+ PATH
2
+ remote: ../../..
3
+ specs:
4
+ captify (0.2.2)
5
+ capistrano
6
+
7
+ PATH
8
+ remote: rubygems/gems/template1-1.0.0
9
+ specs:
10
+ template2-1.0.0 (1.0.0)
11
+
12
+ GEM
13
+ specs:
14
+ capistrano (2.12.0)
15
+ highline
16
+ net-scp (>= 1.0.0)
17
+ net-sftp (>= 2.0.0)
18
+ net-ssh (>= 2.0.14)
19
+ net-ssh-gateway (>= 1.1.0)
20
+ highline (1.6.13)
21
+ net-scp (1.0.4)
22
+ net-ssh (>= 1.99.1)
23
+ net-sftp (2.0.5)
24
+ net-ssh (>= 2.0.9)
25
+ net-ssh (2.5.2)
26
+ net-ssh-gateway (1.1.0)
27
+ net-ssh (>= 1.99.1)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ captify!
34
+ template2-1.0.0 (= 1.0.0)!
@@ -0,0 +1 @@
1
+ Captify::TemplateBundle.register
@@ -0,0 +1 @@
1
+ Captify::TemplateBundle.register
@@ -0,0 +1 @@
1
+ Captify::TemplateBundle.register
@@ -0,0 +1 @@
1
+ Captify::TemplateBundle.register
@@ -0,0 +1 @@
1
+ Captify::TemplateBundle.register
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "not-template"
5
+ s.version = "1.0.0"
6
+
7
+ s.files = [
8
+ "lib/not_template.rb"
9
+ ]
10
+ s.require_paths = ["lib"]
11
+ s.rubygems_version = "1.8.24"
12
+ s.summary = "Not Template"
13
+
14
+ end
15
+
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "template1"
5
+ s.version = "1.0.0"
6
+
7
+ s.files = [
8
+ "lib/template_bundle.rb"
9
+ ]
10
+ s.require_paths = ["lib"]
11
+ s.rubygems_version = "1.8.24"
12
+ s.summary = "Template 1"
13
+
14
+ end
15
+
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "template2"
5
+ s.version = "1.0.0"
6
+
7
+ s.files = [
8
+ "lib/template_bundle.rb"
9
+ ]
10
+ s.require_paths = ["lib"]
11
+ s.rubygems_version = "1.8.24"
12
+ s.summary = "Template 2"
13
+
14
+ end
15
+
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'minitest/spec'
11
+ require 'minitest/autorun'
12
+ require 'minitest/pride'
13
+
14
+ require 'debugger'
15
+ require 'debugger/pry'
16
+
17
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
19
+ require 'captify'
20
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: captify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-12 00:00:00.000000000 Z
12
+ date: 2012-07-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -75,6 +75,54 @@ dependencies:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
77
  version: 1.8.3
78
+ - !ruby/object:Gem::Dependency
79
+ name: minitest
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 3.2.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: 3.2.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: debugger
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: debugger-pry
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
78
126
  description: Capistrano capify with canned templates.
79
127
  email: teohuiming@gmail.com
80
128
  executables:
@@ -93,7 +141,37 @@ files:
93
141
  - VERSION
94
142
  - bin/captify
95
143
  - captify.gemspec
144
+ - lib/captify.rb
145
+ - lib/captify/cli.rb
146
+ - lib/captify/runner.rb
96
147
  - lib/captify/template.rb
148
+ - lib/captify/template_bundle.rb
149
+ - lib/captify/template_loader.rb
150
+ - lib/captify/template_registrar.rb
151
+ - spec/captify/cli_spec.rb
152
+ - spec/captify/runner_spec.rb
153
+ - spec/captify/template_bundle_spec.rb
154
+ - spec/captify/template_loader_spec.rb
155
+ - spec/captify/template_registrar_spec.rb
156
+ - spec/captify/template_spec.rb
157
+ - spec/captify_spec.rb
158
+ - spec/data/files/Gemfile.test_captify
159
+ - spec/data/files/Gemfile.test_captify.lock
160
+ - spec/data/files/load_path/not-template/lib/not_template.rb
161
+ - spec/data/files/load_path/template-without-lib/template_bundle.rb
162
+ - spec/data/files/load_path/template1/lib/template_bundle.rb
163
+ - spec/data/files/load_path/template2/lib/template_bundle.rb
164
+ - spec/data/files/rubygems/gems/not-template-1.0.0/lib/not_template.rb
165
+ - spec/data/files/rubygems/gems/template1-1.0.0/lib/template_bundle.rb
166
+ - spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy.rb
167
+ - spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy/production.rb
168
+ - spec/data/files/rubygems/gems/template1-1.0.0/templates/rails-base/config/deploy/staging.rb
169
+ - spec/data/files/rubygems/gems/template1-1.0.0/templates/sinatra-base/config/deploy.rb
170
+ - spec/data/files/rubygems/gems/template2-1.0.0/lib/template_bundle.rb
171
+ - spec/data/files/rubygems/specifications/not-template-1.0.0.gemspec
172
+ - spec/data/files/rubygems/specifications/template1-1.0.0.gemspec
173
+ - spec/data/files/rubygems/specifications/template2-1.0.0.gemspec
174
+ - spec/helper.rb
97
175
  homepage: http://github.com/teohm/captify
98
176
  licenses:
99
177
  - MIT
@@ -109,7 +187,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
187
  version: '0'
110
188
  segments:
111
189
  - 0
112
- hash: -4128769129857961565
190
+ hash: -177249211097526545
113
191
  required_rubygems_version: !ruby/object:Gem::Requirement
114
192
  none: false
115
193
  requirements: