1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
19 # Cmd that finds the mains of an `mentity`
23 redef fun init_results
do
24 if results
!= null then return new CmdSuccess
27 if not res
isa CmdSuccess then return res
28 var mentity
= self.mentity
.as(not null)
29 var mentities
= new Array[MEntity]
31 if mentity
isa MPackage then
32 for mmodule
in mentity
.collect_all_mmodules
(filter
) do
33 if mmodule_has_main
(mmodule
) then mentities
.add mmodule
35 else if mentity
isa MGroup then
36 for mmodule
in mentity
.collect_all_mmodules
(filter
) do
37 if mmodule_has_main
(mmodule
) then mentities
.add mmodule
39 else if mentity
isa MModule then
40 if mmodule_has_main
(mentity
) then mentities
.add mentity
42 return new WarningNoMains(mentity
)
45 if mentities
.is_empty
then return new WarningNoMains(mentity
)
47 self.results
= mentities
51 # Does `mmodule` has a `main` method?
52 private fun mmodule_has_main
(mmodule
: MModule): Bool do
53 for mclassdef
in mmodule
.collect_redef_mclassdefs
(filter
) do
54 if mclassdef
.name
!= "Sys" then continue
55 for mpropdef
in mclassdef
.collect_redef_mpropdefs
(filter
) do
56 if mpropdef
.name
== "main" then return true
63 # No tests for `mentity`
70 redef fun to_s
do return "No main found for `{mentity.full_name}`"
73 # Cmd that finds the nitc command related to an `mentity`
77 var file
: nullable SourceFile = null
79 var command
: nullable String is lazy
do
80 var path
= test_path
(file
)
81 if path
== null then return null
85 redef fun init_command
do
87 if not res
isa CmdSuccess then return res
88 var mentity
= self.mentity
.as(not null)
90 if mentity
isa MModule then
91 file
= mmodule_main
(mentity
)
92 if file
== null then return new WarningNoMain(mentity
)
94 return new WarningNoMain(mentity
)
99 # Does `mmodule` has a `main` method?
100 private fun mmodule_main
(mmodule
: MModule): nullable SourceFile do
101 for mclassdef
in mmodule
.mclassdefs
do
102 if mclassdef
.name
!= "Sys" then continue
103 for mpropdef
in mclassdef
.mpropdefs
do
104 if mpropdef
.name
== "main" then return mmodule
.location
.file
110 # Return the sourcefile path
112 # This method exists for the only purpose to be redefined by nitunit tests
113 # to avoid path diffs.
114 private fun test_path
(file
: nullable SourceFile): nullable String do
115 if file
== null then return null
116 var base_path
= mentity
.as(MModule).mpackage
.as(not null).location
.file
.as(not null).filename
117 return file
.filename
.replace
(base_path
, "")
121 # No tests for `mentity`
128 redef fun to_s
do return "No main to compile for `{mentity.full_name}`"
131 # Cmd that finds the nitunit command related to an `mentity`
135 var command
: nullable String is lazy
do
136 var results
= self.results
137 if results
== null then return null
139 var tpl
= new Template
141 for result
in results
do
142 var path
= test_path
(result
)
143 if path
== null then continue
146 return tpl
.write_to_string
149 redef fun init_results
do
150 if results
!= null then return new CmdSuccess
153 if not res
isa CmdSuccess then return res
154 var mentity
= self.mentity
.as(not null)
156 var mentities
= new Array[MEntity]
157 if not mentity
isa MPackage then return new WarningNoTest(mentity
)
159 for mgroup
in mentity
.collect_all_mgroups
(filter
) do
160 if mgroup
.is_test
then
164 for mmodule
in mgroup
.collect_mmodules
(filter
) do
165 if mmodule
.is_test
then mentities
.add mmodule
169 if mentities
.is_empty
then return new WarningNoTest(mentity
)
171 self.results
= mentities
175 # Return the mentity path
177 # This method exists for the only purpose to be redefined by nitunit tests
178 # to avoid path diffs.
179 private fun test_path
(mentity
: MEntity): nullable String do
180 var file
= mentity
.location
.file
181 if file
== null then return null
182 var base_path
= self.mentity
.as(not null).location
.file
.as(not null).filename
183 return file
.filename
.replace
(base_path
, "")
187 # No tests for `mentity`
194 redef fun to_s
do return "No nitunit files for `{mentity.full_name}`"
197 # Cmd that finds the man file related to an `mentity`
202 var file
: nullable String = null
204 redef fun init_command
do
206 if not res
isa CmdSuccess then return res
207 var mentity
= self.mentity
.as(not null)
210 if mentity
isa MPackage then
212 else if mentity
isa MGroup then
213 mpackage
= mentity
.mpackage
214 else if mentity
isa MModule then
215 mpackage
= mentity
.mpackage
218 if mpackage
== null then return new WarningNoManFile(mentity
)
220 var source_file
= mpackage
.location
.file
221 if source_file
== null then return new WarningNoManFile(mentity
)
223 var man_dir
= source_file
.filename
/ "man"
224 if not man_dir
.file_exists
then return new WarningNoManFile(mentity
)
227 for file
in man_dir
.files
do
228 if not file
.has_prefix
(mentity
.name
) then continue
229 man_file
= man_dir
/ file
231 if man_file
== null then return new WarningNoManFile(mentity
)
239 # No man file for `mentity`
240 class WarningNoManFile
246 redef fun to_s
do return "No man file for `{mentity.full_name}`"
252 # Synopsis string extracted from man
253 var synopsis
: nullable String
255 redef fun init_command
do
257 if not res
isa CmdSuccess then return res
258 var mentity
= self.mentity
.as(not null)
259 var file
= self.file
.as(not null)
261 var lines
= file
.to_path
.read_lines
262 var in_synopsis
= false
264 if in_synopsis
and line
.has_prefix
(mentity
.name
) then
268 if line
!= "# SYNOPSIS" then continue
272 if synopsis
== null then return new WarningNoManSynopsis(mentity
)
278 # No synopsis found in the man file for `mentity`
279 class WarningNoManSynopsis
285 redef fun to_s
do return "No synopsis found in the man file for `{mentity.full_name}`"
291 # Options description
292 var options
: nullable ArrayMap[String, String]
294 redef fun init_command
do
296 if not res
isa CmdSuccess then return res
297 var mentity
= self.mentity
.as(not null)
298 var file
= self.file
.as(not null)
300 var options
= new ArrayMap[String, String]
302 var lines
= file
.to_path
.read_lines
303 var in_options
= false
304 for i
in [0 .. lines
.length
[ do
306 if line
== "# OPTIONS" then
308 else if in_options
and line
.has_prefix
("### ") then
309 var opt
= line
.substring
(4, line
.length
).trim
.replace
("`", "")
311 if i
< lines
.length
- 1 then
312 desc
= lines
[i
+ 1].trim
315 else if line
.has_prefix
("# ") then
320 if options
.is_empty
then return new WarningNoManOptions(mentity
)
321 self.options
= options
327 # No options description found in the man file for `mentity`
328 class WarningNoManOptions
334 redef fun to_s
do return "No options description found in the man file for `{mentity.full_name}`"