contao 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/contao ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'contao/cli'
data/lib/contao.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'contao/version'
2
+ require 'core_ext/object'
2
3
  require 'singleton'
3
4
  require 'ostruct'
4
5
 
@@ -1,3 +1,5 @@
1
+ require 'yaml'
2
+
1
3
  module TechnoGate
2
4
  module Contao
3
5
  class Application < OpenStruct
@@ -5,7 +7,9 @@ module TechnoGate
5
7
 
6
8
  def initialize
7
9
  super
8
- self.config = OpenStruct.new
10
+
11
+ init_config
12
+ parse_global_config
9
13
  end
10
14
 
11
15
  def self.configure(&block)
@@ -34,15 +38,54 @@ module TechnoGate
34
38
  end
35
39
 
36
40
  def name
37
- File.basename TechnoGate::Contao.root
41
+ self.config.application_name || File.basename(Contao.root)
38
42
  end
39
43
 
40
44
  def self.name
41
45
  instance.name
42
46
  end
43
47
 
48
+ def self.default_global_config(options = {})
49
+ {
50
+ 'install_password' => '',
51
+ 'encryption_key' => '',
52
+ 'admin_email' => 'wael@technogate.fr',
53
+ 'time_zone' => 'Europe/Paris',
54
+ 'mysql' => {
55
+ 'host' => 'localhost',
56
+ 'user' => 'root',
57
+ 'pass' => 'toor',
58
+ 'port' => 3306,
59
+ },
60
+ 'smtp' => {
61
+ 'enabled' => false,
62
+ 'host' => '',
63
+ 'user' => '',
64
+ 'pass' => '',
65
+ 'ssl' => true,
66
+ 'port' => 465,
67
+ },
68
+ }.merge(options)
69
+ end
70
+
71
+ def global_config_path
72
+ "#{ENV['HOME']}/.contao/config.yml"
73
+ end
74
+
44
75
  protected
45
76
 
77
+ # Initialize the config
78
+ def init_config
79
+ self.config = OpenStruct.new
80
+ end
81
+
82
+ # Parse the global yaml configuration file
83
+ def parse_global_config
84
+ if File.exists? global_config_path
85
+ self.config.global = YAML.load(File.read(global_config_path)).to_openstruct
86
+ end
87
+ end
88
+
46
89
  # Return an array of arrays of files to link
47
90
  #
48
91
  # @param [String] Absolute path to folder from which to link
data/lib/contao/cli.rb ADDED
@@ -0,0 +1,3 @@
1
+ Signal.trap("INT") { puts; exit(1) }
2
+
3
+ require 'contao/commands/application'
@@ -0,0 +1,15 @@
1
+ require 'contao/version'
2
+
3
+ if ['--version', '-v'].include? ARGV.first
4
+ puts "Contao #{Contao::VERSION}"
5
+ exit(0)
6
+ end
7
+
8
+ case ARGV[0]
9
+ when 'new'
10
+ require 'contao/generators/application'
11
+ TechnoGate::Contao::Generators::Application.new(path: ARGV[1]).generate
12
+ else
13
+ require 'contao/commands/help'
14
+ print_help
15
+ end
@@ -0,0 +1,20 @@
1
+ def print_help
2
+ puts <<-EOH.gsub(/ [ ]+/, ' ')
3
+ Welcome to Contao!
4
+
5
+ This gem will help you to quickly generate an application using contao
6
+ that has pre-built support for Sass, Compass, CoffeeScript, Jasmine and
7
+ Capistrano.
8
+
9
+ It also feature hashed assets served by the Contao Assets extension, this
10
+ allows you to have an md5 appended to each of your assets file name
11
+
12
+ To generate a new project, use the following command:
13
+
14
+ $ contao new /path/to/application
15
+
16
+ The generated application will be created at /path/to/application and the
17
+ application name would be set to the last component in the path, in this
18
+ case it would be application
19
+ EOH
20
+ end
@@ -0,0 +1,77 @@
1
+ require 'contao/generators/base'
2
+ require 'contao/system'
3
+
4
+ module TechnoGate
5
+ module Contao
6
+ module Generators
7
+ class Application < Base
8
+ REPO_URL = 'https://github.com/TechnoGate/contao_template.git'
9
+
10
+ def generate
11
+ clone_template
12
+ rename_project
13
+ run_bundle_install
14
+ run_cap_multistage_setup
15
+ commit_everything
16
+ replace_origin_with_template
17
+ end
18
+
19
+ protected
20
+ def clone_template
21
+ git_args = "clone --recursive #{REPO_URL} #{project_path}"
22
+ Contao::System.safe_system 'git', *git_args.split(' ')
23
+ end
24
+
25
+ def rename_project
26
+ config = File.read(config_application_path)
27
+ File.open(config_application_path, 'w') do |file|
28
+ file.write config.gsub(/contao_template/, project_name)
29
+ end
30
+ end
31
+
32
+ def run_bundle_install
33
+ Dir.chdir project_path do
34
+ Contao::System.safe_system 'bundle', 'install'
35
+ end
36
+ end
37
+
38
+ def run_cap_multistage_setup
39
+ Dir.chdir project_path do
40
+ Contao::System.safe_system 'bundle', 'exec', 'cap', 'multistage:setup'
41
+ end
42
+ end
43
+
44
+ def commit_everything
45
+ Dir.chdir project_path do
46
+ Contao::System.safe_system('git', 'add', '-A', '.')
47
+ Contao::System.safe_system(
48
+ 'git',
49
+ 'commit',
50
+ '-m',
51
+ 'Import generated files inside the repository'
52
+ )
53
+ end
54
+ end
55
+
56
+ def replace_origin_with_template
57
+ Dir.chdir project_path do
58
+ Contao::System.safe_system 'git', 'remote', 'rm', 'origin'
59
+ Contao::System.safe_system 'git', 'remote', 'add', 'template', REPO_URL
60
+ end
61
+ end
62
+
63
+ def config_application_path
64
+ "#{project_path}/config/application.rb"
65
+ end
66
+
67
+ def project_path
68
+ @options[:path]
69
+ end
70
+
71
+ def project_name
72
+ File.basename project_path
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,15 @@
1
+ module TechnoGate
2
+ module Contao
3
+ module Generators
4
+ class Base
5
+ def initialize(options = {})
6
+ @options = options
7
+ end
8
+
9
+ def generate
10
+
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -19,6 +19,20 @@ module TechnoGate
19
19
  def self.notify(*args, &block)
