A code formatter for Julia with rules set in stone.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

148 lines
4.1 KiB

# SPDX-License-Identifier: MIT
errno::Cint = 0
function panic(msg...)
printstyled(stderr, "ERROR: "; color = :red, bold = true)
for m in msg
if m isa Exception
showerror(stderr, m)
else
print(stderr, msg...)
end
end
println(stderr)
global errno = 1
return errno
end
function (@main)(argv)
# Reset errno
global errno = 0
# Default values
inputfiles = String[]
outputfile = nothing
verbose = false
debug = false
inplace = false
# Parse the arguments
while length(argv) > 0
x = popfirst!(argv)
if x == "-i"
inplace = true
elseif x == "-v"
verbose = true
elseif x == "-vv"
debug = verbose = true
elseif x == "-o"
if length(argv) < 1
return panic("expected output file as argument after `-o`")
end
outputfile = popfirst!(argv)
else
# Remaining arguments must be inputfile(s)
push!(inputfiles, x)
for x in argv
if x == "-"
return panic("input \"-\" can not be used with multiple files")
end
push!(inputfiles, x)
end
break
end
end
# stdin is the default input
if isempty(inputfiles)
push!(inputfiles, "-")
end
# multiple files require -i and no -o
if length(inputfiles) > 1
if !inplace
return panic("option `-i` is required for multiple input files")
elseif outputfile !== nothing
return panic("option `-o` is incompatible with multiple input files")
end
end
# inplace = true is incompatible with given output
if inplace && outputfile !== nothing
@assert length(inputfiles) == 1
return panic("option `-i` is incompatible with option `-o $(outputfile)`")
end
# inplace = true is incompatible with stdin as input
if inplace && first(inputfiles) == "-"
return panic("option `-i` is incompatible with stdin as input")
end
# Loop over the input files
for inputfile in inputfiles
# Read the input
input_is_file = true
if inputfile == "-"
input_is_file = false
sourcetext = try
read(stdin, String)
catch err
return panic("could not read input from stdin: ", err)
end
elseif isfile(inputfile)
sourcetext = try
read(inputfile, String)
catch err
panic("could not read input from file `$(inputfile)`: ", err)
continue
end
else
panic("input file does not exist: `$(inputfile)`")
continue
end
# Check output
if inplace
@assert outputfile === nothing
@assert isfile(inputfile)
@assert input_is_file
# @assert length(inputfiles) == 1 # checked above
output = inputfile
else
@assert length(inputfiles) == 1
if outputfile === nothing || outputfile == "-"
output = stdout
elseif isfile(outputfile) && input_is_file && samefile(outputfile, inputfile)
return panic("can not use same file for input and output, use `-i` to modify a file in place")
else
output = outputfile
end
end
# Call the library to format the text
ctx = try
ctx = Context(sourcetext; verbose = verbose, debug = debug)
format_tree!(ctx)
ctx
catch err
panic(err)
continue
end
# Write the output, but skip if inplace and it didn't change
changed = ctx.fmt_tree !== ctx.src_tree
if changed || !inplace
try
write(output, take!(ctx.fmt_io))
catch err
panic("could not write to output: ", err)
end
else
# Log if verbose perhaps
end
end # inputfile loop
return errno
end