xing-root 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/xing/edicts/clean-rake.rb +16 -0
- data/lib/xing/edicts/clean-run.rb +40 -0
- data/lib/xing/edicts/launch-browser.rb +91 -0
- data/lib/xing/edicts/start-child.rb +11 -0
- data/lib/xing/edicts/structure-checker.rb +99 -0
- data/lib/xing/edicts.rb +3 -0
- data/lib/xing/managers/child.rb +110 -0
- data/lib/xing/managers/tmux.rb +188 -0
- data/lib/xing/tasks/backend.rb +45 -0
- data/lib/xing/tasks/build.rb +28 -0
- data/lib/xing/tasks/develop.rb +144 -0
- data/lib/xing/tasks/frontend.rb +44 -0
- data/lib/xing/tasks/spec.rb +79 -0
- data/lib/xing/tasks/tasklib.rb +25 -0
- data/lib/xing/tasks.rb +8 -0
- data/lib/xing-root.rb +4 -0
- data/spec/edicts/clean_rake_spec.rb +43 -0
- data/spec/edicts/clean_run_spec.rb +43 -0
- data/spec/edicts/launch-browser_spec.rb +91 -0
- data/spec/edicts/start-child_spec.rb +30 -0
- data/spec/managers/tmux_spec.rb +104 -0
- data/spec/support/file-sandbox.rb +163 -0
- data/spec/tasks/develop_spec.rb +46 -0
- data/spec/tasks/frontend_spec.rb +26 -0
- data/spec/tasks/structure_checker_spec.rb +41 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f1e5c25fdf0a0131b66f61a48b065e7a042edfda
|
4
|
+
data.tar.gz: bdda3cd893b79191835a14ade4ce89b6a63844d5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e3e77cdf6e85e6108aa2876c879a783e68a97ffc64d3ab4c525d43ce6fb9cf369133f42e01d93dd05b91f12fe954a37a5b396e5365ed86769f1456dad9084467
|
7
|
+
data.tar.gz: 57bb2b0db2a4884c8eef59f885d21241b842e15571a3f34484e25c721be0ca8240824e07e6da660da7400921ae5f76cdd06aee86ae869682c8ef363da489a514
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'caliph'
|
2
|
+
require 'edict'
|
3
|
+
|
4
|
+
module Xing
|
5
|
+
module Edicts
|
6
|
+
class CleanRun < Edict::Rule
|
7
|
+
include Caliph::CommandLineDSL
|
8
|
+
|
9
|
+
setting :dir
|
10
|
+
setting :shell_cmd
|
11
|
+
setting :env_hash
|
12
|
+
setting :caliph_shell
|
13
|
+
|
14
|
+
def setup_defaults
|
15
|
+
super
|
16
|
+
@caliph_shell = Caliph::Shell.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
self.env_hash ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def action
|
24
|
+
Bundler.with_clean_env do
|
25
|
+
Dir.chdir(dir) do
|
26
|
+
command = cmd(*shell_cmd)
|
27
|
+
|
28
|
+
env_hash.each_pair do |name, value|
|
29
|
+
command.set_env(name, value)
|
30
|
+
end
|
31
|
+
|
32
|
+
result = caliph_shell.run(command)
|
33
|
+
|
34
|
+
result.must_succeed!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'caliph'
|
2
|
+
require 'edict'
|
3
|
+
require 'xing-root'
|
4
|
+
|
5
|
+
module Xing::Edicts
|
6
|
+
class LaunchBrowser < Edict::Command
|
7
|
+
setting :reload_server_port
|
8
|
+
setting :static_server_port
|
9
|
+
setting :setup_time_limit, 60
|
10
|
+
setting :max_wait, 16
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
self.command = ""
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_live_reload_server!
|
18
|
+
begin_time = Time.now
|
19
|
+
begin
|
20
|
+
test_conn = TCPSocket.new 'localhost', reload_server_port
|
21
|
+
rescue Errno::ECONNREFUSED
|
22
|
+
if Time.now - begin_time > setup_time_limit
|
23
|
+
puts "Couldn't connect to test server on localhost:#{reload_server_port} after #{setup_time_limit} seconds - bailing out"
|
24
|
+
exit 1
|
25
|
+
else
|
26
|
+
sleep 0.05
|
27
|
+
retry
|
28
|
+
end
|
29
|
+
ensure
|
30
|
+
test_conn.close rescue nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def check_existing_browser
|
35
|
+
started = Time.now
|
36
|
+
changes = {}
|
37
|
+
while(Time.now - started < max_wait)
|
38
|
+
begin
|
39
|
+
changes = JSON.parse(Net::HTTP.get(URI("http://localhost:#{reload_server_port}/changed")))
|
40
|
+
rescue Errno::ECONNREFUSED
|
41
|
+
puts "LiveReload server abruptly stopped receiving connections. Bailing out."
|
42
|
+
exit 2
|
43
|
+
end
|
44
|
+
|
45
|
+
if changes["clients"].empty?
|
46
|
+
sleep 0.25
|
47
|
+
else
|
48
|
+
break
|
49
|
+
end
|
50
|
+
end
|
51
|
+
changes["clients"]
|
52
|
+
end
|
53
|
+
|
54
|
+
def launch_new_browser
|
55
|
+
puts
|
56
|
+
puts "No running development browsers: launching...."
|
57
|
+
|
58
|
+
browser_command = %w{open xdg-open chrome chromium}.find do |command|
|
59
|
+
run_command(cmd('which', command)).succeeds?
|
60
|
+
end
|
61
|
+
|
62
|
+
if browser_command.nil?
|
63
|
+
raise "Can't find any executable to launch a browser with."
|
64
|
+
end
|
65
|
+
|
66
|
+
run_command( cmd(browser_command, "http://localhost:#{static_server_port}/") ).must_succeed!
|
67
|
+
end
|
68
|
+
|
69
|
+
def subprocess_action
|
70
|
+
require 'net/http'
|
71
|
+
require 'json'
|
72
|
+
|
73
|
+
check_live_reload_server!
|
74
|
+
|
75
|
+
existing = check_existing_browser
|
76
|
+
|
77
|
+
if existing.empty?
|
78
|
+
launch_new_browser
|
79
|
+
else
|
80
|
+
puts
|
81
|
+
puts "There's already a browser attached to the LiveReload server."
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def action
|
86
|
+
fork do
|
87
|
+
subprocess_action
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'xing-root'
|
2
|
+
require 'find'
|
3
|
+
require 'edict'
|
4
|
+
|
5
|
+
module Xing::Edicts
|
6
|
+
class StructureChecker < Edict::Rule
|
7
|
+
include Find
|
8
|
+
|
9
|
+
class Error < ::StandardError
|
10
|
+
end
|
11
|
+
|
12
|
+
setting :dir
|
13
|
+
nil_field :context_hash
|
14
|
+
setting :out_stream, $stdout
|
15
|
+
|
16
|
+
def setup
|
17
|
+
@problems = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def action
|
21
|
+
analyze
|
22
|
+
report
|
23
|
+
end
|
24
|
+
|
25
|
+
def analyze
|
26
|
+
context = context_from_hash(context_hash || {:escapes => %w{common framework build}})
|
27
|
+
return unless File.directory?(dir)
|
28
|
+
find(dir) do |path|
|
29
|
+
if File.directory?(path)
|
30
|
+
else
|
31
|
+
next if File.basename(path)[0] == ?.
|
32
|
+
case path
|
33
|
+
when /\.js\z/
|
34
|
+
check_imports(path, context)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def context_from_hash(hash)
|
41
|
+
Context.new(hash)
|
42
|
+
end
|
43
|
+
|
44
|
+
def report
|
45
|
+
unless @problems.empty?
|
46
|
+
@problems.group_by do |problem|
|
47
|
+
problem.file
|
48
|
+
end.each do |file, problems|
|
49
|
+
out_stream.puts "In #{file}"
|
50
|
+
problems.each{|prob| out_stream.puts " " + prob.to_s}
|
51
|
+
out_stream.puts
|
52
|
+
end
|
53
|
+
raise Error, "Problems found in ECMAScript structure"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Context
|
58
|
+
def initialize(hash)
|
59
|
+
@escape_clause_list = hash.delete(:escapes) || %w{common framework build}
|
60
|
+
raise "Unknown fields in context: #{hash.inspect}" unless hash.empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
attr_reader :escape_clause_list
|
64
|
+
end
|
65
|
+
|
66
|
+
class Problem < ::Struct.new(:msg, :line, :lineno, :file)
|
67
|
+
def to_s
|
68
|
+
"#{lineno}:<#{line}>: #{msg}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def problem(msg, line, lineno, file)
|
73
|
+
@problems << Problem.new(msg, line.chomp, lineno + 1, file)
|
74
|
+
end
|
75
|
+
|
76
|
+
def check_imports(path, context)
|
77
|
+
File.read(path).lines.grep(/\s*import/).each_with_index do |import_line, lineno|
|
78
|
+
md = /.*from (?<quote>['"])(?<from>.*)\k<quote>/.match(import_line)
|
79
|
+
if md.nil?
|
80
|
+
problem "doesn't seem to have a 'from' clause...", import_line, lineno, path
|
81
|
+
end
|
82
|
+
|
83
|
+
if /\.\./ =~ md[:from]
|
84
|
+
if /\A\.\./ !~ md[:from]
|
85
|
+
problem "from includes .. not at pos 0", import_line, lineno, path
|
86
|
+
end
|
87
|
+
if /\w.*\.\./ =~ md[:from]
|
88
|
+
problem "from includes .. after words", import_line, lineno, path
|
89
|
+
end
|
90
|
+
if !(violation = %r{(?<dir>\w+)/\w}.match md[:from]).nil?
|
91
|
+
unless %r{\.\./(#{context.escape_clause_list.join("|")})} =~ md[:from]
|
92
|
+
problem "Imports Rule: 'from' includes ../ and then #{violation[:dir].inspect} not in #{context.escape_clause_list.inspect}", import_line, lineno, path
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/xing/edicts.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
class ChildManager
|
2
|
+
def initialize
|
3
|
+
@child_pids = []
|
4
|
+
@parent_pid = Process.pid
|
5
|
+
@child_data = {}
|
6
|
+
end
|
7
|
+
attr_accessor :child_pids, :child_data
|
8
|
+
|
9
|
+
ChildRecord = Struct.new(:name, :status)
|
10
|
+
|
11
|
+
def start_child(name, task)
|
12
|
+
child_pid = Process.fork do
|
13
|
+
Signal.trap("HUP") do
|
14
|
+
puts "Parent exited"
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
exec(*(%w{bundle exec rake} + [task]))
|
19
|
+
end
|
20
|
+
puts "#{@parent_pid}: #{name} running in pid #{child_pid}"
|
21
|
+
|
22
|
+
at_exit { kill_child(child_pid) }
|
23
|
+
child_data[child_pid] = ChildRecord.new(name, nil)
|
24
|
+
child_pids << child_pid
|
25
|
+
end
|
26
|
+
|
27
|
+
def exited?(pid)
|
28
|
+
return false unless child_data.has_key?(pid)
|
29
|
+
return true unless child_data[pid].status.nil?
|
30
|
+
|
31
|
+
begin
|
32
|
+
_apid, status = *Process.wait2(pid, Process::WNOHANG | Process::WUNTRACED)
|
33
|
+
rescue Errno::ECHILD
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
|
37
|
+
unless status.nil?
|
38
|
+
child_data[pid].status = status
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
def wait_until_dead(pilimit)
|
45
|
+
start = Time.now
|
46
|
+
while Time.now - start < limit
|
47
|
+
Process.waitpid(-1, Process::WNOHANG | Process::WUNTRACED)
|
48
|
+
sleep(0.1)
|
49
|
+
end
|
50
|
+
return false
|
51
|
+
rescue SystemCallError # = no children
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
|
55
|
+
def wait_all
|
56
|
+
Process.waitall
|
57
|
+
end
|
58
|
+
|
59
|
+
def kill_child(pid)
|
60
|
+
unless Process.pid == @parent_pid
|
61
|
+
puts "#{Process.pid} #@parent_pid Not original parent: not killing"
|
62
|
+
return
|
63
|
+
end
|
64
|
+
puts "PID #{Process.pid} is killing child #{pid} #{child_data[pid].name}"
|
65
|
+
|
66
|
+
if exited?(pid)
|
67
|
+
puts "#{pid} #{child_data[pid].name} already exited"
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
begin
|
72
|
+
Process::kill("TERM", pid)
|
73
|
+
rescue Errno::ESRCH
|
74
|
+
puts "Hm. #{pid} is already gone: dead?"
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
78
|
+
limit = 10
|
79
|
+
start = Time.now
|
80
|
+
while Time.now - start < limit
|
81
|
+
begin
|
82
|
+
Process::kill(0, pid)
|
83
|
+
sleep(0.1)
|
84
|
+
rescue Errno::ESRCH
|
85
|
+
return
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
begin
|
90
|
+
Process::kill("KILL", pid)
|
91
|
+
rescue Errno::ESRCH
|
92
|
+
return
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def kill_all
|
97
|
+
unless Process.pid == @parent_pid
|
98
|
+
puts "Although #{Process.pid} was asked to kill all, it isn't #@parent_pid the original parent"
|
99
|
+
return
|
100
|
+
end
|
101
|
+
child_pids.each do |pid|
|
102
|
+
kill_child(pid)
|
103
|
+
end
|
104
|
+
previous_term_trap = trap "TERM" do
|
105
|
+
puts "Trapped TERM once"
|
106
|
+
trap "TERM", previous_term_trap
|
107
|
+
end
|
108
|
+
Process::kill("TERM", 0)
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'caliph'
|
2
|
+
|
3
|
+
module Xing
|
4
|
+
module Managers
|
5
|
+
class Tmux
|
6
|
+
include Caliph::CommandLineDSL
|
7
|
+
|
8
|
+
MINIMUM_WINDOW_COLUMNS = 75
|
9
|
+
MINIMUM_WINDOW_LINES = 18
|
10
|
+
|
11
|
+
def initialize(shell=nil)
|
12
|
+
@shell = shell || Tmux.shell
|
13
|
+
@first_child = true
|
14
|
+
@extra_config_path='~/.lrd-dev-tmux.conf'
|
15
|
+
end
|
16
|
+
attr_reader :shell
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def shell
|
20
|
+
@shell ||= Caliph.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def available?
|
24
|
+
shell.run("which", "tmux").succeeds?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def tmux_exe
|
29
|
+
@tmux_exe ||= shell.run("which", "tmux").stdout.chomp
|
30
|
+
end
|
31
|
+
|
32
|
+
def tmux(*cmd)
|
33
|
+
command = cmd(tmux_exe, *cmd)
|
34
|
+
puts command.string_format
|
35
|
+
shell.run(command).stdout.chomp
|
36
|
+
end
|
37
|
+
|
38
|
+
def copied_env_vars
|
39
|
+
%w{PORT_OFFSET GEM_HOME GEM_PATH}
|
40
|
+
end
|
41
|
+
|
42
|
+
def default_env
|
43
|
+
{"PORT_OFFSET" => 0}
|
44
|
+
end
|
45
|
+
|
46
|
+
def session_env
|
47
|
+
Hash[copied_env_vars.map do |varname|
|
48
|
+
varvalue = ENV[varname] || default_env[varname]
|
49
|
+
[varname, varvalue] unless varvalue.nil?
|
50
|
+
end.compact]
|
51
|
+
end
|
52
|
+
|
53
|
+
def env_string
|
54
|
+
session_env.map do |envpair|
|
55
|
+
envpair.join("=")
|
56
|
+
end.join(" ")
|
57
|
+
end
|
58
|
+
|
59
|
+
def rake_command(task)
|
60
|
+
"env #{env_string} bundle exec rake #{task}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def wait_all
|
64
|
+
path = File.expand_path(@extra_config_path)
|
65
|
+
if File.exists?(path)
|
66
|
+
puts "Loading #{path}"
|
67
|
+
tmux "source-file #{path}"
|
68
|
+
else
|
69
|
+
puts "No extra config found at #{path}"
|
70
|
+
end
|
71
|
+
|
72
|
+
tmux "attach-session -d" unless existing?
|
73
|
+
end
|
74
|
+
|
75
|
+
def existing?
|
76
|
+
!(ENV['TMUX'].nil? or ENV['TMUX'].empty?)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
class TmuxPane < Tmux
|
82
|
+
|
83
|
+
def initialize(shell=nil)
|
84
|
+
super
|
85
|
+
@window_name = "Dev Servers"
|
86
|
+
@pane_count = 0
|
87
|
+
@window_count = 1
|
88
|
+
end
|
89
|
+
attr_accessor :window_name
|
90
|
+
|
91
|
+
def new_window_after
|
92
|
+
@new_window_after ||= calculate_lines_per_window
|
93
|
+
end
|
94
|
+
|
95
|
+
# need to use %x here rather than open a Caliph subshell
|
96
|
+
# won't ahve the same terminal with subshell
|
97
|
+
def tput_lines
|
98
|
+
%x"tput lines".chomp.to_i
|
99
|
+
end
|
100
|
+
|
101
|
+
def tput_cols
|
102
|
+
%x"tput cols".chomp.to_i
|
103
|
+
end
|
104
|
+
|
105
|
+
def calculate_lines_per_window
|
106
|
+
lines = tput_lines
|
107
|
+
min_lines = (ENV["XING_TMUX_MIN_LINES"] || MINIMUM_WINDOW_LINES).to_i
|
108
|
+
min_lines = [1, lines / min_lines].max
|
109
|
+
if calculate_layout == "tiled"
|
110
|
+
min_lines * 2
|
111
|
+
else
|
112
|
+
min_lines
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def calculate_layout
|
117
|
+
min_cols = (ENV["XING_TMUX_MIN_COLS"] || MINIMUM_WINDOW_COLUMNS).to_i
|
118
|
+
cols = tput_cols
|
119
|
+
if cols > min_cols * 2
|
120
|
+
"tiled"
|
121
|
+
else
|
122
|
+
"even-vertical"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def open_new_pane(name, task)
|
127
|
+
tmux "new-window -d -n '#{name}' '#{rake_command(task)}' \\; set-window-option remain-on-exit on"
|
128
|
+
tmux "join-pane -d -s '#{name}.0' -t '#{@window_name}.bottom'"
|
129
|
+
end
|
130
|
+
|
131
|
+
def open_first_window(name, task)
|
132
|
+
if tmux('list-windows -F \'#{window_name}\'') =~ /#{name}|#{@window_name}/
|
133
|
+
puts "It looks like there are already windows open for this tmux?"
|
134
|
+
exit 2
|
135
|
+
end
|
136
|
+
|
137
|
+
if existing?
|
138
|
+
tmux "new-window -n '#@window_name' '#{rake_command(task)}' \\; set-window-option remain-on-exit on"
|
139
|
+
else
|
140
|
+
tmux "new-session -d -n '#@window_name' '#{rake_command(task)}' \\; set-window-option remain-on-exit on"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def open_additional_window(name, task)
|
145
|
+
tmux "select-layout -t '#@window_name' #{@layout}"
|
146
|
+
@window_count = @window_count + 1
|
147
|
+
@window_name = "Dev Servers #{@window_count}"
|
148
|
+
tmux "new-window -d -n '#@window_name' '#{rake_command(task)}' \\; set-window-option remain-on-exit on"
|
149
|
+
@pane_count = 0
|
150
|
+
end
|
151
|
+
|
152
|
+
def start_child(name, task)
|
153
|
+
if @first_child
|
154
|
+
open_first_window(name, task)
|
155
|
+
elsif @pane_count >= new_window_after
|
156
|
+
open_additional_window(name, task)
|
157
|
+
else
|
158
|
+
open_new_pane(name, task)
|
159
|
+
end
|
160
|
+
@pane_count = @pane_count + 1
|
161
|
+
@first_child = false
|
162
|
+
end
|
163
|
+
|
164
|
+
def wait_all
|
165
|
+
tmux "select-layout -t '#@window_name' #{@layout}"
|
166
|
+
super
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
class TmuxWindow < Tmux
|
171
|
+
def start_child(name, task)
|
172
|
+
if @first_child
|
173
|
+
if tmux 'list-windows -F \'#{window_name}\'' =~ /#{name}/
|
174
|
+
puts "It looks like there are already windows open for this tmux?"
|
175
|
+
exit 2
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
if @first_child and not existing?
|
180
|
+
tmux "new-session -d -n '#{name}' '#{rake_command(task)}' \\; set-window-option remain-on-exit on"
|
181
|
+
else
|
182
|
+
tmux "new-window -n '#{name}' '#{rake_command(task)}' \\; set-window-option remain-on-exit on"
|
183
|
+
end
|
184
|
+
@first_child = false
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'xing/edicts'
|
2
|
+
require 'xing/tasks/tasklib'
|
3
|
+
|
4
|
+
module Xing
|
5
|
+
module Tasks
|
6
|
+
class Backend < Tasklib
|
7
|
+
default_namespace :backend
|
8
|
+
setting :dir, "backend"
|
9
|
+
|
10
|
+
def define
|
11
|
+
in_namespace do
|
12
|
+
edict_task :bundle_install, Edicts::CleanRun do |bi|
|
13
|
+
bi.shell_cmd = %w{bundle check || bundle install}
|
14
|
+
end
|
15
|
+
|
16
|
+
edict_task :check_dependencies, Edicts::CleanRun do |cd|
|
17
|
+
cd.shell_cmd = %w{bundle exec rake dependencies:check}
|
18
|
+
end
|
19
|
+
task :check_dependencies => :bundle_install
|
20
|
+
|
21
|
+
desc "Migrate database up to current"
|
22
|
+
edict_task :db_migrate, Edicts::CleanRun do |dm|
|
23
|
+
dm.shell_cmd = %w{bundle exec rake db:migrate}
|
24
|
+
end
|
25
|
+
task :db_migrate => :bundle_install
|
26
|
+
|
27
|
+
task :setup => [:bundle_install, :db_migrate]
|
28
|
+
|
29
|
+
edict_task :db_seed, Edicts::CleanRun do |ds|
|
30
|
+
ds.shell_cmd = %w{bundle exec rake db:seed}
|
31
|
+
end
|
32
|
+
task :db_seed => :db_migrate
|
33
|
+
|
34
|
+
desc "Precompile rails assets"
|
35
|
+
edict_task :assets_precompile, Edicts::CleanRun do |ap|
|
36
|
+
ap.shell_cmd = %w{bundle exec rake assets:precompile}
|
37
|
+
end
|
38
|
+
task :assets_precompile => [:bundle_install, :db_migrate]
|
39
|
+
|
40
|
+
task :all => [:db_seed, :assets_precompile]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'xing/edicts'
|
2
|
+
require 'xing/tasks/tasklib'
|
3
|
+
|
4
|
+
module Xing
|
5
|
+
module Tasks
|
6
|
+
class Build < Tasklib
|
7
|
+
default_namespace :build
|
8
|
+
setting :config_dir, "../frontend"
|
9
|
+
|
10
|
+
def define
|
11
|
+
in_namespace do
|
12
|
+
task :all => ['frontend:all']
|
13
|
+
|
14
|
+
namespace :frontend do
|
15
|
+
edict_task :grunt_compile, Edicts::CleanRun do |gc|
|
16
|
+
gc.dir = "frontend"
|
17
|
+
gc.env_hash = {"CUSTOM_CONFIG_DIR" => config_dir}
|
18
|
+
gc.shell_cmd = %w{bundle exec node_modules/.bin/grunt compile}
|
19
|
+
end
|
20
|
+
task :grunt_compile => ['frontend:setup']
|
21
|
+
|
22
|
+
task :all => [:grunt_compile]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|