20
20
  instance.notify(*args, &block)
21
21
  end
22
+
23
+ def warn(message, options = {})
24
+ if ::Guard::UI.send(:color_enabled?)
25
+ message = "\e[0;34mContao>>\e[0m \e[0;33m#{message}\e[0m"
26
+ else
27
+ message = "Contao>> #{message}"
28
+ end
29
+
30
+ ::Guard::UI.info(message, options)
31
+ end
32
+
33
+ def self.warn(*args, &block)
34
+ instance.warn(*args, &block)
35
+ end
22
36
  end
23
37
  end
24
38
  end
@@ -0,0 +1,34 @@
1
+ module TechnoGate
2
+ module Contao
3
+ class System
4
+ class ErrorDuringExecution < RuntimeError; end
5
+
6
+ def self.system cmd, *args
7
+ fork do
8
+ yield if block_given?
9
+ args.collect!{|arg| arg.to_s}
10
+ exec(cmd, *args) rescue nil
11
+ exit! 1 # never gets here unless exec failed
12
+ end
13
+ Process.wait
14
+ $?.success?
15
+ end
16
+
17
+ # Kernel.system but with exceptions
18
+ def self.safe_system cmd, *args
19
+ unless self.system cmd, *args
20
+ args = args.map{ |arg| arg.to_s.gsub " ", "\\ " } * " "
21
+ raise ErrorDuringExecution, "Failure while executing: #{cmd} #{args}"
22
+ end
23
+ end
24
+
25
+ # prints no output
26
+ def self.quiet_system cmd, *args
27
+ self.system(cmd, *args) do
28
+ $stdout.close
29
+ $stderr.close
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -83,30 +83,31 @@ namespace :contao do
83
83
 
84
84
  desc "Generate the localconfig.php"
85
85
  task :generate_localconfig do
86
- require 'parseconfig'
87
-
88
- my_cnf_path = File.expand_path("#{ENV['HOME']}/.my.cnf")
89
- localconfig_template = TechnoGate::Contao.expandify('config/examples/localconfig.php.erb')
90
- localconfig_path = TechnoGate::Contao.expandify(TechnoGate::Contao::Application.config.contao_public_path).join('system/config/localconfig.php')
91
-
92
- if File.exists?(my_cnf_path)
93
- my_cnf = ParseConfig.new(my_cnf_path)
94
- mysql_host = my_cnf.params['client']['host']
95
- mysql_user = my_cnf.params['client']['user']
96
- mysql_password = my_cnf.params['client']['password']
86
+ require 'active_support/core_ext/object/blank'
87
+ config = TechnoGate::Contao::Application.config.global
88
+
89
+ if !config && config.install_password.blank? || config.encryption_key.blank?
90
+ message = <<-EOS
91
+ You did not set the install password, and the encryption key in your
92
+ #{ENV['HOME']}/.contao/config.yml, I cannot generate a localconfig
93
+ since the required configuration keys are missing.
94
+ EOS
95
+ message.gsub!(/ [ ]+/, ' ').gsub!(/\n/, '').gsub!(/^ /, '')
96
+ TechnoGate::Contao::Notifier.warn(message, title: "Contao Bootstrap")
97
97
  else
98
- puts "Please add these details to #{my_cnf_path}"
99
- mysql_host = ask("What host is mysql running on", default: 'localhost', validate: /.+/)
100
- mysql_user = ask("What user to use with mysql", validate: /.+/)
101
- mysql_password = ask("What is the user's password", validate: /.+/, echo: false)
102
- end
103
- mysql_database = TechnoGate::Contao::Application.name
104
- contao_env = TechnoGate::Contao.env
98
+ config = config.clone
99
+ config.contao_env = TechnoGate::Contao.env
100
+ config.application_name = TechnoGate::Contao::Application.name
101
+ config.mysql.database = config.application_name
105
102
 
106
- localconfig = ERB.new(File.read(localconfig_template)).result(binding)
107
- File.open(localconfig_path, 'w') {|f| f.write localconfig }
103
+ localconfig_template = TechnoGate::Contao.expandify('config/examples/localconfig.php.erb')
104
+ localconfig_path = TechnoGate::Contao.expandify(TechnoGate::Contao::Application.config.contao_public_path).join('system/config/localconfig.php')
108
105
 
109
- TechnoGate::Contao::Notifier.notify("The configuration file localconfig.php was generated successfully.", title: "Contao Bootstrap")
106
+ localconfig = ERB.new(File.read(localconfig_template)).result(binding)
107
+ File.open(localconfig_path, 'w') {|f| f.write localconfig }
108
+
109
+ TechnoGate::Contao::Notifier.notify("The configuration file localconfig.php was generated successfully.", title: "Contao Bootstrap")
110
+ end
110
111
  end
