mirror of
https://github.com/numtide/treefmt.git
synced 2024-08-16 20:30:25 +03:00
adding working directory option on prjfmt.toml for each formatter (#59)
* adding working directory option on prjfmt.toml for each formatter * rename workdir into work_dir * switch from xshell into process::Command * fix unordered command_context by changing to BTreeMap
This commit is contained in:
parent
f53c70d5ac
commit
3ad67a3851
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"nixEnvSelector.nixShellConfig": "${workspaceRoot}/shell.nix",
|
"files.trimFinalNewlines": true,
|
||||||
"files.trimFinalNewlines": true
|
"nixEnvSelector.nixFile": "${workspaceRoot}/shell.nix"
|
||||||
}
|
}
|
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -610,7 +610,6 @@ dependencies = [
|
|||||||
"structopt",
|
"structopt",
|
||||||
"toml",
|
"toml",
|
||||||
"which",
|
"which",
|
||||||
"xshell",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -700,18 +699,3 @@ name = "winapi-x86_64-pc-windows-gnu"
|
|||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xshell"
|
|
||||||
version = "0.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ed373ede30cea03e8c0af22f48ee1ba80efbf06fec8b4746977e6ee703878de0"
|
|
||||||
dependencies = [
|
|
||||||
"xshell-macros",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xshell-macros"
|
|
||||||
version = "0.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7f6af9f8119104697b0105989a73c578ce33f922d9d6f3dae0e8ae3d538db321"
|
|
||||||
|
@ -21,5 +21,4 @@ serde_json = "1.0"
|
|||||||
sha-1 = "0.9.2"
|
sha-1 = "0.9.2"
|
||||||
structopt = "0.3"
|
structopt = "0.3"
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
xshell = "0.1"
|
|
||||||
which = "4.0.2"
|
which = "4.0.2"
|
||||||
|
@ -12,10 +12,11 @@ A formatter MUST adhere to the following interface:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Where
|
Where
|
||||||
* `<command>` is the name of the formatter.
|
|
||||||
* `[options]` is any number of flags and options that the formatter wants to
|
- `<command>` is the name of the formatter.
|
||||||
provide.
|
- `[options]` is any number of flags and options that the formatter wants to
|
||||||
* `[...<files>]` is one or more files that the formatter should process.
|
provide.
|
||||||
|
- `[...<files>]` is one or more files that the formatter should process.
|
||||||
|
|
||||||
Whenever the program is invoked with the list of files, it MUST only process all the files that are passed and format them. Files that are not passed should never be formatted.
|
Whenever the program is invoked with the list of files, it MUST only process all the files that are passed and format them. Files that are not passed should never be formatted.
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
# A list of known formatters
|
# A list of known formatters
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| name | files as argument | write-in-place | update-mtime |
|
| name | files as argument | write-in-place | update-mtime |
|
||||||
|-----------|-------------------|----------------|----------------------|
|
| --------- | ----------------- | -------------- | -------------------- |
|
||||||
| gofmt | yes | yes | keeps the same mtime |
|
| gofmt | yes | yes | keeps the same mtime |
|
||||||
| cargo fmt | no | yes | yes |
|
| cargo fmt | no | yes | yes |
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
## 0.1.0.0 -- YYYY-mm-dd
|
## 0.1.0.0 -- YYYY-mm-dd
|
||||||
|
|
||||||
* First version. Released on an unsuspecting world.
|
- First version. Released on an unsuspecting world.
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
## 0.1.0.0 -- YYYY-mm-dd
|
## 0.1.0.0 -- YYYY-mm-dd
|
||||||
|
|
||||||
* First version. Released on an unsuspecting world.
|
- First version. Released on an unsuspecting world.
|
||||||
|
@ -20,6 +20,8 @@ pub struct Root {
|
|||||||
pub struct FmtConfig {
|
pub struct FmtConfig {
|
||||||
/// Command formatter to run
|
/// Command formatter to run
|
||||||
pub command: String,
|
pub command: String,
|
||||||
|
/// Working directory for formatter
|
||||||
|
pub work_dir: Option<String>,
|
||||||
/// Argument for formatter
|
/// Argument for formatter
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub options: Vec<String>,
|
pub options: Vec<String>,
|
||||||
|
@ -9,8 +9,8 @@ use std::collections::BTreeSet;
|
|||||||
use std::fs::metadata;
|
use std::fs::metadata;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
use which::which;
|
use which::which;
|
||||||
use xshell::cmd;
|
|
||||||
|
|
||||||
/// Make sure that formatter binary exists. This also for other formatter
|
/// Make sure that formatter binary exists. This also for other formatter
|
||||||
pub fn check_bin(command: &str) -> Result<()> {
|
pub fn check_bin(command: &str) -> Result<()> {
|
||||||
@ -61,6 +61,10 @@ pub fn run_treefmt(cwd: PathBuf, cache_dir: PathBuf) -> anyhow::Result<()> {
|
|||||||
for c in context {
|
for c in context {
|
||||||
if !c.metadata.is_empty() {
|
if !c.metadata.is_empty() {
|
||||||
println!("Command: {}", c.command);
|
println!("Command: {}", c.command);
|
||||||
|
println!(
|
||||||
|
"Working Directory: {}",
|
||||||
|
c.work_dir.clone().unwrap_or("".to_string())
|
||||||
|
);
|
||||||
println!("Files:");
|
println!("Files:");
|
||||||
for m in &c.metadata {
|
for m in &c.metadata {
|
||||||
let path = &m.path;
|
let path = &m.path;
|
||||||
@ -71,17 +75,29 @@ pub fn run_treefmt(cwd: PathBuf, cache_dir: PathBuf) -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: report errors (both Err(_), and Ok(bad status))
|
// TODO: report errors (both Err(_), and Ok(bad status))
|
||||||
let _outputs: Vec<xshell::Result<std::process::Output>> = context
|
let _outputs: Vec<std::io::Result<std::process::Output>> = context
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|c| {
|
.map(|c| {
|
||||||
let arg = &c.options;
|
let arg = &c.options;
|
||||||
let cmd_arg = &c.command;
|
let mut cmd_arg = Command::new(&c.command);
|
||||||
|
let work_dir = match c.work_dir.clone() {
|
||||||
|
Some(x) => x,
|
||||||
|
None => String::new(),
|
||||||
|
};
|
||||||
let paths = c.metadata.iter().map(|f| &f.path);
|
let paths = c.metadata.iter().map(|f| &f.path);
|
||||||
cmd!("{cmd_arg} {arg...} {paths...}").output()
|
if !work_dir.is_empty() {
|
||||||
|
let _x = std::env::set_current_dir(work_dir);
|
||||||
|
cmd_arg.args(arg).args(paths).output()
|
||||||
|
} else {
|
||||||
|
let _x = std::env::set_current_dir(cwd.clone());
|
||||||
|
cmd_arg.args(arg).args(paths).output()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if mfst.manifest.is_empty() || ctxs.is_empty() {
|
if mfst.manifest.is_empty() && ctxs.is_empty() {
|
||||||
|
CLOG.info("First time running treefmt");
|
||||||
|
CLOG.info("capturing formatted file's state...");
|
||||||
create_manifest(treefmt_toml, cache_dir, old_ctx)?;
|
create_manifest(treefmt_toml, cache_dir, old_ctx)?;
|
||||||
} else {
|
} else {
|
||||||
// Read the current status of files and insert into the manifest.
|
// Read the current status of files and insert into the manifest.
|
||||||
@ -161,6 +177,7 @@ pub fn create_command_context(
|
|||||||
Ok(CmdContext {
|
Ok(CmdContext {
|
||||||
command: config.command.clone(),
|
command: config.command.clone(),
|
||||||
options: config.options.clone(),
|
options: config.options.clone(),
|
||||||
|
work_dir: config.work_dir.clone(),
|
||||||
metadata: path_to_filemeta(list_files)?,
|
metadata: path_to_filemeta(list_files)?,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -30,6 +30,7 @@ pub fn create_manifest(
|
|||||||
let treefmt = cmd.command;
|
let treefmt = cmd.command;
|
||||||
let manifest = CmdContext {
|
let manifest = CmdContext {
|
||||||
command: treefmt.to_string(),
|
command: treefmt.to_string(),
|
||||||
|
work_dir: cmd.work_dir,
|
||||||
options: cmd.options,
|
options: cmd.options,
|
||||||
metadata: cmd.metadata,
|
metadata: cmd.metadata,
|
||||||
};
|
};
|
||||||
@ -102,15 +103,32 @@ pub fn check_treefmt(
|
|||||||
cache: &RootManifest,
|
cache: &RootManifest,
|
||||||
) -> Result<Vec<CmdContext>> {
|
) -> Result<Vec<CmdContext>> {
|
||||||
let cache_context = cache.manifest.values();
|
let cache_context = cache.manifest.values();
|
||||||
let results = cmd_context.iter().zip(cache_context);
|
let map_ctx: BTreeMap<String, CmdContext> = cmd_context
|
||||||
|
.into_iter()
|
||||||
|
.map(|cmd| {
|
||||||
|
let treefmt = cmd.command.clone();
|
||||||
|
let ctx = CmdContext {
|
||||||
|
command: treefmt.to_string(),
|
||||||
|
work_dir: cmd.work_dir.clone(),
|
||||||
|
options: cmd.options.clone(),
|
||||||
|
metadata: cmd.metadata.clone(),
|
||||||
|
};
|
||||||
|
(treefmt, ctx)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let new_cmd_ctx = map_ctx.values();
|
||||||
|
let results = new_cmd_ctx.clone().into_iter().zip(cache_context);
|
||||||
let cache_context: Vec<CmdContext> = results
|
let cache_context: Vec<CmdContext> = results
|
||||||
.clone()
|
.clone()
|
||||||
.map(|(new, old)| {
|
.map(|(new, old)| {
|
||||||
Ok(CmdContext {
|
Ok(CmdContext {
|
||||||
command: new.command.clone(),
|
command: new.command.clone(),
|
||||||
|
work_dir: new.work_dir.clone(),
|
||||||
options: new.options.clone(),
|
options: new.options.clone(),
|
||||||
metadata: if new.command != old.command || new.options != old.options {
|
metadata: if new.command != old.command
|
||||||
|
|| new.options != old.options
|
||||||
|
|| new.work_dir != old.work_dir
|
||||||
|
{
|
||||||
// If either the command or the options have changed, invalidate old entries
|
// If either the command or the options have changed, invalidate old entries
|
||||||
new.metadata.clone()
|
new.metadata.clone()
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,6 +21,8 @@ pub static CLOG: CustomLogOutput = CustomLogOutput::new();
|
|||||||
pub struct CmdContext {
|
pub struct CmdContext {
|
||||||
/// formatter command to run
|
/// formatter command to run
|
||||||
pub command: String,
|
pub command: String,
|
||||||
|
/// formatter work_dir
|
||||||
|
pub work_dir: Option<String>,
|
||||||
/// formatter arguments or flags
|
/// formatter arguments or flags
|
||||||
pub options: Vec<String>,
|
pub options: Vec<String>,
|
||||||
/// formatter target path
|
/// formatter target path
|
||||||
@ -30,6 +32,7 @@ pub struct CmdContext {
|
|||||||
impl PartialEq for CmdContext {
|
impl PartialEq for CmdContext {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.command == other.command
|
self.command == other.command
|
||||||
|
&& self.work_dir == other.work_dir
|
||||||
&& self.options == other.options
|
&& self.options == other.options
|
||||||
&& self.metadata == other.metadata
|
&& self.metadata == other.metadata
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user