xing-root 0.0.1
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.
- 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
|