111
112
 
112
113
  desc "Generate the htaccess file"
@@ -1,3 +1,3 @@
1
1
  module Contao
2
- VERSION = '0.3.4'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -0,0 +1,16 @@
1
+ class ::Object
2
+ def to_openstruct
3
+ case self
4
+ when Hash
5
+ object = self.clone
6
+ object.each do |key, value|
7
+ object[key] = value.to_openstruct
8
+ end
9
+ OpenStruct.new(object)
10
+ when Array
11
+ self.clone.map! { |i| i.to_openstruct }
12
+ else
13
+ self
14
+ end
15
+ end
16
+ end
@@ -2,88 +2,94 @@ require 'spec_helper'
2
2
 
3
3
  module TechnoGate
4
4
  module Contao
5
- describe Application do
5
+ describe Application, :fakefs do
6
6
  subject { Contao::Application.instance }
7
7
  let(:klass) { Contao::Application }
8
8
 
9
- it_should_behave_like "Singleton"
10
-
11
- it "should be an open struct" do
12
- subject.class.superclass.should == OpenStruct
9
+ before :each do
10
+ stub_filesystem!(:global_config => {'install_password' => 'some install password'})
11
+ subject.send :parse_global_config
13
12
  end
14
13
 
15
- it "should have a config as a superclass" do
16
- subject.config.class.should == OpenStruct
17
- end
14
+ it_should_behave_like 'Config'
18
15
 
19
- describe "config" do
20
- it "should set a configuration variable using a block" do
21
- Contao::Application.configure do
22
- config.foo = :bar
23
- end
16
+ describe "Global Config" do
24
17
 
25
- Contao::Application.instance.config.foo.should == :bar
18
+ it "should parse the global config file if the file exists" do
19
+ subject.config.global.should_not be_empty
26
20
  end
27
21
 
28
- it "should be accessible form the class level" do
29
- Contao::Application.configure do
30
- config.foo = :bar
31
- end
32
-
33
- Contao::Application.config.foo.should == :bar
22
+ it "should correctly parse the global config" do
23
+ subject.config.global.install_password.should == 'some install password'
34
24
  end
25
+ end
35
26
 
36
- describe '#linkify', :fakefs do
37
- before :each do
38
- stub_filesystem!
39
- end
27
+ describe '#linkify' do
28
+ it "should call #exhaustive_list_of_files_to_link" do
29
+ subject.should_receive(:exhaustive_list_of_files_to_link).with(
30
+ Contao.expandify(Application.config.contao_path),
31
+ Contao.expandify(Application.config.contao_public_path)
32
+ ).once.and_return []
40
33
 
41
- it "should call #exhaustive_list_of_files_to_link" do
42
- subject.should_receive(:exhaustive_list_of_files_to_link).with(
43
- Contao.expandify(Application.config.contao_path),
44
- Contao.expandify(Application.config.contao_public_path)
45
- ).once.and_return []
34
+ subject.linkify
35
+ end
46
36
 
47
- subject.linkify
48
- end
37
+ it "should actually link the files" do
38
+ subject.linkify
49
39
 
50
- it "should actually link the files" do
51
- subject.linkify
40
+ File.exists?('/root/my_awesome_project/public/non_existing_folder').should be_true
41
+ File.exists?('/root/my_awesome_project/public/system/modules/some_extension').should be_true
42
+ end
52
43
 
53
- File.exists?('/root/public/non_existing_folder').should be_true
54
- File.exists?('/root/public/system/modules/some_extension').should be_true
55
- end
44
+ it "should be accessible at class level" do
45
+ subject.should_receive(:linkify).once
56
46
 
57
- it "should be accessible at class level" do
58
- subject.should_receive(:linkify).once
47
+ Application.linkify
48
+ end
49
+ end
59
50
 
60
- Application.linkify
61
- end
51
+ describe '#exhaustive_list_of_files_to_link' do
52
+ it "should return the correct list of files" do
53
+ list = subject.send :exhaustive_list_of_files_to_link, '/root/my_awesome_project/contao', '/root/my_awesome_project/public'
54
+ list.should == [
55
+ ['/root/my_awesome_project/contao/non_existing_folder', '/root/my_awesome_project/public/non_existing_folder'],
56
+ ['/root/my_awesome_project/contao/system/modules/some_extension', '/root/my_awesome_project/public/system/modules/some_extension']
57
+ ]
62
58
  end
59
+ end
60
+
61
+ describe '#name' do
62
+ it {should respond_to :name}
63
63
 
64
- describe '#exhaustive_list_of_files_to_link', :fakefs do
64
+ describe "without it being set in the configuration" do
65
65
  before :each do
66
- stub_filesystem!
66
+ TechnoGate::Contao::Application.configure do
67
+ config.application_name = nil
68
+ end
69
+ end
70
+
71
+ it "should return the correct name" do
72
+ subject.name.should == 'my_awesome_project'
67
73
  end
68
74
 
69
- it "should return the correct list of files" do
70
- list = subject.send :exhaustive_list_of_files_to_link, '/root/contao', '/root/public'
71
- list.should == [
72
- ['/root/contao/non_existing_folder', '/root/public/non_existing_folder'],
73
- ['/root/contao/system/modules/some_extension', '/root/public/system/modules/some_extension']
74
- ]
75
+ it "should be accessible at class level" do
76
+ Application.name.should == 'my_awesome_project'
75
77
  end
