-
-
Notifications
You must be signed in to change notification settings - Fork 94
Expand file tree
/
Copy pathexample.rb
More file actions
167 lines (131 loc) · 3.1 KB
/
example.rb
File metadata and controls
167 lines (131 loc) · 3.1 KB
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
require 'yaml'
# A helper class used in Runfile to generate example README files
class Example
class << self
def examples
filter_dirs('examples').map { |dir| new dir }
end
def fixtures
filter_dirs('spec/fixtures/workspaces')
.select { |dir| File.exist? "#{dir}/src/bashly.yml" }
.map { |dir| new dir, type: :fixture }
end
def all
examples + fixtures
end
private
def filter_dirs(base_dir)
Dir["#{base_dir}/*"].select { |f| File.directory? f }
end
end
attr_reader :dir, :type
def initialize(dir, type: :example)
@dir = dir
@type = type
end
def inspect
%[#<Example type=:#{type}, dir="#{dir}">]
end
def config
@config ||= if File.exist? yaml_path
YAML.unsafe_load_file yaml_path
else
{}
end
end
def yaml
@yaml ||= File.read(yaml_path).strip
end
def yaml_path
"#{dir}/src/bashly.yml"
end
def readme
@readme ||= File.exist?(readme_path) ? File.read(readme_path) : ''
end
def readme_path
"#{dir}/README.md"
end
def regenerate_readme
raise '#regenerate_readme called on a fixture' if type == :fixture
File.write readme_path, generated_readme
end
def executable
@executable ||= File.file?(executable_path) ? executable_path : nil
end
private
def executable_path
"#{dir}/#{config['name']}"
end
def test_commands
filename = "#{dir}/test.sh"
content = File.read filename
marker = '### Try Me ###'
return nil unless content.include? marker
result = content
.split(/\s*#{marker}\s*/).last
.split("\n")
.reject { |line| line.empty? or line.start_with? '#' }
abort "Can't find #{marker} marker in #{filename}" if result.empty?
result
end
def test_output
return nil unless test_commands
result = ''
test_commands.each do |command|
result += "### `$ #{command}`\n\n"
result += "````shell\n"
Dir.chdir dir do
result += `#{command} 2>&1`
result += "\n\n"
end
result += "````\n\n"
end
result
end
def generated_readme
marker = '-----'
content = readme.split(marker)[0].strip
extra_files = ''
if content =~ /<!-- include: (.*) -->/
included_files = $1.split
extra_files = files_markdown included_files
end
<<~MARKDOWN
#{content}
#{marker}
## `bashly.yml`
````yaml
#{yaml}
````
#{extra_files}
## Output
#{test_output || '*None*'}
MARKDOWN
end
def files_markdown(files)
result = []
files.each do |file|
lang = markdown_lang file
result << "## `#{file}`\n"
result << "````#{lang}"
result << File.read("#{dir}/#{file}")
result << "````\n"
end
result.join "\n"
end
def markdown_lang(file)
result = langs[File.extname file]
raise "Cannot determine language for #{file}" unless result
result
end
def langs
@langs ||= {
'' => 'bash',
'.md' => 'markdown',
'.sh' => 'bash',
'.ini' => 'ini',
'.yml' => 'yaml',
'.yaml' => 'yaml',
}
end
end