-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathtestrails.rb
executable file
·167 lines (143 loc) · 5.05 KB
/
testrails.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/env ruby
require 'json'
source = ARGV[0]
home = File.expand_path(__dir__)
if not source
puts 'Usage: '
Dir.chdir home
Dir["docs/src/_examples/rails/*.md"].sort.each do |file|
next if File.basename(file) == 'index.md'
puts " #{$PROGRAM_NAME} #{file}"
end
exit 1
end
# determine what to install based on the markdown source file name
install = File.basename(source, '.md').gsub('_', ':').gsub('-', '')
# extract instructions from markdown source
source = IO.read(source)
gen = %r{\./bin/rails generate .*}.match(source)
html = /.*`(.*?)`.*?```(?:html|erb)\n(.*?)```/m.match(source)
ruby = /.*`(.*?)`.*?```ruby\n(.*?)```/m.match(source)
link = %r{<(http://localhost:3000/.*?)>}.match(source)
rails = /Rails Version: (\d[.\w]*)/i.match(source)
opts = source[/rails new [-\w]+(.*)/, 1]
run = /## Try it out!\n.*?```\n(.*?)```/m.match(source)
# match the version of rails to the example
if rails
installed = `gem list '^rails$'`.scan(/\d[.\w]+/)
version = installed.find {|version| version.start_with? rails[1]}
rails "Rails version #{version} is not installed" unless version
rails = "rails _#{version}_"
else
rails = 'rails'
end
# Create a rails app
system 'rm -rf testrails'
system "#{rails} new testrails#{opts}"
Dir.chdir 'testrails'
system './bin/spring stop'
# install ruby2js and dependencies
add = ["gem 'ruby2js', path: #{home.inspect}, require: 'ruby2js/rails'"]
add << "gem 'stimulus-rails'" if install.include? 'stimulus_webpacker'
IO.write 'Gemfile', "\n" + add.join("\n"), mode: 'a'
system './bin/bundle install'
system "./bin/rails ruby2js:install:#{install}"
# install locally built ruby2js
ruby2js = "#{home}/packages/ruby2js"
version = JSON.parse(IO.read "#{ruby2js}/package.json")['version']
mod = Dir["#{ruby2js}/ruby2js-ruby2js-*#{version}.tgz"].first
system "yarn add #{mod}" if mod
# install locally built webpack-loader
loader = "#{home}/packages/webpack-loader"
version = JSON.parse(IO.read "#{loader}/package.json")['version']
mod = Dir["#{loader}/ruby2js-webpack-loader-*#{version}.tgz"].first
system "yarn add #{mod}" if mod
# create ruby and html sources per markdown
system gen[0]
IO.write html[1], html[2], mode: 'a+' if html
IO.write ruby[1], ruby[2], mode: 'w' if ruby
File.unlink ruby[1].chomp('.rb') if File.exist? ruby[1].chomp('.rb')
if ARGV.include? '-w' or ARGV.include? '--watch'
require 'listen'
ruby2js = File.realpath(__dir__)
# extract config
if File.exist? "#{ruby2js}/testrails/rollup.config.js"
config = IO.read("#{ruby2js}/testrails/rollup.config.js")
config = config[/ruby2js\((\{.*?\})\)/m, 1]
elsif File.exist? "#{ruby2js}/testrails/config/webpack/loaders/ruby2js.js"
config = IO.read("#{ruby2js}/testrails/config/webpack/loaders/ruby2js.js")
config = config[/@ruby2js.*?options:\s*(\{.*?\})\s*\}\s*\]/m, 1]
else
config = {}
end
# convert to Ruby2JS options
config = eval config
filters = config.delete(:filters)
eslevel = config.delete(:eslevel)
opts = config.map{|name, value| "--#{name}=#{value}"}.join(' ')
opts += " --es#{eslevel}" if eslevel
opts += " --filter=#{filters.join(',')}" if filters
# watch for changes
controllers = "#{ruby2js}/testrails/app/javascript/controllers"
elements = "#{ruby2js}/testrails/app/javascript/elements"
listener = Listen.to(*Dir[controllers, elements]) do |mod, add, rem|
(mod + add).each do |file|
source = File.basename(file)
next unless source.end_with? '.js.rb'
target = source.sub('.rb', '')
cmd = "#{ruby2js}/demo/ruby2js.rb #{opts} <#{source} >#{target}"
system "cd #{File.dirname(file)}; #{cmd}"
# replace .rb reference in index with .js
if File.exist? "#{controllers}/index.js"
index = IO.read("#{controllers}/index.js")
if index.include? source
index.gsub! source, target
IO.write("#{controllers}/index.js", index)
end
end
end
end
# remove .rb from require.context call
if File.exist? "#{elements}/index.js"
index = IO.read("#{elements}/index.js")
if index.include? '(\\.rb)?'
index.gsub! '(\\.rb)?', ''
IO.write("#{elements}/index.js", index)
end
end
listener.start
# update everything
Dir["#{controllers}/*.rb", "#{elements}/*.rb"].each do |file|
system "touch #{file}"
end
end
# launch browser once server is up and running
require 'net/http'
Thread.new do
port = link[1][/:(\d+)/, 1].to_i
# wait for server to start
60.times do
sleep 0.5
begin
status = Net::HTTP.get_response('0.0.0.0','/',port).code
break if %(200 404 500).include? status
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT
end
end
# launch browser
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
system "start #{link[1]}"
elsif RbConfig::CONFIG['host_os'] =~ /darwin/
system "open #{link[1]}"
elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
if ENV['WSLENV'] and not `which wslview`.empty?
system "wslview #{link[1]}"
else
system "xdg-open #{link[1]}"
end
end
end
# start server
(run ? run[1].split("\n") : ['./bin/rails server']).each do |cmd|
system cmd
end