Module: MilkTea::CLI::CommandFormat
- Included in:
- MilkTea::CLI
- Defined in:
- lib/milk_tea/tooling/cli/commands/format.rb
Instance Method Summary collapse
- #format_command ⇒ Object
- #format_paths(paths, options) ⇒ Object
- #parse_format_options ⇒ Object
- #print_file_profiles(file_profiles, label) ⇒ Object
Instance Method Details
#format_command ⇒ Object
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 |
# File 'lib/milk_tea/tooling/cli/commands/format.rb', line 6 def format_command parsed = return 1 unless parsed = parsed[:options] input_paths = parsed[:input_paths] if input_paths.empty? @err.puts("missing source file path") print_usage(@err) return 1 end paths = (input_paths) return 0 if print_no_source_files_if_empty(paths, input_paths) multiple_sources = input_paths.length > 1 || input_paths.any? { |path| File.directory?(path) } if multiple_sources unless [:check] || [:write] @err.puts("format on multiple sources requires --check or --write") print_usage(@err) return 1 end return format_paths(paths, ) end path = paths.first source = read_source_file(path) format_profile = [:profile] ? Linter::Profile.new : nil start_time = [:profile] ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : nil result = Formatter.check_source(source, path: path, mode: [:mode], max_line_length: [:max_line_length], profile: format_profile) elapsed_ms = start_time ? ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000.0).round(1) : nil rc = if [:check] announce_file_action(path, "format-check") if result.changed info("needs formatting #{path}") 1 else info("already formatted #{path}") 0 end elsif [:write] announce_file_action(path, "format-write") if result.changed File.write(path, result.formatted_source) info("formatted #{path}") else info("already formatted #{path}") end 0 else @out.write(result.formatted_source) 0 end print_file_profiles([{ path:, total_ms: elapsed_ms, profile: format_profile }], "format") if [:profile] rc end |
#format_paths(paths, options) ⇒ Object
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 |
# File 'lib/milk_tea/tooling/cli/commands/format.rb', line 68 def format_paths(paths, ) format_profiles = [] if [:check] needs_fmt = [] paths.each do |p| announce_file_action(p, "format-check") format_profile = [:profile] ? Linter::Profile.new : nil start_time = [:profile] ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : nil result = Formatter.check_source(read_source_file(p), path: p, mode: [:mode], max_line_length: [:max_line_length], profile: format_profile) elapsed_ms = start_time ? ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000.0).round(1) : nil format_profiles << { path: p, total_ms: elapsed_ms, profile: format_profile } if [:profile] needs_fmt << p if result.changed end print_file_profiles(format_profiles, "format") if [:profile] if needs_fmt.empty? info("all #{paths.size} file(s) already formatted") return 0 end needs_fmt.each { |p| info("needs formatting #{p}") } info("#{needs_fmt.size} file(s) need formatting") return 1 end # --write changed = 0 paths.each do |p| announce_file_action(p, "format-write") format_profile = [:profile] ? Linter::Profile.new : nil start_time = [:profile] ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : nil result = Formatter.check_source(read_source_file(p), path: p, mode: [:mode], max_line_length: [:max_line_length], profile: format_profile) elapsed_ms = start_time ? ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000.0).round(1) : nil format_profiles << { path: p, total_ms: elapsed_ms, profile: format_profile } if [:profile] if result.changed File.write(p, result.formatted_source) info("formatted #{p}") changed += 1 end end print_file_profiles(format_profiles, "format") if [:profile] info("formatted #{changed} of #{paths.size} file(s)") 0 end |
#parse_format_options ⇒ Object
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 168 169 170 171 |
# File 'lib/milk_tea/tooling/cli/commands/format.rb', line 111 def = { check: false, write: false, mode: :safe, max_line_length: nil, profile: false, } input_paths = [] until @argv.empty? option = @argv.shift if option.start_with?("-") case option when "--check" [:check] = true when "--write", "-w" [:write] = true when "--preserve" [:mode] = :preserve when "--canonical" [:mode] = :canonical when "--safe" [:mode] = :safe when "--tidy" [:mode] = :tidy when "--max-line-length" value = @argv.shift return missing_option_value(option) unless value line_length = Integer(value, exception: false) unless line_length && line_length.positive? @err.puts("--max-line-length must be a positive integer") print_usage(@err) return nil end [:max_line_length] = line_length when "--timings" [:profile] = true when "--" input_paths.concat(@argv) @argv.clear else @err.puts("unknown format option #{option}") print_usage(@err) return nil end else input_paths << option end end if [:check] && [:write] @err.puts("format options --check and --write cannot be combined") print_usage(@err) return nil end { options:, input_paths: } end |
#print_file_profiles(file_profiles, label) ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/milk_tea/tooling/cli/commands/format.rb', line 173 def print_file_profiles(file_profiles, label) sorted = file_profiles.sort_by { |fp| -fp[:total_ms] } return if sorted.empty? @out.puts if sorted.size == 1 entry = sorted.first phases = entry[:profile]&.timings_ms&.sort_by { |_, ms| -ms } phase_str = phases&.filter_map { |name, ms| "#{name}: #{format('%.1f', ms)}ms" if ms >= 0.1 }&.join(", ") detail = phase_str && !phase_str.empty? ? " (#{phase_str})" : "" @out.puts("#{label} profile #{entry[:path]}: #{format('%.1f', entry[:total_ms])}ms#{detail}") return end @out.puts("Profile (#{label}): #{sorted.size} file(s)") sorted.each do |entry| phases = entry[:profile]&.timings_ms&.sort_by { |_, ms| -ms } phase_str = phases&.filter_map { |name, ms| "#{name}: #{format('%.1f', ms)}ms" if ms >= 1.0 }&.join(", ") detail = phase_str && !phase_str.empty? ? " (#{phase_str})" : "" @out.puts(" #{entry[:path]}: #{format('%.1f', entry[:total_ms])}ms#{detail}") end total = sorted.sum { |fp| fp[:total_ms] } @out.puts("Total: #{format('%.1f', total)}ms") end |