1use super::super::{
2 act,
3 cli_opt::{LogFormat, When},
4 cross_platform_path, file_list,
5 term::color::{ColorScheme, ColorfulScheme, ColorlessScheme},
6};
7use super::App;
8use pipe_trait::*;
9use relative_path::RelativePath;
10use std::{
11 env, fs,
12 io::{stdin, Read, Write},
13 path::{Path, PathBuf, MAIN_SEPARATOR},
14};
15use tap::tap::*;
16
17impl App {
18 pub fn run(&self) -> Result<(), String> {
20 let Self { opt, fmt } = self;
21
22 if opt.stdio {
23 let mut buffer = String::new();
24 stdin()
25 .read_to_string(&mut buffer)
26 .map_err(|error| format!("Failed to read from STDIN: {}", error))?;
27 let formatted = fmt
28 .format_text(&PathBuf::from("STDIN.ts"), &buffer)?
29 .unwrap_or(buffer);
30 print!("{}", formatted);
31 return Ok(());
32 }
33
34 let files = if opt.files.is_empty() && opt.include.is_none() {
35 file_list::default_files().map_err(|error| error.to_string())?
36 } else {
37 let files = opt
38 .files
39 .iter()
40 .map(|x| cross_platform_path::from_string(x.as_str(), MAIN_SEPARATOR))
41 .pipe(file_list::create_list)
42 .map_err(|error| error.to_string())?;
43 if let Some(list_file_address) = &opt.include {
44 list_file_address
45 .pipe(file_list::read_list)
46 .map_err(|error| error.to_string())?
47 .tap_mut(|x| x.extend(files))
48 } else {
49 files
50 }
51 };
52
53 let file_count = files.len();
54 let mut diff_count = 0;
55
56 let theme: &dyn ColorScheme = if opt.color == When::Never {
57 &ColorlessScheme
58 } else {
59 &ColorfulScheme
60 };
61
62 let log_same = act::log_same::get(opt.details, opt.hide_passed, theme);
63 let log_diff = act::log_diff::get(opt.details, opt.log_format, theme);
64 let may_write = act::may_write::get(opt.write);
65
66 for item in files {
67 let file_list::Item { path, .. } = item;
68
69 let path = if path.is_absolute() {
72 path
73 } else {
74 let path = if cfg!(unix) {
77 path
78 } else {
79 cross_platform_path::convert_path(&path, '/')
81 };
82
83 let path = path
84 .pipe_ref(RelativePath::from_path)
85 .unwrap()
86 .normalize()
87 .to_string();
88
89 let path: &Path = if path.starts_with("./") || path.starts_with(".\\") {
90 &path[2..]
91 } else {
92 &path
93 }
94 .as_ref();
95
96 if cfg!(unix) {
98 path.to_path_buf()
99 } else {
100 cross_platform_path::convert_path(path, MAIN_SEPARATOR)
101 }
102 };
103
104 let path = &path;
105 let file_content = fs::read_to_string(path).map_err(|error| {
106 format!(
107 "Failed to read {path:?}: {error}",
108 path = cross_platform_path::to_string(path, '/'),
109 error = error,
110 )
111 })?;
112
113 let formatted = fmt.format_text(path, &file_content).map_err(|error| {
114 format!(
115 "Failed to parse {path:?}: {error}",
116 path = cross_platform_path::to_string(path, '/'),
117 error = error,
118 )
119 })?;
120 if let Some(formatted) = formatted {
121 assert_ne!(file_content, formatted);
122 diff_count += 1;
123 log_diff(path, &file_content, &formatted);
124 may_write(path, &formatted).map_err(|error| {
125 format!(
126 "Failed to write to {path:?}: {error}",
127 path = cross_platform_path::to_string(path, '/'),
128 error = error,
129 )
130 })?;
131 } else {
132 log_same(path);
133 }
134 }
135
136 println!(
137 "SUMMARY: total {}; changed {}; unchanged {}",
138 file_count,
139 diff_count,
140 file_count - diff_count,
141 );
142
143 if opt.log_format == LogFormat::GitHubActions {
144 if let Some(gh_output_file) = env::var_os("GITHUB_OUTPUT") {
145 let mut gh_output_file = fs::OpenOptions::new()
146 .append(true)
147 .create(true)
148 .open(gh_output_file)
149 .unwrap();
150 writeln!(gh_output_file, "total={}", file_count).unwrap();
151 writeln!(gh_output_file, "changed={}", diff_count).unwrap();
152 writeln!(gh_output_file, "unchanged={}", file_count - diff_count).unwrap();
153 } else {
154 println!("::set-output name=total::{}", file_count);
155 println!("::set-output name=changed::{}", diff_count);
156 println!("::set-output name=unchanged::{}", file_count - diff_count);
157 }
158 }
159
160 if file_count == 0 {
161 return Err("No files found".to_string());
162 }
163
164 if !opt.write && diff_count != 0 {
165 return Err(format!("There are {} unformatted files", diff_count));
166 }
167
168 Ok(())
169 }
170}