1#[cfg(test)]
7#[path = "io_test.rs"]
8mod io_test;
9
10use crate::error::CargoMakeError;
11use fsio::file::modify_file;
12use fsio::path as fsio_path;
13use fsio::path::from_path::FromPath;
14use glob::glob;
15use ignore::WalkBuilder;
16use std::collections::HashSet;
17use std::fs::File;
18use std::io;
19use std::path::PathBuf;
20
21pub(crate) fn create_text_file(text: &str, extension: &str) -> Result<String, CargoMakeError> {
22 let file_path = fsio_path::get_temporary_file_path(extension);
23
24 match fsio::file::write_text_file(&file_path, text) {
25 Ok(_) => Ok(file_path),
26 Err(error) => {
27 error!("Unable to create file: {} {:#?}", &file_path, &error);
28 Err(error.into())
29 }
30 }
31}
32
33pub(crate) fn create_file(
34 write_content: &dyn Fn(&mut File) -> io::Result<()>,
35 extension: &str,
36) -> Result<String, CargoMakeError> {
37 let file_path = fsio_path::get_temporary_file_path(extension);
38
39 match modify_file(&file_path, write_content, false) {
40 Ok(_) => Ok(file_path),
41 Err(error) => {
42 error!("Unable to write to file: {} {:#?}", &file_path, &error);
43 Err(error.into())
44 }
45 }
46}
47
48pub(crate) fn delete_file(file: &str) {
49 match fsio::file::delete(file) {
50 Ok(_) => debug!("File deleted: {}", &file),
51 Err(error) => debug!("Unable to delete file: {} {:#?}", &file, error),
52 }
53}
54
55pub(crate) fn write_text_file(file_path: &str, text: &str) -> bool {
56 match fsio::file::write_text_file(file_path, text) {
57 Ok(_) => true,
58 Err(_) => false,
59 }
60}
61
62pub(crate) fn read_text_file(file_path: &PathBuf) -> Result<String, CargoMakeError> {
63 debug!("Opening file: {:#?}", &file_path);
64
65 Ok(fsio::file::read_text_file(file_path)?)
66}
67
68pub(crate) fn get_path_list(
69 glob_pattern: &str,
70 include_files: bool,
71 include_dirs: bool,
72 ignore_type: Option<String>,
73) -> Vec<String> {
74 let mut path_list = vec![];
75 match glob(glob_pattern) {
76 Ok(paths) => {
77 for entry in paths {
78 match entry {
79 Ok(path) => {
80 if (include_dirs && path.is_dir()) || (include_files && path.is_file()) {
81 let mut value_string: String = FromPath::from_path(&path);
82 value_string = value_string.replace("\\", "/");
83 if !value_string.starts_with("./") {
84 value_string.insert_str(0, "./");
85 }
86
87 path_list.push(value_string);
88 }
89 }
90 Err(error) => {
91 error!(
92 "Error while iterating over path entries of glob: {}, error: {:#?}",
93 glob_pattern, error
94 );
95 return vec![];
96 }
97 }
98 }
99 }
100 Err(error) => {
101 error!(
102 "Error while running glob: {}, error: {:#?}",
103 glob_pattern, error
104 );
105 return vec![];
106 }
107 }
108
109 if !path_list.is_empty() {
110 if let Some(ignore_type_value) = ignore_type {
111 let mut included_paths = HashSet::new();
112
113 match ignore_type_value.as_str() {
114 "git" => {
115 for entry in WalkBuilder::new("./")
116 .hidden(true)
117 .parents(true)
118 .git_ignore(true)
119 .git_exclude(true)
120 .build()
121 {
122 match entry {
123 Ok(path) => {
124 let mut value_string: String = FromPath::from_path(&path.path());
125 value_string = value_string.replace("\\", "/");
126 included_paths.insert(value_string);
127 }
128 Err(error) => error!(
129 "Error while running git ignore path checks, error: {:#?}",
130 error
131 ),
132 }
133 }
134 }
135 _ => error!("Unsupported ignore type: {}", &ignore_type_value),
136 };
137
138 if included_paths.is_empty() {
139 path_list.clear();
140 } else {
141 let org_path_list = path_list;
142 path_list = vec![];
143 for path in org_path_list {
144 if included_paths.contains(&path) {
145 path_list.push(path);
146 }
147 }
148 }
149 }
150 }
151
152 path_list
153}
154
155pub(crate) fn canonicalize_to_string(path_string: &str) -> String {
156 fsio_path::canonicalize_or(path_string, path_string)
157}