76
78
  end
77
79
 
78
- describe '#name' do
79
- it {should respond_to :name}
80
+ describe "with it being set in the configuration" do
81
+ before :each do
82
+ TechnoGate::Contao::Application.configure do
83
+ config.application_name = 'my_super_awesome_project'
84
+ end
85
+ end
80
86
 
81
- it "should return the correct name" do
82
- subject.name.should == 'root'
87
+ it "should be my_awesome_project" do
88
+ subject.name.should == 'my_super_awesome_project'
83
89
  end
84
90
 
85
91
  it "should be accessible at class level" do
86
- Application.name.should == 'root'
92
+ Application.name.should == 'my_super_awesome_project'
87
93
  end
88
94
  end
89
95
  end
@@ -16,18 +16,18 @@ module TechnoGate
16
16
  stub_filesystem!
17
17
 
18
18
  [
19
- '/root/app/assets/javascripts/simple_coffeescript_file.js.coffee',
20
- '/root/app/assets/javascripts/simple_javascript_file.js',
21
- '/root/app/assets/javascripts/nested/script.js.coffee',
22
- '/root/lib/assets/javascripts/simple_coffeescript_file.js.coffee',
23
- '/root/vendor/assets/javascripts/simple_coffeescript_file.js.coffee',
19
+ '/root/my_awesome_project/app/assets/javascripts/simple_coffeescript_file.js.coffee',
20
+ '/root/my_awesome_project/app/assets/javascripts/simple_javascript_file.js',
21
+ '/root/my_awesome_project/app/assets/javascripts/nested/script.js.coffee',
22
+ '/root/my_awesome_project/lib/assets/javascripts/simple_coffeescript_file.js.coffee',
23
+ '/root/my_awesome_project/vendor/assets/javascripts/simple_coffeescript_file.js.coffee',
24
24
  ].each do |file|
25
25
  FileUtils.mkdir_p File.dirname(file)
26
26
  File.open(file, 'w') do |f|
27
27
  f.write file.
28
- gsub('/root/app/assets/javascripts/', '').
29
- gsub('/root/lib/assets/javascripts/', '').
30
- gsub('/root/vendor/assets/javascripts/', '')
28
+ gsub('/root/my_awesome_project/app/assets/javascripts/', '').
29
+ gsub('/root/my_awesome_project/lib/assets/javascripts/', '').
30
+ gsub('/root/my_awesome_project/vendor/assets/javascripts/', '')
31
31
  end
32
32
  end
33
33
  end
@@ -35,28 +35,28 @@ module TechnoGate
35
35
  it "should compile coffeescripts" do
36
36
  subject.send :compile_assets
37
37
 
38
- File.exists?('/root/tmp/compiled_javascript/app_assets_javascripts/simple_coffeescript_file.js').should be_true
39
- File.exists?('/root/tmp/compiled_javascript/lib_assets_javascripts/simple_coffeescript_file.js').should be_true
40
- File.exists?('/root/tmp/compiled_javascript/vendor_assets_javascripts/simple_coffeescript_file.js').should be_true
41
- File.exists?('/root/tmp/compiled_javascript/app_assets_javascripts/simple_javascript_file').should be_false
42
- File.exists?('/root/tmp/compiled_javascript/app_assets_javascripts/nested/script.js').should be_true
38
+ File.exists?('/root/my_awesome_project/tmp/compiled_javascript/app_assets_javascripts/simple_coffeescript_file.js').should be_true
39
+ File.exists?('/root/my_awesome_project/tmp/compiled_javascript/lib_assets_javascripts/simple_coffeescript_file.js').should be_true
40
+ File.exists?('/root/my_awesome_project/tmp/compiled_javascript/vendor_assets_javascripts/simple_coffeescript_file.js').should be_true
41
+ File.exists?('/root/my_awesome_project/tmp/compiled_javascript/app_assets_javascripts/simple_javascript_file').should be_false
42
+ File.exists?('/root/my_awesome_project/tmp/compiled_javascript/app_assets_javascripts/nested/script.js').should be_true
43
43
  end
44
44
  end
45
45
 
46
46
  describe "#compute_destination_filename" do
47
47
  it "should be able to compute given a relative file" do
48
48
  subject.send(:compute_destination_filename, "app/js", "app/js/file.js.coffee").should ==
49
- "/root/tmp/compiled_javascript/app_js/file.js"
49
+ "/root/my_awesome_project/tmp/compiled_javascript/app_js/file.js"
50
50
  end
51
51
 
52
52
  it "should be able to compute given an absolute file" do
53
- subject.send(:compute_destination_filename, "app/js", "/root/app/js/file.js.coffee").should ==
54
- "/root/tmp/compiled_javascript/app_js/file.js"
53
+ subject.send(:compute_destination_filename, "app/js", "/root/my_awesome_project/app/js/file.js.coffee").should ==
54
+ "/root/my_awesome_project/tmp/compiled_javascript/app_js/file.js"
55
55
  end
56
56
 
57
57
  it "should add automaticallty .js extension" do
58
58
  subject.send(:compute_destination_filename, "app/js", "app/js/file.coffee").should ==
59
- "/root/tmp/compiled_javascript/app_js/file.js"
59
+ "/root/my_awesome_project/tmp/compiled_javascript/app_js/file.js"
60
60
  end
61
61
  end
62
62
 
@@ -64,13 +64,13 @@ module TechnoGate
64
64
  before :each do
65
65
  stub_filesystem!
66
66
 
