nitpretty: does not force break on string literals anymore
[nit.git] / src / nitpretty.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
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
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 # `nitpretty` is a tool able to pretty print Nit files.
16 #
17 # See `man nitpretty` for more infos.
18 import pretty
19
20 redef class ToolContext
21 # The working directory used to store temp files.
22 var opt_dir = new OptionString("Working directory (default is '.nitpretty')", "--dir")
23
24 # Output pretty printed code with this filename.
25 var opt_output = new OptionString("Output name (default is pretty.nit)", "-o",
26 "--output")
27
28 # Show diff between source and pretty printed code.
29 var opt_diff = new OptionBool("Show diff between source and output", "--diff")
30
31 # Show diff between source and pretty printed code using meld.
32 var opt_meld = new OptionBool("Show diff between source and output using meld",
33 "--meld")
34
35 # Break too long string literals.
36 var opt_break_str = new OptionBool("Break too long string literals", "--break-strings")
37
38 # Check formatting instead of pretty printing.
39 #
40 # This option create a tempory pretty printed file then check if
41 # the output of the diff command on the source file and the pretty
42 # printed one is empty.
43 var opt_check = new OptionBool("Check format of Nit source files", "--check")
44 end
45
46 # Return result from diff between `file1` and `file2`.
47 private fun diff(file1, file2: String): String do
48 var p = new IProcess("diff", "-u", file1, file2)
49 var res = p.read_all
50 p.wait
51 p.close
52 return res
53 end
54
55 # process options
56 var toolcontext = new ToolContext
57
58 toolcontext.option_context.
59 add_option(toolcontext.opt_dir, toolcontext.opt_output, toolcontext.opt_diff,
60 toolcontext.opt_meld, toolcontext.opt_check, toolcontext.opt_break_str)
61
62 toolcontext.tooldescription = "Usage: nitpretty [OPTION]... <file.nit>\n" +
63 "Pretty print Nit code from Nit source files."
64
65 toolcontext.process_options args
66 var arguments = toolcontext.option_context.rest
67 # build model
68 var model = new Model
69 var mbuilder = new ModelBuilder(model, toolcontext)
70 var mmodules = mbuilder.parse(arguments)
71 mbuilder.run_phases
72
73 if mmodules.is_empty then
74 print "Error: no module to pretty print"
75 return
76 end
77
78 if not toolcontext.opt_check.value and mmodules.length > 1 then
79 print "Error: only --check option allow multiple modules"
80 return
81 end
82
83 var dir = toolcontext.opt_dir.value or else ".nitpretty"
84 if not dir.file_exists then dir.mkdir
85 var v = new PrettyPrinterVisitor
86
87 if toolcontext.opt_break_str.value then
88 v.break_strings = true
89 end
90
91 for mmodule in mmodules do
92 if not mbuilder.mmodule2nmodule.has_key(mmodule) then
93 print " Error: no source file for module {mmodule}"
94 return
95 end
96
97 var nmodule = mbuilder.mmodule2nmodule[mmodule]
98 var file = "{dir}/{mmodule.name}.nit"
99 var tpl = v.pretty_nmodule(nmodule)
100 tpl.write_to_file file
101
102 if toolcontext.opt_check.value then
103 var res = diff(nmodule.location.file.filename, file)
104
105 if not res.is_empty then
106 print "Wrong formating for module {nmodule.location.file.filename}"
107 toolcontext.info(res, 1)
108
109 if toolcontext.opt_meld.value then
110 sys.system "meld {nmodule.location.file.filename} {file}"
111 end
112 else
113 toolcontext.info("[OK] {nmodule.location.file.filename}", 1)
114 end
115 else
116 # write to file
117 var out = toolcontext.opt_output.value
118 if out != null then sys.system "cp {file} {out}"
119
120 # open in meld
121 if toolcontext.opt_meld.value then
122 sys.system "meld {arguments.first} {file}"
123 return
124 end
125
126 # show diff
127 if toolcontext.opt_diff.value then
128 var res = diff(arguments.first, file)
129 if not res.is_empty then print res
130 return
131 end
132
133 # show pretty
134 if not toolcontext.opt_quiet.value then tpl.write_to sys.stdout
135 end
136 end