Open aminya opened 1 year ago
Similar with PHP's PHP-CS-Fixer
In my Symfony project (PHP) I built a little wrapper script to overcome this limitation. It's not nice, but it works for now.
I created the file bin/dprint-stdout-wrapper.sh
#!/usr/bin/env bash
# Currently dprint doesn't provide a way to use commands which modify the
# file directly instead of printing the result to stdout
# see https://github.com/dprint/dprint-plugin-exec/issues/26
#
# Therefore we use this little wrapper script which we can call like this
# bin/dprint-stdout-wrapper.sh vendor/bin/php-cs-fixer fix {{file_path}}
#
# The last argument MUST BE the file path as it first calls the command and
# then uses cat to print that path to a file
# https://unix.stackexchange.com/a/612122
FILE_PATH="${!#}" # see man bash, search for "indirect expansion"
# this "pops" the file path from the argument list which we use via $@
set -- "${@:1:$#-1}"
$@ $FILE_PATH >&2 && cat $FILE_PATH
Now I can use the following config in my dprint.json to run PHP-CS-Fixer and Twig-CS-Fixer:
{
// ...
"markup": {
"associations": [
"!**/*.twig"
]
},
"exec": {
"cwd": "${configDir}",
"commands": [
{
"command": "bin/dprint-stdout-wrapper.sh vendor/bin/php-cs-fixer fix {{file_path}}",
"exts": ["php"]
},
{
"command": "bin/dprint-stdout-wrapper.sh vendor/bin/twig-cs-fixer lint --report null --fix {{file_path}}",
"exts": ["twig"]
}
]
},
"excludes": [
"**/node_modules",
"**/*-lock.json",
"assets/vendor/*",
"assets/**/controllers.json",
"composer.json",
"public/assets/*",
"package.json",
"README.md"
],
"plugins": [
// ...
"https://plugins.dprint.dev/exec-0.5.0.json@8d9972eee71fa1590e04873540421f3eda7674d0f1aae3d7c788615e7b7413d0"
]
}
Edit: added twig-cs-fixer command
Edit 2: >&2
was required to pipe stdout to stderr
@adaliszk I just updated my comment. See "Edit 2"
I just noticed one downside: When running dprint fmt
the fix is still applied to the file.
So we also would need dprint-plugin-exec to provide us with the current mode, maybe via a command template {{mode}}
.
Then in our script we can decide if we want to use fix
or check
(or --dry-run
, etc)
Yeah, I was thinking about making a wrapper like that, but the issue is that there would be two separate reads and writes for the same file. At the moment, I am exploring the option of changing the PHP-CS-Fixer and, in extension, Laravel Pint to have a print mode instead.
Luckily, the stdin option is already there, so it's easy to argue for a stdout mode to let any external tool handle the filesystem.
Yes, that's really not very elegant, just a workaround. Also I now used a similar wrapper for Twig-CS-Fixer and then running prettier with the Plugin for Tailwind automatic class sorting on the file (https://github.com/ttskch/prettier-plugin-tailwindcss-anywhere)
After also adding https://daisyui.com/ it was writing log output from daisyUI to my twig files. I now set an env var in my script which disables logging from the tailwind.config.js – also not very nice.
Okay, my colleague had issues in VS Code because the command wrote to the file multiple times. I now updated my wrapper script to use a temporary file instead.
bin/dprint-stdout-wrapper.sh
#!/usr/bin/env bash
# Currently dprint doesn't provide a way to use commands which modify the
# file directly instead of printing the result to stdout
# see https://github.com/dprint/dprint-plugin-exec/issues/26
#
# Therefore we use this little wrapper script which we can call like this
# bin/dprint-stdout-wrapper.sh vendor/bin/php-cs-fixer fix
#
# dprint passes the input via stdin which we write to a temporary file.
# Then we apply the formatting to the temporary file and write the result
# to stdout. dprint then writes the output back to the input file.
TEMP_FILE=$(mktemp)
# read stdin to temporary file
cat - > $TEMP_FILE
function cleanup {
rm "$TEMP_FILE"
}
# make sure the temporary file is removed on exit, even in error cases
trap cleanup EXIT
$@ $TEMP_FILE >&2 && cat $TEMP_FILE
To make it work for twig files in VS Code my workaround is even worse, but works now:
bin/fix-twig.sh
#!/usr/bin/env bash
# Currently dprint doesn't provide a way to use commands which modify the
# file directly instead of printing the result to stdout
# see https://github.com/dprint/dprint-plugin-exec/issues/26
#
# Therefore we use this little wrapper script which we can call like this
# bin/fix-twig.sh {{file_path}}
#
# dprint passes the input via stdin which we write to a temporary file.
# Then we apply the formatting to the temporary file and write the result
# to stdout. dprint then writes the output back to the input file.
# We use the file path for prettier to determine the correct parser
# https://prettier.io/docs/en/options.html#file-path
FILE_PATH="$1"
TEMP_FILE=$(mktemp)
# read stdin to temporary file
cat - > $TEMP_FILE
function cleanup {
rm -f "$TEMP_FILE"
}
# make sure the temporary file is removed on exit, even in error cases
trap cleanup EXIT
CURRENT_SCRIPT_DIR_NAME=$(dirname "${BASH_SOURCE[0]}")
vendor/bin/twig-cs-fixer lint --report null --fix $TEMP_FILE
cat $TEMP_FILE | \
DISABLE_DAISY_LOGS=1 node_modules/.bin/prettier \
--config "$CURRENT_SCRIPT_DIR_NAME/.prettierrc" \
--stdin-filepath "$FILE_PATH"
The .prettierrc file is taken from https://github.com/ttskch/prettier-plugin-tailwindcss-anywhere?tab=readme-ov-file#usage
My dprint.json looks like:
{
// ...
"markup": {
"associations": [
"!**/*.twig"
]
},
"exec": {
"cwd": "${configDir}",
"commands": [
{
"command": "bin/dprint-stdout-wrapper.sh vendor/bin/php-cs-fixer fix",
"exts": ["php"]
},
{
"command": "bin/fix-twig.sh {{file_path}}",
"exts": ["twig"]
}
]
},
"excludes": [
"**/node_modules",
"**/*-lock.json",
"assets/vendor/*",
"assets/**/controllers.json",
"composer.json",
"public/assets/*",
"package.json"
],
"plugins": [
// ...
"https://plugins.dprint.dev/exec-0.5.0.json@8d9972eee71fa1590e04873540421f3eda7674d0f1aae3d7c788615e7b7413d0"
]
}
Edit: simplified bin/fix-twig.sh
as https://github.com/ttskch/prettier-plugin-tailwindcss-anywhere/issues/2 got fixed.
Some formatter tools like
black
from Python have no option for printing to the stdout. There should be an option so that those tools can directly write to the file without warnings.