67
- FileUtils.mkdir_p '/root/tmp/compiled_javascript'
67
+ FileUtils.mkdir_p '/root/my_awesome_project/tmp/compiled_javascript'
68
68
  end
69
69
 
70
70
  it "should remove the temporary javascript compiled files" do
71
71
  subject.clean
72
72
 
73
- File.exists?('/root/tmp/compiled_javascript').should be_false
73
+ File.exists?('/root/my_awesome_project/tmp/compiled_javascript').should be_false
74
74
  end
75
75
  end
76
76
  end
@@ -0,0 +1,174 @@
1
+ require 'spec_helper'
2
+ require 'contao/generators/application'
3
+
4
+ module TechnoGate
5
+ module Contao
6
+ module Generators
7
+ describe Application do
8
+ let(:klass) { Application }
9
+ subject {
10
+ Application.new path: @path
11
+ }
12
+
13
+ before :each do
14
+ @path = '/root/my_awesome_project'
15
+ end
16
+
17
+ it_should_behave_like "Generator"
18
+
19
+ describe "#generate" do
20
+ before :each do
21
+ klass.any_instance.stub :clone_template
22
+ klass.any_instance.stub :rename_project
23
+ klass.any_instance.stub :run_bundle_install
24
+ klass.any_instance.stub :run_cap_multistage_setup
25
+ klass.any_instance.stub :commit_everything
26
+ klass.any_instance.stub :replace_origin_with_template
27
+ System.stub(:system)
28
+ end
29
+
30
+ it "should have the following call stack" do
31
+ subject.should_receive(:clone_template).once.ordered
32
+ subject.should_receive(:rename_project).once.ordered
33
+ subject.should_receive(:run_bundle_install).once.ordered
34
+ subject.should_receive(:run_cap_multistage_setup).once.ordered
35
+ subject.should_receive(:commit_everything).once.ordered
36
+ subject.should_receive(:replace_origin_with_template).once.ordered
37
+
38
+ subject.generate
39
+ end
40
+ end
41
+
42
+ describe "#clone_template" do
43
+ it {should respond_to :clone_template}
44
+
45
+ it "should clone the repository to path provided to the initializer" do
46
+ System.should_receive(:system).with(
47
+ 'git',
48
+ 'clone',
49
+ '--recursive',
50
+ Application::REPO_URL,
51
+ @path
52
+ ).once.and_return true
53
+
54
+ subject.send :clone_template
55
+ end
56
+ end
57
+
58
+ describe "#rename_project", :fakefs do
59
+ before :each do
60
+ stub_filesystem!(:application_name => 'contao_template')
61
+ end
62
+
63
+ it {should respond_to :rename_project}
64
+
65
+ it "should rename the application" do
66
+ subject.send :rename_project
67
+
68
+ File.read('/root/my_awesome_project/config/application.rb').should =~
69
+ /config\.application_name\s+=\s+'my_awesome_project'/
70
+ end
71
+ end
72
+
73
+ describe "#run_bundle_install", :fakefs do
74
+ before :each do
75
+ stub_filesystem!
76
+ end
77
+
78
+ it {should respond_to :run_bundle_install}
79
+
80
+ it "should change the folder to the path" do
81
+ Dir.should_receive(:chdir).once
82
+
83
+ subject.send :run_bundle_install
84
+ end
85
+
86
+ it "should run bundle install" do
87
+ System.should_receive(:system).with('bundle', 'install').once.and_return true
88
+
89
+ subject.send :run_bundle_install
90
+ end
91
+ end
92
+
93
+ describe "#run_cap_multistage_setup", :fakefs do
94
+ before :each do
95
+ stub_filesystem!
96
+ end
97
+
98
+ it {should respond_to :run_cap_multistage_setup}
99
+
100
+ it "should change the folder to the path" do
101
+ Dir.should_receive(:chdir).once
102
+
103
+ subject.send :run_cap_multistage_setup
104
+ end
105
+
106
+ it "should run cap multistage:setup" do
107
+ System.should_receive(:system).with(
108
+ 'bundle',
109
+ 'exec',
110
+ 'cap',
111
+ 'multistage:setup'
112
+ ).once.and_return true
113
+
114
+ subject.send :run_cap_multistage_setup
115
+ end
116
+ end
117
+
118
+ describe "#commit_everything", :fakefs do
119
+ before :each do
120
+ stub_filesystem!
121
+ end
122
+
123
+ it {should respond_to :commit_everything}
124
+
125
+ it "should change the folder to the path" do
126
+ Dir.should_receive(:chdir).once
127
+
128
+ subject.send :commit_everything
129
+ end
130
+
131
+ it "should run git commit -am 'Generated project'" do
132
+ System.should_receive(:system).with('git', 'add', '-A', '.').once.ordered.and_return true
133
+ System.should_receive(:system).with(
134
+ 'git',
135
+ 'commit',
136
+ '-m',
137
+ 'Import generated files inside the repository'
138
+ ).once.ordered.and_return true
139
+
140
+ subject.send :commit_everything
141
+ end
142
+ end
143
+
144
+ describe '#replace_origin_with_template', :fakefs do
145
+ before :each do
146
+ stub_filesystem!
147
+ end
148
+
149
+ it {should respond_to :replace_origin_with_template}
150
+
151
+ it "should change the folder to the path" do
152
+ Dir.should_receive(:chdir).once
153
+
154
+ subject.send :replace_origin_with_template
155
+ end
156
+
157
+ it "should replace origin with template" do
158
+ System.should_receive(:system).with('git', 'remote', 'rm', 'origin').once.ordered.and_return true
159
+ System.should_receive(:system).with(
160
+ 'git',
161
+ 'remote',
162
+ 'add',
163
+ 'template',
164
+ Application::REPO_URL
165
+ ).once.ordered.and_return true
166
+
167
+ subject.send :replace_origin_with_template
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'contao/generators/base'
3
+
4
+ module TechnoGate
5
+ module Contao
6
+ module Generators
7
+ describe Base do
8
+ let(:klass) { Base }
9
+
10
+ it_should_behave_like "Generator"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -11,8 +11,8 @@ module TechnoGate
11
11
 
