From c5783fb9be0af828055f886b03a6ccdf1b838b24 Mon Sep 17 00:00:00 2001 From: marschattha Date: Wed, 4 Mar 2026 03:54:50 +0500 Subject: [PATCH 1/2] fix(check): skip exported config for formatters when workspace file exists Load repository config files into the staging area before exported configs so that workspace files take precedence. The existing to.exists() guard in load_config_file_from naturally skips the exported config when the workspace file is already present, making formatter behavior consistent with linters. Co-Authored-By: Claude Opus 4.6 --- qlty-check/src/executor.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/qlty-check/src/executor.rs b/qlty-check/src/executor.rs index c1307bf51..9bc947608 100644 --- a/qlty-check/src/executor.rs +++ b/qlty-check/src/executor.rs @@ -314,7 +314,20 @@ impl Executor { let mut loaded_config_files = vec![]; - // load exported config paths before anything else + // load repository config files first so that workspace files take + // precedence over exported configs in the staging area + for config_file in &repository_config_files { + if let Err(err) = load_config_file_from_repository( + config_file, + &self.plan.workspace, + &self.plan.staging_area.destination_directory, + ) { + error!("Failed to load config file from repository: {:?}", err); + } + } + + // load exported config paths — these are skipped if the file already + // exists in the destination (e.g. from a workspace config file above) for config_file in &exported_config_paths { if self.plan.workspace.root != self.plan.staging_area.destination_directory { // for formatters @@ -337,16 +350,6 @@ impl Executor { self.check_and_copy_configs_into_tool_install(&mut loaded_config_files)?; self.plan_plugins_fetch(&mut loaded_config_files)?; - for config_file in &repository_config_files { - if let Err(err) = load_config_file_from_repository( - config_file, - &self.plan.workspace, - &self.plan.staging_area.destination_directory, - ) { - error!("Failed to load config file from repository: {:?}", err); - } - } - for config_file in &config_file_names { if self.plan.workspace.root != self.plan.staging_area.destination_directory { // for formatters From 4b588afc2d4d823d88ece1e30d2ad89891f57643 Mon Sep 17 00:00:00 2001 From: marschattha Date: Thu, 5 Mar 2026 17:30:31 +0500 Subject: [PATCH 2/2] test(check): add integration test for workspace config precedence over exported config Verify that workspace config files take precedence over exported config files for both linters and formatters. The test uses distinct issue messages ("WORKSPACE" vs "EXPORTED") so a failure directly indicates which plugin used the wrong config. Co-Authored-By: Claude Opus 4.6 --- .../.gitignore | 4 +++ .../.qlty/qlty.toml | 13 ++++++++ .../config-source/formatter-results.txt | 1 + .../config-source/linter-results.txt | 1 + .../config-source/source.toml | 30 +++++++++++++++++++ .../formatter-results.txt | 1 + .../linter-results.txt | 1 + .../sample.sh | 2 ++ ...xported_config_workspace_precedence.stderr | 1 + ...xported_config_workspace_precedence.stdout | 7 +++++ .../exported_config_workspace_precedence.toml | 3 ++ 11 files changed, 64 insertions(+) create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/.gitignore create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/.qlty/qlty.toml create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/formatter-results.txt create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/linter-results.txt create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/source.toml create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/formatter-results.txt create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/linter-results.txt create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/sample.sh create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.stderr create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.stdout create mode 100644 qlty-cli/tests/cmd/check/exported_config_workspace_precedence.toml diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/.gitignore b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/.gitignore new file mode 100644 index 000000000..abbd1c70e --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/.gitignore @@ -0,0 +1,4 @@ +.qlty/results +.qlty/logs +.qlty/out +.qlty/sources diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/.qlty/qlty.toml b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/.qlty/qlty.toml new file mode 100644 index 000000000..245a6b2e6 --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/.qlty/qlty.toml @@ -0,0 +1,13 @@ +config_version = "0" + +[[source]] +name = "config-source" +directory = "config-source" + +[[plugin]] +name = "precedence-linter" +version = "1.0.0" + +[[plugin]] +name = "precedence-formatter" +version = "1.0.0" diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/formatter-results.txt b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/formatter-results.txt new file mode 100644 index 000000000..80cc9773a --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/formatter-results.txt @@ -0,0 +1 @@ +sample.sh:2:1: EXPORTED formatter used exported config diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/linter-results.txt b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/linter-results.txt new file mode 100644 index 000000000..146f2b5a4 --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/linter-results.txt @@ -0,0 +1 @@ +sample.sh:2:1: EXPORTED linter used exported config diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/source.toml b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/source.toml new file mode 100644 index 000000000..577a94e0f --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/config-source/source.toml @@ -0,0 +1,30 @@ +config_version = "0" + +[plugins.definitions.precedence-linter] +file_types = ["shell"] +config_files = ["linter-results.txt"] +exported_config_paths = [ + "linter-results.txt", +] + +[plugins.definitions.precedence-linter.drivers.lint] +prepare_script = "mkdir ${linter} && echo type %1 > ${linter}/cat.cmd || echo type %1 > ${linter}/cat.cmd" +script = "cat linter-results.txt" +output_format = "regex" +output_regex = "((?P.*):(?P-?\\d+):(?P-?\\d+): (?P\\S+) (?P.+))\n" +success_codes = [0] + +[plugins.definitions.precedence-formatter] +file_types = ["shell"] +config_files = ["formatter-results.txt"] +exported_config_paths = [ + "formatter-results.txt", +] + +[plugins.definitions.precedence-formatter.drivers.fmt] +driver_type = "formatter" +prepare_script = "mkdir ${linter} && echo type %1 > ${linter}/cat.cmd || echo type %1 > ${linter}/cat.cmd" +script = "cat formatter-results.txt" +output_format = "regex" +output_regex = "((?P.*):(?P-?\\d+):(?P-?\\d+): (?P\\S+) (?P.+))\n" +success_codes = [0] diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/formatter-results.txt b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/formatter-results.txt new file mode 100644 index 000000000..001cfd4a8 --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/formatter-results.txt @@ -0,0 +1 @@ +sample.sh:2:1: WORKSPACE formatter used workspace config diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/linter-results.txt b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/linter-results.txt new file mode 100644 index 000000000..d28b6ed77 --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/linter-results.txt @@ -0,0 +1 @@ +sample.sh:2:1: WORKSPACE linter used workspace config diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/sample.sh b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/sample.sh new file mode 100644 index 000000000..4163036ef --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.in/sample.sh @@ -0,0 +1,2 @@ +#!/bin/sh +echo hi diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.stderr b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.stderr new file mode 100644 index 000000000..eb07d1161 --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.stderr @@ -0,0 +1 @@ +✖ 2 issues diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.stdout b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.stdout new file mode 100644 index 000000000..c0bc23a5d --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.stdout @@ -0,0 +1,7 @@ + + ISSUES: 2[..] + +sample.sh:2:0 + 2:0 medium formatter used workspace config precedence-formatter:WORKSPACE[..] + 2:0 medium linter used workspace config precedence-linter:WORKSPACE[..] +[..] diff --git a/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.toml b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.toml new file mode 100644 index 000000000..ca7a5c984 --- /dev/null +++ b/qlty-cli/tests/cmd/check/exported_config_workspace_precedence.toml @@ -0,0 +1,3 @@ +bin.name = "qlty" +args = ["check", "--all", "--no-cache"] +status.code = 1