contao 0.3.4 → 0.4.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.
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