12
12
  stub_filesystem!
13
13
 
14
- @file_path = "/root/app/assets/javascripts/file.js"
15
- @app_js_path = "/root/public/resources/application.js"
14
+ @file_path = "/root/my_awesome_project/app/assets/javascripts/file.js"
15
+ @app_js_path = "/root/my_awesome_project/public/resources/application.js"
16
16
 
17
17
  File.open(@file_path, 'w') do |file|
18
18
  file.write("not compiled js")
@@ -57,7 +57,7 @@ module TechnoGate
57
57
  before :each do
58
58
  stub_filesystem!
59
59
 
60
- @app_js_path = "/root/public/resources/application.js"
60
+ @app_js_path = "/root/my_awesome_project/public/resources/application.js"
61
61
 
62
62
  File.open(@app_js_path, 'w') do |file|
63
63
  file.write('compiled js')
@@ -45,6 +45,44 @@ module TechnoGate
45
45
  klass.notify(@message, @options)
46
46
  end
47
47
  end
48
+
49
+ describe '#warn' do
50
+ before :each do
51
+ @message = "Hello"
52
+ @output = "Contao>> #{@message}"
53
+ @colored_output = "\e[0;34mContao>>\e[0m \e[0;33m#{@message}\e[0m"
54
+ @options = {title: "Hello, World!"}
55
+
56
+ ::Guard::UI.stub(:color_enabled?).and_return(false)
57
+ end
58
+
59
+ it {should respond_to :warn}
60
+
61
+ it "should call guard ui" do
62
+ ::Guard::UI.should_receive(:info).with(@output, {})
63
+
64
+ subject.warn(@message)
65
+ end
66
+
67
+ it "should send whatever options passed to the info method" do
68
+ ::Guard::UI.should_receive(:info).with(@output, @options)
69
+
70
+ subject.warn(@message, @options)
71
+ end
72
+
73
+ it "should use colors if enabled" do
74
+ ::Guard::UI.should_receive(:color_enabled?).once.and_return(true)
75
+ ::Guard::UI.should_receive(:info).with(@colored_output, @options)
76
+
77
+ subject.warn(@message, @options)
78
+ end
79
+
80
+ it "should be accessible at class level" do
81
+ klass.any_instance.should_receive(:warn).with(@message, @options)
82
+
83
+ klass.warn(@message, @options)
84
+ end
85
+ end
48
86
  end
49
87
  end
50
88
  end
@@ -91,7 +91,7 @@ module TechnoGate
91
91
  before :each do
92
92
  stub_filesystem!
93
93
 
94
- @app_css_path = "/root/public/resources/application.css"
94
+ @app_css_path = "/root/my_awesome_project/public/resources/application.css"
95
95
 
96
96
  File.open(@app_css_path, 'w') do |file|
97
97
  file.write('compiled css')
@@ -42,13 +42,13 @@ module TechnoGate
42
42
 
43
43
  describe '#expandify' do
44
44
  before :each do
45
- subject.root = '/root'
45
+ subject.root = '/root/my_awesome_project'
46
46
  end
47
47
 
48
48
  it {should respond_to :expandify}
49
49
 
50
50
  it "should expand the path if it's relative" do
51
- subject.expandify('app').to_s.should == '/root/app'
51
+ subject.expandify('app').to_s.should == '/root/my_awesome_project/app'
52
52
  end
53
53
 
54
54
  it "should not expand an expanded path" do
data/spec/spec_helper.rb CHANGED
@@ -22,8 +22,9 @@ RSpec.configure do |c|
22
22
 
23
23
  c.before :each do
24
24
  ::TechnoGate::Contao.env = @env = :development
25
- ::TechnoGate::Contao.root = @root = "/root"
25
+ ::TechnoGate::Contao.root = @root = "/root/my_awesome_project"
26
26
  ::TechnoGate::Contao::Application.configure do
27
+ config.application_name = 'my_awesome_project'
27
28
  config.javascripts_path = ['vendor/assets/javascripts', 'lib/assets/javascripts', 'app/assets/javascripts']
28
29
  config.stylesheets_path = 'app/assets/stylesheets'
29
30
  config.images_path = 'app/assets/images'
@@ -13,7 +13,7 @@ shared_examples_for "Compiler" do
13
13
 
14
14
  it "should set the manifest_path as an instance variable" do
15
15
  subject.instance_variable_get(:@manifest_path).should ==
16
- Pathname('/root/public/resources/manifest.json')
16
+ Pathname('/root/my_awesome_project/public/resources/manifest.json')
17
17
  end
18
18
  end
19
19
 
@@ -67,9 +67,9 @@ shared_examples_for "Compiler" do
67
67
 
68
68
  it "should remove the entire assets_public_path" do
69
69
  stub_filesystem!
70
- File.directory?("/root/public/resources").should be_true
70
+ File.directory?("/root/my_awesome_project/public/resources").should be_true
71
71
  subject.clean
72
- File.directory?("/root/public/resources").should be_false
72
+ File.directory?("/root/my_awesome_project/public/resources").should be_false
73
73
  end
74
74
  end
75
75
 
@@ -78,7 +78,7 @@ shared_examples_for "Compiler" do
78
78
 
79
79
  it "should create the js_path" do
80
80
  subject.send :prepare_folders
81
- File.directory?("/root/public/resources")
81
+ File.directory?("/root/my_awesome_project/public/resources")
82
82
  end
83
83
  end
84
84
 
@@ -94,13 +94,13 @@ shared_examples_for "Compiler" do
94
94
  before :each do
95
95
  stub_filesystem!
96
96
 
97
- @file_path = '/root/file.something.extension'
97
+ @file_path = '/root/my_awesome_project/file.something.extension'
98
98
  File.open(@file_path, 'w') do |f|
99
99
  f.write('some data')
100
100
  end
101
101
 
102
102
  @digest = Digest::MD5.hexdigest('some data')
103
- @digested_file_path = "/root/file.something-#{@digest}.extension"
103
+ @digested_file_path = "/root/my_awesome_project/file.something-#{@digest}.extension"
104
104
  end
105
105
 
106
106
  it "should be able to create a hashed file" do
@@ -119,13 +119,13 @@ shared_examples_for "Compiler" do
119
119
  stub_filesystem!
120
120
 
121
121
  @files = [
122
- '/root/public/resources/application.js',
123
- '/root/public/resources/application-d41d8cd98f00b204e9800998ecf8427e.js',
124
- '/root/public/resources/application.css',
125
- '/root/public/resources/application-982436e5fe99465e0540d0cf38e7aff4.css',
122
+ '/root/my_awesome_project/public/resources/application.js',
123
+ '/root/my_awesome_project/public/resources/application-d41d8cd98f00b204e9800998ecf8427e.js',
124
+ '/root/my_awesome_project/public/resources/application.css',
125
+ '/root/my_awesome_project/public/resources/application-982436e5fe99465e0540d0cf38e7aff4.css',
126
126
  ].each {|f| File.open(f, 'w') {|fh| fh.write ""}}
127
127
 
128
- @manifest_path = '/root/public/resources/manifest.json'
128
+ @manifest_path = '/root/my_awesome_project/public/resources/manifest.json'
129
129
  end
130
130
 
131
131
  describe "stylesheets" do
@@ -0,0 +1,29 @@
1
+ shared_examples_for "Config" do
2
+ it_should_behave_like "Singleton"
3
+
4
+ it "should be an open struct" do
5
+ subject.class.superclass.should == OpenStruct
6
+ end
7
+
8
+ it "should have a config as a superclass" do
9
+ subject.config.class.should == OpenStruct
10
+ end
11
+
12
+ describe "config" do
13
+ it "should set a configuration variable using a block" do
14
+ klass.configure do
15
+ config.foo = :bar
16
+ end
17
+
18
+ klass.instance.config.foo.should == :bar
19
+ end
20
+
21
+ it "should be accessible form the class level" do
22
+ klass.configure do
23
+ config.foo = :bar
24
+ end
25
+
26
+ klass.config.foo.should == :bar
27
+ end
28
+ end
29
+ end
@@ -1,14 +1,15 @@
1
- def stub_filesystem!
1
+ def stub_filesystem!(options = {})
2
2
  [
3
3
 
4
- '/root/app/assets/javascripts',
5
- '/root/app/assets/stylesheets',
6
- '/root/app/assets/images',
7
- '/root/contao/non_existing_folder',
8
- '/root/contao/system/modules/some_extension',
9
- '/root/public/resources',
10
- '/root/public/system/modules/frontend',
11
- '/root/vendor/assets/javascripts',
4
+ '/root/my_awesome_project/config',
5
+ '/root/my_awesome_project/app/assets/javascripts',
6
+ '/root/my_awesome_project/app/assets/stylesheets',
7
+ '/root/my_awesome_project/app/assets/images',
8
+ '/root/my_awesome_project/contao/non_existing_folder',
9
+ '/root/my_awesome_project/contao/system/modules/some_extension',
10
+ '/root/my_awesome_project/public/resources',
11
+ '/root/my_awesome_project/public/system/modules/frontend',
12
+ '/root/my_awesome_project/vendor/assets/javascripts',
12
13
  '/tmp',
13
14
 
14
15
  ].each do |folder|
@@ -17,4 +18,42 @@ def stub_filesystem!
17
18
  f.write "Stub file"
18
19
  end
19
20
  end
21
+
22
+ stub_global_config_file!(options[:global_config] || {})
23
+ stub_config_application!(options[:application_name])
24
+ end
25
+
26
+ def stub_global_config_file!(config = {})
27
+ config = TechnoGate::Contao::Application.default_global_config(
28
+ 'install_password' => 'f0fb33dcebe5753f053b882bb49faefe7384f22e:7305d1f250f3481bac35f2839a2a4fd6',
29
+ 'encryption_key' => 'e626cd6b8fd219b3e1803dc59620d972'
30
+ ).merge(config)
31
+
32
+ config_file = TechnoGate::Contao::Application.instance.global_config_path
33
+
34
+ FileUtils.mkdir_p File.dirname(config_file)
35
+ File.open(config_file, 'w') do |file|
36
+ file.write YAML.dump(config)
37
+ end
38
+ end
39
+
40
+ def stub_config_application!(application_name = 'my_awesome_project')
41
+ File.open('/root/my_awesome_project/config/application.rb', 'w') do |f|
42
+ f.write(<<-EOS)
43
+ require File.expand_path('../boot', __FILE__)
44
+
45
+ # Initialize the application
46
+ Dir["#{TechnoGate::Contao.root.join('config', 'initializers')}/**/*.rb"].each {|f| require f}
47
+
48
+ TechnoGate::Contao::Application.configure do
49
+ config.application_name = '#{application_name}'
50
+ config.javascripts_path = ["vendor/assets/javascripts", "lib/assets/javascripts", "app/assets/javascripts"]
51
+ config.stylesheets_path = 'app/assets/stylesheets'
52
+ config.images_path = 'app/assets/images'
53
+ config.contao_path = 'contao'
54
+ config.contao_public_path = 'public'
55
+ config.assets_public_path = 'public/resources'
56
+ end
57
+ EOS
58
+ end
20
59
  end
@@ -0,0 +1,8 @@
1
+ shared_examples_for "Generator" do
2
+ describe "Initialization" do
3
+ it "should store any passed info in the @options" do
4
+ klass.new(path: '/path/to/application').instance_variable_get(:@options).should ==
5
+ {path: '/path/to/application'}
6
+ end
7
+ end
8
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contao
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -207,7 +207,8 @@ description: Contao Integration with Compass, Sass, Coffee-script, Rake, Guard w
207
207
  asset pre-compiler and asset-manifest generator
208
208
  email:
209
209
  - wael.nasreddine@gmail.com
210
- executables: []
210
+ executables:
211
+ - contao
211
212
  extensions: []
212
213
  extra_rdoc_files: []
213
214
  files:
@@ -217,25 +218,35 @@ files:
217
218
  - LICENSE
218
219
  - README.md
219
220
  - Rakefile
221
+ - bin/contao
220
222
  - contao.gemspec
221
223
  - lib/contao.rb
222
224
  - lib/contao/application.rb
225
+ - lib/contao/cli.rb
223
226
  - lib/contao/coffeescript_compiler.rb
227
+ - lib/contao/commands/application.rb
228
+ - lib/contao/commands/help.rb
224
229
  - lib/contao/compiler.rb
230
+ - lib/contao/generators/application.rb
231
+ - lib/contao/generators/base.rb
225
232
  - lib/contao/javascript_compiler.rb
226
233
  - lib/contao/notifier.rb
227
234
  - lib/contao/stylesheet_compiler.rb
235
+ - lib/contao/system.rb
228
236
  - lib/contao/tasks/assets.rake
229
237
  - lib/contao/tasks/contao.rake
230
238
  - lib/contao/tasks/jasmine.rake
231
239
  - lib/contao/tasks/whitespace.rake
232
240
  - lib/contao/version.rb
233
241
  - lib/contao_patches/development/development_htaccess.patch
242
+ - lib/core_ext/object.rb
234
243
  - lib/guard/assets.rb
235
244
  - lib/monkey_patches.rb
236
245
  - lib/monkey_patches/compass/urls.rb
237
246
  - spec/lib/contao/application_spec.rb
238
247
  - spec/lib/contao/coffeescript_compiler_spec.rb
248
+ - spec/lib/contao/generators/application_spec.rb
249
+ - spec/lib/contao/generators/base_spec.rb
239
250
  - spec/lib/contao/javascript_compiler_spec.rb
240
251
  - spec/lib/contao/notifier_spec.rb
241
252
  - spec/lib/contao/stylesheet_compiler_spec.rb
@@ -243,7 +254,9 @@ files:
243
254
  - spec/lib/guard/assets_spec.rb
244
255
  - spec/spec_helper.rb
245
256
  - spec/support/compiler_shared_examples.rb
257
+ - spec/support/config_shared_examples.rb
246
258
  - spec/support/filesystem_mock.rb
259
+ - spec/support/generator_shared_examples.rb
247
260
  - spec/support/singleton_shared_example.rb
248
261
  homepage: ''
249
262
  licenses: []
@@ -259,7 +272,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
259
272
  version: '0'
260
273
  segments:
261
274
  - 0
262
- hash: -4565490712393146300
275
+ hash: 4578868734635956444
263
276
  required_rubygems_version: !ruby/object:Gem::Requirement
264
277
  none: false
265
278
  requirements:
@@ -268,7 +281,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
268
281
  version: '0'
269
282
  segments:
270
283
  - 0
271
- hash: -4565490712393146300
284
+ hash: 4578868734635956444
272
285
  requirements: []
273
286
  rubyforge_project:
274
287
  rubygems_version: 1.8.24
@@ -279,6 +292,8 @@ summary: Contao Integration with Compass, Sass, Coffee-script, Rake, Guard with
279
292
  test_files:
280
293
  - spec/lib/contao/application_spec.rb
281
294
  - spec/lib/contao/coffeescript_compiler_spec.rb
295
+ - spec/lib/contao/generators/application_spec.rb
296
+ - spec/lib/contao/generators/base_spec.rb
282
297
  - spec/lib/contao/javascript_compiler_spec.rb
283
298
  - spec/lib/contao/notifier_spec.rb
284
299
  - spec/lib/contao/stylesheet_compiler_spec.rb
@@ -286,5 +301,7 @@ test_files:
286
301
  - spec/lib/guard/assets_spec.rb
287
302
  - spec/spec_helper.rb
288
303
  - spec/support/compiler_shared_examples.rb
304
+ - spec/support/config_shared_examples.rb
289
305
  - spec/support/filesystem_mock.rb
306
+ - spec/support/generator_shared_examples.rb
290
307
  - spec/support/singleton_shared_example.rb