aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml35
-rw-r--r--.github/workflows/formatters.yml23
-rw-r--r--.github/workflows/lint.yml16
-rw-r--r--.gitignore3
-rw-r--r--Makefile24
-rw-r--r--README.md27
-rw-r--r--apheleia.el7
-rwxr-xr-xscripts/check-line-length.bash2
-rwxr-xr-xscripts/docker-pid1.bash23
-rwxr-xr-xscripts/docker-run.bash19
-rwxr-xr-xscripts/docker.bash9
-rw-r--r--test/formatters/Dockerfile13
-rwxr-xr-xtest/formatters/apheleia-ft.el296
-rwxr-xr-xtest/formatters/build-image.bash22
-rwxr-xr-xtest/formatters/install-common.bash41
-rwxr-xr-xtest/formatters/install-formatters.bash44
-rw-r--r--test/formatters/installers/black.bash1
-rw-r--r--test/formatters/installers/brittany.bash11
-rw-r--r--test/formatters/installers/clang-format.bash1
-rw-r--r--test/formatters/installers/fish-indent.bash1
-rw-r--r--test/formatters/installers/gofmt.bash1
-rw-r--r--test/formatters/installers/google-java-format.bash12
-rw-r--r--test/formatters/installers/isort.bash1
-rw-r--r--test/formatters/installers/latexindent.bash1
-rw-r--r--test/formatters/installers/mix-format.bash1
-rw-r--r--test/formatters/installers/ocamlformat.bash5
-rw-r--r--test/formatters/installers/prettier.bash1
-rw-r--r--test/formatters/installers/rustfmt.bash5
-rw-r--r--test/formatters/installers/terraform.bash5
-rwxr-xr-xtest/formatters/run-func.bash8
-rw-r--r--test/formatters/samplecode/black/in.py4
-rw-r--r--test/formatters/samplecode/black/out.py3
-rw-r--r--test/formatters/samplecode/brittany/in.hs10
-rw-r--r--test/formatters/samplecode/brittany/out.hs9
-rw-r--r--test/formatters/samplecode/clang-format/in.c2
-rw-r--r--test/formatters/samplecode/clang-format/out.c6
-rw-r--r--test/formatters/samplecode/fish-indent/in.fish10
-rw-r--r--test/formatters/samplecode/fish-indent/out.fish10
-rw-r--r--test/formatters/samplecode/gofmt/in.go11
-rw-r--r--test/formatters/samplecode/gofmt/out.go9
-rw-r--r--test/formatters/samplecode/google-java-format/in.java16
-rw-r--r--test/formatters/samplecode/google-java-format/out.java7
-rw-r--r--test/formatters/samplecode/isort/in.py20
-rw-r--r--test/formatters/samplecode/isort/out.py11
-rw-r--r--test/formatters/samplecode/latexindent/in.tex9
-rw-r--r--test/formatters/samplecode/latexindent/out.tex9
-rw-r--r--test/formatters/samplecode/mix-format/in.erl7
-rw-r--r--test/formatters/samplecode/mix-format/out.erl6
-rw-r--r--test/formatters/samplecode/ocamlformat/in.ml9
-rw-r--r--test/formatters/samplecode/ocamlformat/out.ml3
-rw-r--r--test/formatters/samplecode/prettier/in.css13
-rw-r--r--test/formatters/samplecode/prettier/in.html1
-rw-r--r--test/formatters/samplecode/prettier/in.js4
-rw-r--r--test/formatters/samplecode/prettier/in.json1
-rw-r--r--test/formatters/samplecode/prettier/in.scss1
-rw-r--r--test/formatters/samplecode/prettier/in.ts1
-rw-r--r--test/formatters/samplecode/prettier/in.yml13
-rw-r--r--test/formatters/samplecode/prettier/out.css6
-rw-r--r--test/formatters/samplecode/prettier/out.html5
-rw-r--r--test/formatters/samplecode/prettier/out.js10
-rw-r--r--test/formatters/samplecode/prettier/out.json19
-rw-r--r--test/formatters/samplecode/prettier/out.scss9
-rw-r--r--test/formatters/samplecode/prettier/out.ts6
-rw-r--r--test/formatters/samplecode/prettier/out.yml10
-rw-r--r--test/formatters/samplecode/rustfmt/in.rs12
-rw-r--r--test/formatters/samplecode/rustfmt/out.rs9
-rw-r--r--test/formatters/samplecode/terraform/in.tf6
-rw-r--r--test/formatters/samplecode/terraform/out.tf6
68 files changed, 920 insertions, 41 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index fdc3930..0000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-version: 2
-shared: &shared
- machine:
- image: ubuntu-1604:201903-01
- steps:
- - checkout
- # This command will pick up $VERSION from the environment.
- - run: >-
- make docker
- CMD="make -k compile checkdoc longlines"
-jobs:
- emacs-25:
- <<: *shared
- environment:
- VERSION: "25"
- emacs-26:
- <<: *shared
- environment:
- VERSION: "26"
- emacs-27:
- <<: *shared
- environment:
- VERSION: "27"
- emacs-git:
- <<: *shared
- environment:
- VERSION: "master"
-workflows:
- version: 2
- ci:
- jobs:
- - emacs-25
- - emacs-26
- - emacs-27
- - emacs-git
diff --git a/.github/workflows/formatters.yml b/.github/workflows/formatters.yml
new file mode 100644
index 0000000..b114eea
--- /dev/null
+++ b/.github/workflows/formatters.yml
@@ -0,0 +1,23 @@
+name: Changed formatters
+on: [pull_request]
+jobs:
+ formatters:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout pull request
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
+ - name: Fetch master
+ run: |
+ git fetch
+ - name: Test changed formatters
+ run: |
+ set -euo pipefail
+
+ mkdir -p .tmp
+ make docker CMD="make fmt-changed > .tmp/changed"
+ export FORMATTERS="$(< .tmp/changed)"
+ if [[ -n "${FORMATTERS}" ]]; then
+ make fmt-build fmt-docker CMD="make fmt-test"
+ fi
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..34fde49
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,16 @@
+name: Lint
+on: [push]
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ emacs_version: [25, 26, 27, "master"]
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Run linters
+ env:
+ VERSION: ${{ matrix.emacs_version }}
+ run: >-
+ make docker CMD="make lint"
diff --git a/.gitignore b/.gitignore
index c531d98..9a66d3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
*.elc
+.log
+.tmp
+auto
diff --git a/Makefile b/Makefile
index f80d759..1f3ccd2 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,8 @@ CMD ?=
EMACS ?= emacs
+TAG ?= latest
+
# The order is important for compilation.
for_compile := *.el
for_checkdoc := *.el
@@ -17,7 +19,7 @@ help: ## Show this message
column -t -s'|' >&2
.PHONY: lint
-lint: compile checkdoc longlines ## Build project and run all linters
+lint: compile checkdoc longlines fmt-lint ## Build project and run all linters
.PHONY: compile
compile: ## Check for byte-compiler errors
@@ -52,3 +54,23 @@ clean: ## Remove build artifacts
.PHONY: docker
docker: ## Start a Docker shell; e.g. make docker VERSION=25.3
@scripts/docker.bash "$(VERSION)" "$(CMD)"
+
+.PHONY: fmt-build # env vars: FORMATTERS, TAG
+fmt-build: ## Build a Docker image with formatters installed
+ @test/formatters/build-image.bash
+
+.PHONY: fmt-docker # env var: TAG
+fmt-docker: ## Start a Docker shell for testing formatters
+ @scripts/docker-run.bash -e FORMATTERS "apheleia-formatters:$(TAG)" "$(CMD)"
+
+.PHONY: fmt-lint
+fmt-lint: ## Do basic linting for formatter configuration
+ @test/formatters/run-func.bash apheleia-ft-lint
+
+.PHONY: fmt-check
+fmt-changed: ## Get list of changed formatters on this PR
+ @test/formatters/run-func.bash apheleia-ft-changed
+
+.PHONY: fmt-test # env var: FORMATTERS
+fmt-test: ## Actually run formatter tests
+ @test/formatters/run-func.bash apheleia-ft-test
diff --git a/README.md b/README.md
index 705d722..f5fa043 100644
--- a/README.md
+++ b/README.md
@@ -218,7 +218,32 @@ Apheleia exposes some hooks for advanced customization:
## Contributing
Please see [the contributor guide for my
-projects](https://github.com/raxod502/contributor-guide).
+projects](https://github.com/raxod502/contributor-guide) for general
+information, and the following sections for Apheleia-specific details.
+
+### Adding a formatter
+
+I have done my best to make it straightforward to add a formatter. You
+just follow these steps:
+
+1. Install your formatter on your machine so you can test.
+2. Create an entry in `apheleia-formatters` with how to run it. (See
+ the docstring of this variable for explanation about the available
+ keywords.)
+3. Add entries for the relevant major modes in `apheleia-mode-alist`.
+4. See if it works for you!
+5. Add a file at `test/formatters/installers/yourformatter.bash` which
+ explains how to install the formatter on Ubuntu. This will be used
+ by CI.
+6. Test with `make fmt-build FORMATTERS=yourformatter` to do the
+ installation, then `make fmt-docker` to start a shell with the
+ formatter available. Verify it runs in this environment.
+7. Add an example input (pre-formatting) and output (post-formatting)
+ file at `test/formatters/samplecode/yourformatter/in.whatever` and
+ `test/formatters/samplecode/yourformatter/out.whatever`.
+8. Verify that the tests are passing, using `make fmt-test
+ FORMATTERS=yourformatter` from inside the `fmt-docker` shell.
+9. Submit a pull request, CI should now be passing!
## Acknowledgements
diff --git a/apheleia.el b/apheleia.el
index 84ae1b4..2d40f47 100644
--- a/apheleia.el
+++ b/apheleia.el
@@ -700,10 +700,11 @@ formatter being run, for diagnostic purposes."
(fish-indent . ("fish_indent"))
(gofmt . ("gofmt"))
(google-java-format . ("google-java-format" "-"))
- (isort . ("isort" "--stdout" "-"))
- (latexindent . ("latexindent"))
+ (isort . ("isort" "-"))
+ (latexindent . ("latexindent" "--logfile=/dev/null"))
(mix-format . ("mix" "format" "-"))
- (ocamlformat . ("ocamlformat" "-" "--name" filepath))
+ (ocamlformat . ("ocamlformat" "-" "--name" filepath
+ "--enable-outside-detected-project"))
(prettier . (npx "prettier" "--stdin-filepath" filepath))
(rustfmt . ("rustfmt" "--quiet" "--emit" "stdout"))
(terraform . ("terraform" "fmt" "-")))
diff --git a/scripts/check-line-length.bash b/scripts/check-line-length.bash
index c6a040d..3dd4cd1 100755
--- a/scripts/check-line-length.bash
+++ b/scripts/check-line-length.bash
@@ -6,6 +6,8 @@ set -o pipefail
find=(
find .
-name .git -prune -o
+ -name .log -prune -o
+ -path ./test/formatters -prune -o
-name "*.elc" -o
-type f -print
)
diff --git a/scripts/docker-pid1.bash b/scripts/docker-pid1.bash
new file mode 100755
index 0000000..cee0dff
--- /dev/null
+++ b/scripts/docker-pid1.bash
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+cat <<"EOF" > /etc/sudoers.d/apheleia
+%sudo ALL=(ALL:ALL) NOPASSWD: ALL
+EOF
+
+groupadd -g "$(stat -c %g "$PWD")" -o -p '!' -r apheleia
+useradd -u "$(stat -c %u "$PWD")" -g "$(stat -c %g "$PWD")" \
+ -o -p '!' -m -N -l -s /usr/bin/bash -G sudo apheleia
+
+runuser -u apheleia touch /home/apheleia/.sudo_as_admin_successful
+
+if (( "$#" == 0 )) || [[ -z "$1" ]]; then
+ set -- bash
+fi
+
+if (( "$#" == 1 )) && [[ "$1" == *" "* ]]; then
+ set -- bash -c "$1"
+fi
+
+exec runuser -u apheleia -- "$@"
diff --git a/scripts/docker-run.bash b/scripts/docker-run.bash
new file mode 100755
index 0000000..e7de1f4
--- /dev/null
+++ b/scripts/docker-run.bash
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+repo="$(git rev-parse --show-toplevel)"
+
+docker=(docker)
+if [[ "$OSTYPE" != darwin* ]] && [[ "$EUID" != 0 ]]; then
+ docker=(sudo -E "${docker[@]}")
+fi
+
+it=()
+
+if [[ -t 0 ]]; then
+ it+=(-it)
+fi
+
+exec "${docker[@]}" run "${it[@]}" --rm -v "${repo}:/src" \
+ --entrypoint=/src/scripts/docker-pid1.bash "$@"
diff --git a/scripts/docker.bash b/scripts/docker.bash
index d846122..812cded 100755
--- a/scripts/docker.bash
+++ b/scripts/docker.bash
@@ -22,4 +22,11 @@ docker build . -t "apheleia:$tag" \
--build-arg "UID=$UID" \
--build-arg "VERSION=$tag"
-docker run -it --rm -v "$PWD:/home/docker/src" "apheleia:$tag" "${args[@]}"
+it=()
+
+if [[ -t 0 ]]; then
+ it+=(-it)
+fi
+
+docker run "${it[@]}" --rm -v "$PWD:/home/docker/src" \
+ "apheleia:$tag" "${args[@]}"
diff --git a/test/formatters/Dockerfile b/test/formatters/Dockerfile
new file mode 100644
index 0000000..4807552
--- /dev/null
+++ b/test/formatters/Dockerfile
@@ -0,0 +1,13 @@
+# Ubuntu 20.04 LTS supported until April 2025
+FROM ubuntu:20.04
+
+WORKDIR /build
+COPY install-common.bash /build/
+RUN ./install-common.bash
+
+ARG FORMATTERS
+COPY install-formatters.bash /build/
+COPY installers /build/installers/
+RUN ./install-formatters.bash
+
+WORKDIR /src
diff --git a/test/formatters/apheleia-ft.el b/test/formatters/apheleia-ft.el
new file mode 100755
index 0000000..9e2a288
--- /dev/null
+++ b/test/formatters/apheleia-ft.el
@@ -0,0 +1,296 @@
+;; -*- lexical-binding: t -*-
+
+;; `apheleia-ft' - short for `apheleia-formatter-tests'. The functions
+;; in here are not part of the public interface of Apheleia and
+;; breaking changes may occur at any time.
+
+(require 'apheleia)
+
+(require 'cl-lib)
+(require 'map)
+
+(defvar apheleia-ft--test-dir
+ (file-name-directory
+ (or load-file-name buffer-file-name))
+ "Directory containing this module.")
+
+(defun apheleia-ft--get-formatters (&optional all)
+ "Return list of strings naming the formatters to run.
+This is determined by the environment variable FORMATTERS,
+defaulting to all known formatters if the environment variable is
+not set.
+
+If ALL is non-nil, unconditionally return all formatters."
+ (let ((env-var (or (getenv "FORMATTERS") "")))
+ (cond
+ ((or all (string-empty-p env-var))
+ (mapcar #'symbol-name (map-keys apheleia-formatters)))
+ (t
+ (split-string env-var "[ ,]+")))))
+
+(defun apheleia-ft--get-formatters-from-ref (ref)
+ "Check out given Git REF and return `apheleia-formatters' from there.
+Return an Elisp data structure, same as the `apheleia-formatters'
+already in memory on the current branch."
+ (let ((old-apheleia (make-temp-file "apheleia-" nil ".el"))
+ (stderr-file (make-temp-file "apheleia-ft-stderr-")))
+ (with-temp-file old-apheleia
+ (let ((exit-status
+ (call-process
+ "git"
+ nil (list (current-buffer) stderr-file) nil
+ "show" (format "%s:apheleia.el" ref))))
+ (unless (zerop exit-status)
+ (with-temp-buffer
+ (insert-file-contents stderr-file)
+ (princ (buffer-string)))
+ (error "Failed to 'git show %s:apheleia.el', got exit status %S"
+ ref exit-status))))
+ (with-temp-buffer
+ (call-process
+ (if invocation-directory
+ (expand-file-name invocation-name invocation-directory)
+ invocation-name)
+ nil (current-buffer) nil
+ "--batch" "-l" old-apheleia "--eval" "(prin1 apheleia-formatters)")
+ (goto-char (point-min))
+ (read (current-buffer)))))
+
+(defun apheleia-ft--get-formatters-for-pull-request ()
+ "Return list of formatter string names that were touched in this PR.
+This means their commands in `apheleia-formatters' are different
+from how they appear on master, or they were added relative to
+master."
+ (let ((old-formatters (apheleia-ft--get-formatters-from-ref "origin/master"))
+ (new-formatters apheleia-formatters)
+ (touched-formatters nil))
+ (map-do
+ (lambda (formatter command)
+ (unless (equal command (alist-get formatter old-formatters))
+ (push (symbol-name formatter) touched-formatters)))
+ new-formatters)
+ touched-formatters))
+
+(defun apheleia-ft-changed ()
+ "Print to stdout a comma-delimited list of formatters changed in this PR."
+ (princ (concat
+ (string-join
+ (apheleia-ft--get-formatters-for-pull-request) ",")
+ "\n")))
+
+(defun apheleia-ft--read-file (filename)
+ "Return the contents of FILENAME as a string."
+ (with-temp-buffer
+ (insert-file-contents filename)
+ (buffer-string)))
+
+(defun apheleia-ft--write-temp-file (contents extension)
+ "Write file CONTENTS string to temporary file with given EXTENSION.
+Return the filename."
+ (unless (or (string-prefix-p "." extension) (string-empty-p extension))
+ (setq extension (concat "." extension)))
+ (make-temp-file "apheleia-ft-file-" nil extension contents))
+
+(defun apheleia-ft--input-files (formatter)
+ "For given FORMATTER, return list of input files used in test cases.
+These are absolute filepaths beginning with \"in.\"."
+ (directory-files
+ (apheleia-ft--path-join
+ apheleia-ft--test-dir
+ "samplecode" formatter)
+ 'full
+ "^in\\."))
+
+(defun apheleia-ft--path-join (component &rest components)
+ "Join COMPONENT and COMPONENTS together, left to right.
+Return an absolute path."
+ (let ((result component))
+ (while (setq component (pop components))
+ (setq result (expand-file-name component result)))
+ result))
+
+(defun apheleia-ft--print-diff (lhs-name lhs rhs-name rhs)
+ "Print a Git-style line-wise diff between two strings.
+LHS-NAME is a human-readable name for the LHS string, same for
+RHS-NAME and RHS."
+ (with-temp-buffer
+ (let* ((lhs-file (apheleia-ft--write-temp-file lhs lhs-name))
+ (rhs-file (apheleia-ft--write-temp-file rhs rhs-name))
+ (stderr-file (make-temp-file "apheleia-ft-stderr-"))
+ (exit-status
+ (call-process
+ "git" nil (list (current-buffer) stderr-file) nil "diff"
+ "--no-index" lhs-file rhs-file)))
+ (unless (memq exit-status '(0 1))
+ (with-temp-buffer
+ (insert-file-contents stderr-file)
+ (princ (buffer-string)))
+ (error "Git diff exited with status %S" exit-status))
+ (princ (buffer-string)))))
+
+(defun apheleia-ft-lint ()
+ "Lint general file structure for formatter tests.
+This validates that necessary support files exist for every
+formatter defined in apheleia.el, and that they are well-formed,
+and no extraneous ones exist.
+
+This operation is intended to be fast and simple, and does not
+involve running any formatters."
+ (interactive)
+ (let ((formatters (mapcar #'symbol-name (map-keys apheleia-formatters)))
+ (installers
+ (mapcar
+ (lambda (filename)
+ (string-remove-suffix ".bash" filename))
+ (directory-files
+ (apheleia-ft--path-join
+ apheleia-ft--test-dir "installers")
+ nil "\\.bash$")))
+ (samplecode-dirs
+ (directory-files
+ (apheleia-ft--path-join
+ apheleia-ft--test-dir "samplecode")
+ nil "^[^.]")))
+ (dolist (formatter formatters)
+ (unless (member formatter installers)
+ (error "Missing installer script at installers/%s.bash" formatter)))
+ (dolist (installer installers)
+ (unless (member installer formatters)
+ (error "Spurious installer script at installers/%s.bash" installer)))
+ (dolist (formatter formatters)
+ (unless (member formatter samplecode-dirs)
+ (error "Missing sample code dir at samplecode/%s" formatter))
+ (let ((in-files
+ (directory-files
+ (apheleia-ft--path-join
+ apheleia-ft--test-dir "samplecode" formatter)
+ nil "^in"))
+ (out-files nil)
+ (all-files
+ (directory-files
+ (apheleia-ft--path-join
+ apheleia-ft--test-dir "samplecode" formatter)
+ nil "^[^.]")))
+ (unless in-files
+ (error "Empty sample code dir at samplecode/%s" formatter))
+ (dolist (in-file in-files)
+ (let ((out-file (replace-regexp-in-string "^in" "out" in-file)))
+ (unless (file-exists-p
+ (apheleia-ft--path-join
+ apheleia-ft--test-dir "samplecode" formatter out-file))
+ (error "Input file %s is has no corresponding output file %s"
+ in-file out-file))
+ (push out-file out-files)))
+ (dolist (file all-files)
+ (unless (or (member file in-files)
+ (member file out-files))
+ (error "Spurious sample code file at samplecode/%s/%s"
+ formatter file)))))
+ (dolist (samplecode-dir samplecode-dirs)
+ (unless (member samplecode-dir formatters)
+ (error
+ "Spurious sample code directory at samplecode/%s"
+ samplecode-dir))))
+ (message "[format-test] linting passed"))
+
+(defun apheleia-ft-test (&rest formatters)
+ "Run tests for provided FORMATTERS.
+Interactively, select a single formatter to test using
+`completing-read'. If FORMATTERS is not provided (or,
+interactively, with prefix argument), fall back to the FORMATTERS
+environment variable, defaulting to all formatters."
+ (interactive
+ (unless (or current-prefix-arg noninteractive)
+ (list (completing-read "Formatter: " (apheleia-ft--get-formatters)))))
+ (dolist (formatter (or formatters (apheleia-ft--get-formatters)))
+ (dolist (in-file (apheleia-ft--input-files formatter))
+ (let ((extension (file-name-extension in-file))
+ (in-text (apheleia-ft--read-file in-file))
+ (in-temp-real-file nil)
+ (in-temp-file nil)
+ (out-temp-file nil)
+ (command (alist-get (intern formatter) apheleia-formatters))
+ (syms nil)
+ (stdout-buffer nil)
+ (stderr-file (make-temp-file "apheleia-ft-stderr-"))
+ (default-directory temporary-file-directory)
+ (exit-status nil)
+ (out-file (replace-regexp-in-string
+ "/in\\([^/]+\\)" "/out\\1" in-file 'fixedcase)))
+ (mapc
+ (lambda (arg)
+ (when (memq arg '(file filepath input output inplace))
+ (cl-pushnew arg syms)))
+ command)
+ (when (or (memq 'file syms) (memq 'filepath syms))
+ (setq in-temp-real-file (apheleia-ft--write-temp-file
+ in-text extension)))
+ (when (or (memq 'input syms) (memq 'inplace syms))
+ (setq in-temp-file (apheleia-ft--write-temp-file
+ in-text extension))
+ (when (memq 'inplace syms)
+ (setq out-temp-file in-temp-file)))
+ (when (memq 'output syms)
+ (setq out-temp-file (apheleia-ft--write-temp-file
+ "" extension)))
+ (setq command
+ (mapcar
+ (lambda (arg)
+ (pcase arg
+ ((or `file `filepath)
+ in-temp-real-file)
+ ((or `input `inplace)
+ in-temp-file)
+ (`output
+ out-temp-file)
+ (_ arg)))
+ command))
+ (setq command (delq 'npx command))
+ (setq stdout-buffer (get-buffer-create
+ (format "*apheleia-ft-stdout-%S" formatter)))
+ (with-current-buffer stdout-buffer
+ (erase-buffer))
+ (setq exit-status
+ (apply
+ #'call-process
+ (car command)
+ (unless (or (memq 'file syms)
+ (memq 'input syms)
+ (memq 'inplace syms))
+ in-file)
+ (list stdout-buffer stderr-file)
+ nil
+ (cdr command)))
+ ;; Verify that formatter succeeded.
+ (unless (zerop exit-status)
+ (with-temp-buffer
+ (insert-file-contents stderr-file)
+ (princ (buffer-string)))
+ (error
+ "Formatter %s exited with status %S" formatter exit-status))
+ ;; Verify that formatter has not touched original file.
+ (when in-temp-real-file
+ (let ((in-text-now (apheleia-ft--read-file in-temp-real-file)))
+ (unless (string= in-text in-text-now)
+ (apheleia-ft--print-diff
+ "original" in-text
+ "updated" in-text-now)
+ (error "Formatter %s modified original file in place" formatter))))
+ ;; Verify that formatter formatted correctly.
+ (let ((out-text
+ (if (or (memq 'output syms) (memq 'inplace syms))
+ (apheleia-ft--read-file out-temp-file)
+ (with-current-buffer stdout-buffer
+ (buffer-string))))
+ (expected-out-text
+ (apheleia-ft--read-file out-file)))
+ (unless (string= out-text expected-out-text)
+ (apheleia-ft--print-diff
+ "expected" expected-out-text
+ "actual" out-text)
+ (error "Formatter %s did not format as expected" formatter)))
+ (princ (format
+ "[format-test] success: formatter %s (file %s)\n"
+ formatter (file-name-nondirectory in-file)))))))
+
+(provide 'apheleia-ft)
diff --git a/test/formatters/build-image.bash b/test/formatters/build-image.bash
new file mode 100755
index 0000000..a118d12
--- /dev/null
+++ b/test/formatters/build-image.bash
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+echo >&2 "build-image.bash: tagging apheleia-formatters:${TAG:-latest}"
+
+if [[ -n "${FORMATTERS:-}" ]]; then
+ echo "build-image.bash: will install these formatters: ${FORMATTERS}"
+else
+ echo "build-image.bash: will install all formatters by default"
+fi
+
+cd "$(dirname "$0")"
+
+docker=(docker)
+if [[ "$OSTYPE" != darwin* ]] && [[ "$EUID" != 0 ]]; then
+ docker=(sudo -E "${docker[@]}")
+fi
+
+exec "${docker[@]}" build . \
+ -t "apheleia-formatters:${TAG:-latest}" \
+ --build-arg "FORMATTERS=${FORMATTERS:-}"
diff --git a/test/formatters/install-common.bash b/test/formatters/install-common.bash
new file mode 100755
index 0000000..2e812a2
--- /dev/null
+++ b/test/formatters/install-common.bash
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+
+set -euxo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get update
+apt-get install -y curl gnupg lsb-release
+
+curl -fsSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add -
+
+ubuntu_name="$(lsb_release -cs)"
+node_repo="$(curl -fsSL https://deb.nodesource.com/setup_current.x | grep NODEREPO= | grep -Eo 'node_[0-9]+\.x' | head -n1)"
+
+tee -a /etc/apt/sources.list.d/nodejs.list >/dev/null <<EOF
+deb [arch=amd64] https://deb.nodesource.com/${node_repo} ${ubuntu_name} main
+EOF
+
+apt-get update
+
+packages="
+
+bsdmainutils
+emacs-nox
+git
+jq
+make
+nodejs
+sudo
+unzip
+wget
+sudo
+unzip
+wget
+
+"
+
+apt-get install -y ${packages}
+
+rm /etc/emacs/site-start.d/*
+
+rm -rf /var/lib/apt/lists/*
diff --git a/test/formatters/install-formatters.bash b/test/formatters/install-formatters.bash
new file mode 100755
index 0000000..b235566
--- /dev/null
+++ b/test/formatters/install-formatters.bash
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+if [[ -n "${FORMATTERS:-}" ]]; then
+ IFS=' ,' read -ra FORMATTERS <<< "${FORMATTERS}"
+else
+ readarray -t FORMATTERS < <(ls installers | grep '\.bash$' | sed 's/\.bash$//')
+fi
+
+if (( "${#FORMATTERS[@]}" > 0 )); then
+ echo >&2 "Installing the following ${#FORMATTERS[@]} formatter(s):"
+ for f in "${FORMATTERS[@]}"; do
+ echo >&2 " * ${f}"
+ done
+else
+ echo >&2 "Installing NO formatters"
+fi
+
+echo >&2 "-- Setting up --"
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get update
+
+orig_wd="${PWD}"
+
+mkdir /tmp/apheleia-work
+cd /tmp/apheleia-work
+
+latest_release() {
+ curl -fsSL "https://api.github.com/repos/$1/releases/latest" | jq -r .tag_name
+}
+
+echo >&2 "-- Will install ${#FORMATTERS[@]} formatter(s) --"
+
+for f in "${FORMATTERS[@]}"; do
+ echo >&2 "-- Installing formatter ${f} --"
+ . "${orig_wd}/installers/${f}.bash"
+done
+
+echo >&2 "-- Cleaning up --"
+
+rm -rf /var/lib/apt/lists/*
+rm -rf /tmp/apheleia-work
diff --git a/test/formatters/installers/black.bash b/test/formatters/installers/black.bash
new file mode 100644
index 0000000..b1b5b34
--- /dev/null
+++ b/test/formatters/installers/black.bash
@@ -0,0 +1 @@
+apt-get install -y black
diff --git a/test/formatters/installers/brittany.bash b/test/formatters/installers/brittany.bash
new file mode 100644
index 0000000..118870b
--- /dev/null
+++ b/test/formatters/installers/brittany.bash
@@ -0,0 +1,11 @@
+# PPA recommended at https://www.haskell.org/cabal/download.html
+apt-key adv --keyserver keyserver.ubuntu.com --recv-keys FF3AEACEF6F88286
+echo "deb [arch=amd64] http://ppa.launchpad.net/hvr/ghc/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/brittany.list
+
+apt-get update
+apt-get install -y cabal-install-3.4 ghc
+ln -s /opt/cabal/bin/cabal /usr/local/bin/
+
+cabal v2-update
+cabal v2-install brittany
+cp -L "$HOME/.cabal/bin/brittany" /usr/local/bin/
diff --git a/test/formatters/installers/clang-format.bash b/test/formatters/installers/clang-format.bash
new file mode 100644
index 0000000..49f65c2
--- /dev/null
+++ b/test/formatters/installers/clang-format.bash
@@ -0,0 +1 @@
+apt-get install -y clang-format
diff --git a/test/formatters/installers/fish-indent.bash b/test/formatters/installers/fish-indent.bash
new file mode 100644
index 0000000..0dd768e
--- /dev/null
+++ b/test/formatters/installers/fish-indent.bash
@@ -0,0 +1 @@
+apt-get install -y fish
diff --git a/test/formatters/installers/gofmt.bash b/test/formatters/installers/gofmt.bash
new file mode 100644
index 0000000..6e54ccd
--- /dev/null
+++ b/test/formatters/installers/gofmt.bash
@@ -0,0 +1 @@
+apt-get install -y golang-go
diff --git a/test/formatters/installers/google-java-format.bash b/test/formatters/installers/google-java-format.bash
new file mode 100644
index 0000000..7b69a5f
--- /dev/null
+++ b/test/formatters/installers/google-java-format.bash
@@ -0,0 +1,12 @@
+apt-get install -y default-jre
+
+ver="$(latest_release google/google-java-format | sed 's/^v//')"
+
+mkdir /opt/google-java-format
+wget "https://github.com/google/google-java-format/releases/download/v${ver}/google-java-format-${ver}-all-deps.jar" -O /opt/google-java-format/google-java-format.jar
+
+cat <<"EOF" > /usr/local/bin/google-java-format
+#!/bin/sh
+exec java -jar /opt/google-java-format/google-java-format.jar "$@"
+EOF
+chmod +x /usr/local/bin/google-java-format
diff --git a/test/formatters/installers/isort.bash b/test/formatters/installers/isort.bash
new file mode 100644
index 0000000..3e76ce5
--- /dev/null
+++ b/test/formatters/installers/isort.bash
@@ -0,0 +1 @@
+apt-get install -y isort python3-setuptools
diff --git a/test/formatters/installers/latexindent.bash b/test/formatters/installers/latexindent.bash
new file mode 100644
index 0000000..85d9e00
--- /dev/null
+++ b/test/formatters/installers/latexindent.bash
@@ -0,0 +1 @@
+apt-get install -y texlive-extra-utils
diff --git a/test/formatters/installers/mix-format.bash b/test/formatters/installers/mix-format.bash
new file mode 100644
index 0000000..f09283d
--- /dev/null
+++ b/test/formatters/installers/mix-format.bash
@@ -0,0 +1 @@
+apt-get install -y elixir
diff --git a/test/formatters/installers/ocamlformat.bash b/test/formatters/installers/ocamlformat.bash
new file mode 100644
index 0000000..b7ce7f1
--- /dev/null
+++ b/test/formatters/installers/ocamlformat.bash
@@ -0,0 +1,5 @@
+apt-get install -y opam
+
+opam init -n --disable-sandboxing --root /opt/ocamlformat
+opam install ocamlformat -y --root /opt/ocamlformat
+ln -s /opt/ocamlformat/default/bin/ocamlformat /usr/local/bin/
diff --git a/test/formatters/installers/prettier.bash b/test/formatters/installers/prettier.bash
new file mode 100644
index 0000000..09ba518
--- /dev/null
+++ b/test/formatters/installers/prettier.bash
@@ -0,0 +1 @@
+npm install -g prettier
diff --git a/test/formatters/installers/rustfmt.bash b/test/formatters/installers/rustfmt.bash
new file mode 100644
index 0000000..7ce08d8
--- /dev/null
+++ b/test/formatters/installers/rustfmt.bash
@@ -0,0 +1,5 @@
+ver="$(latest_release rust-lang/rustfmt | sed 's/^v//')"
+
+wget "https://github.com/rust-lang/rustfmt/releases/download/v${ver}/rustfmt_linux-x86_64_v${ver}.tar.gz" -O rustfmt.tar.gz
+tar -xf rustfmt.tar.gz
+cp rustfmt*/rustfmt /usr/local/bin/
diff --git a/test/formatters/installers/terraform.bash b/test/formatters/installers/terraform.bash
new file mode 100644
index 0000000..2f4299f
--- /dev/null
+++ b/test/formatters/installers/terraform.bash
@@ -0,0 +1,5 @@
+curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add -
+echo "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/terraform.list
+
+apt-get update
+apt-get install -y terraform
diff --git a/test/formatters/run-func.bash b/test/formatters/run-func.bash
new file mode 100755
index 0000000..22e7489
--- /dev/null
+++ b/test/formatters/run-func.bash
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+cd "$(dirname "$0")"
+repo="$(git rev-parse --show-toplevel)"
+
+exec emacs --batch -L "${repo}" -L . -l apheleia-ft -f "$1"
diff --git a/test/formatters/samplecode/black/in.py b/test/formatters/samplecode/black/in.py
new file mode 100644
index 0000000..21cdcdb
--- /dev/null
+++ b/test/formatters/samplecode/black/in.py
@@ -0,0 +1,4 @@
+def asdjf ( l,
+ a):
+ 3
+ +4
diff --git a/test/formatters/samplecode/black/out.py b/test/formatters/samplecode/black/out.py
new file mode 100644
index 0000000..0a63d13
--- /dev/null
+++ b/test/formatters/samplecode/black/out.py
@@ -0,0 +1,3 @@
+def asdjf(l, a):
+ 3
+ +4
diff --git a/test/formatters/samplecode/brittany/in.hs b/test/formatters/samplecode/brittany/in.hs
new file mode 100644
index 0000000..4734e5a
--- /dev/null
+++ b/test/formatters/samplecode/brittany/in.hs
@@ -0,0 +1,10 @@
+-- | Foo performs foo and sometimes bar.
+
+foo :: Thoroughness
+ -> Int -> Int
+foo t x = if x > 20
+ then case t of
+ Thorough -> x + 50
+ Somewhat -> x + 20
+ NotAtAll -> 0
+ else 10 + 1
diff --git a/test/formatters/samplecode/brittany/out.hs b/test/formatters/samplecode/brittany/out.hs
new file mode 100644
index 0000000..32cfeb9
--- /dev/null
+++ b/test/formatters/samplecode/brittany/out.hs
@@ -0,0 +1,9 @@
+-- | Foo performs foo and sometimes bar.
+
+foo :: Thoroughness -> Int -> Int
+foo t x = if x > 20
+ then case t of
+ Thorough -> x + 50
+ Somewhat -> x + 20
+ NotAtAll -> 0
+ else 10 + 1
diff --git a/test/formatters/samplecode/clang-format/in.c b/test/formatters/samplecode/clang-format/in.c
new file mode 100644
index 0000000..07aa90b
--- /dev/null
+++ b/test/formatters/samplecode/clang-format/in.c
@@ -0,0 +1,2 @@
+// https://www.ioccc.org/2020/burton/prog.c
+int main(int b,char**i){long long n=B,a=I^n,r=(a/b&a)>>4,y=atoi(*++i),_=(((a^n/b)*(y>>T)|y>>S)&r)|(a^r);printf("%.8s\n",(char*)&_);}
diff --git a/test/formatters/samplecode/clang-format/out.c b/test/formatters/samplecode/clang-format/out.c
new file mode 100644
index 0000000..40e9e60
--- /dev/null
+++ b/test/formatters/samplecode/clang-format/out.c
@@ -0,0 +1,6 @@
+// https://www.ioccc.org/2020/burton/prog.c
+int main(int b, char **i) {
+ long long n = B, a = I ^ n, r = (a / b & a) >> 4, y = atoi(*++i),
+ _ = (((a ^ n / b) * (y >> T) | y >> S) & r) | (a ^ r);
+ printf("%.8s\n", (char *)&_);
+}
diff --git a/test/formatters/samplecode/fish-indent/in.fish b/test/formatters/samplecode/fish-indent/in.fish
new file mode 100644
index 0000000..c5e7063
--- /dev/null
+++ b/test/formatters/samplecode/fish-indent/in.fish
@@ -0,0 +1,10 @@
+ switch (uname)
+ case Linux
+ echo Hi Tux!
+ case Darwin
+ echo Hi Hexley!
+ case FreeBSD NetBSD DragonFly
+ echo Hi Beastie!
+ case '*'
+ echo Hi, stranger!
+ end
diff --git a/test/formatters/samplecode/fish-indent/out.fish b/test/formatters/samplecode/fish-indent/out.fish
new file mode 100644
index 0000000..1bc4e84
--- /dev/null
+++ b/test/formatters/samplecode/fish-indent/out.fish
@@ -0,0 +1,10 @@
+switch (uname)
+ case Linux
+ echo Hi Tux!
+ case Darwin
+ echo Hi Hexley!
+ case FreeBSD NetBSD DragonFly
+ echo Hi Beastie!
+ case '*'
+ echo Hi, stranger!
+end
diff --git a/test/formatters/samplecode/gofmt/in.go b/test/formatters/samplecode/gofmt/in.go
new file mode 100644
index 0000000..f726448
--- /dev/null
+++ b/test/formatters/samplecode/gofmt/in.go
@@ -0,0 +1,11 @@
+package asdfasdf
+func
+
+Factorial(x int) int {
+ if x <=
+ 1 {
+ return x
+}
+ return x * Factorial(x - 1,
+)
+ }
diff --git a/test/formatters/samplecode/gofmt/out.go b/test/formatters/samplecode/gofmt/out.go
new file mode 100644
index 0000000..9e9b1f7
--- /dev/null
+++ b/test/formatters/samplecode/gofmt/out.go
@@ -0,0 +1,9 @@
+package asdfasdf
+
+func Factorial(x int) int {
+ if x <=
+ 1 {
+ return x
+ }
+ return x * Factorial(x-1)
+}
diff --git a/test/formatters/samplecode/google-java-format/in.java b/test/formatters/samplecode/google-java-format/in.java
new file mode 100644
index 0000000..877f756
--- /dev/null
+++ b/test/formatters/samplecode/google-java-format/in.java
@@ -0,0 +1,16 @@
+ package
+ main
+ ;
+
+ public
+ class
+Main { public
+ static
+void main
+ ( String arg[]
+){System.out.println
+ (
+ "Hello, world"
+)
+
+;}}
diff --git a/test/formatters/samplecode/google-java-format/out.java b/test/formatters/samplecode/google-java-format/out.java
new file mode 100644
index 0000000..f23c5a8
--- /dev/null
+++ b/test/formatters/samplecode/google-java-format/out.java
@@ -0,0 +1,7 @@
+package main;
+
+public class Main {
+ public static void main(String arg[]) {
+ System.out.println("Hello, world");
+ }
+}
diff --git a/test/formatters/samplecode/isort/in.py b/test/formatters/samplecode/isort/in.py
new file mode 100644
index 0000000..5bd6f7f
--- /dev/null
+++ b/test/formatters/samplecode/isort/in.py
@@ -0,0 +1,20 @@
+from my_lib import Object
+
+import os
+
+from my_lib import Object3
+
+from my_lib import Object2
+
+import sys
+
+from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14
+
+import sys
+
+from __future__ import absolute_import
+
+from third_party import lib3
+
+print("Hey")
+print("yo")
diff --git a/test/formatters/samplecode/isort/out.py b/test/formatters/samplecode/isort/out.py
new file mode 100644
index 0000000..9d6689f
--- /dev/null
+++ b/test/formatters/samplecode/isort/out.py
@@ -0,0 +1,11 @@
+from __future__ import absolute_import
+
+import os
+import sys
+
+from my_lib import Object, Object2, Object3
+from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9,
+ lib10, lib11, lib12, lib13, lib14, lib15)
+
+print("Hey")
+print("yo")
diff --git a/test/formatters/samplecode/latexindent/in.tex b/test/formatters/samplecode/latexindent/in.tex
new file mode 100644
index 0000000..9a3c300
--- /dev/null
+++ b/test/formatters/samplecode/latexindent/in.tex
@@ -0,0 +1,9 @@
+\begin{filecontents}{mybib.bib}
+@online{strawberryperl,
+title="Strawberry Perl",
+url="http://strawberryperl.com/"}
+@online{cmhblog,
+title="A Perl script ...
+url="...
+}
+\end{filecontents}
diff --git a/test/formatters/samplecode/latexindent/out.tex b/test/formatters/samplecode/latexindent/out.tex
new file mode 100644
index 0000000..67e03e9
--- /dev/null
+++ b/test/formatters/samplecode/latexindent/out.tex
@@ -0,0 +1,9 @@
+\begin{filecontents}{mybib.bib}
+ @online{strawberryperl,
+ title="Strawberry Perl",
+ url="http://strawberryperl.com/"}
+ @online{cmhblog,
+ title="A Perl script ...
+ url="...
+ }
+\end{filecontents}
diff --git a/test/formatters/samplecode/mix-format/in.erl b/test/formatters/samplecode/mix-format/in.erl
new file mode 100644
index 0000000..21f17df
--- /dev/null
+++ b/test/formatters/samplecode/mix-format/in.erl
@@ -0,0 +1,7 @@
+ :c
+ =
+ List.last(
+ [
+:a,:b,
+ :c
+])
diff --git a/test/formatters/samplecode/mix-format/out.erl b/test/formatters/samplecode/mix-format/out.erl
new file mode 100644
index 0000000..9ced1e1
--- /dev/null
+++ b/test/formatters/samplecode/mix-format/out.erl
@@ -0,0 +1,6 @@
+:c =
+ List.last([
+ :a,
+ :b,
+ :c
+ ])
diff --git a/test/formatters/samplecode/ocamlformat/in.ml b/test/formatters/samplecode/ocamlformat/in.ml
new file mode 100644
index 0000000..dc3f123
--- /dev/null
+++ b/test/formatters/samplecode/ocamlformat/in.ml
@@ -0,0 +1,9 @@
+(* https://github.com/ocaml-ppx/ocamlformat/blob/main/test/passing/tests/alignment.ml.ref *)
+
+let file_contents = [
+]
+ @ [
+ foo
+ ] @ [
+ bar
+ ]
diff --git a/test/formatters/samplecode/ocamlformat/out.ml b/test/formatters/samplecode/ocamlformat/out.ml
new file mode 100644
index 0000000..1c449c6
--- /dev/null
+++ b/test/formatters/samplecode/ocamlformat/out.ml
@@ -0,0 +1,3 @@
+(* https://github.com/ocaml-ppx/ocamlformat/blob/main/test/passing/tests/alignment.ml.ref *)
+
+let file_contents = [] @ [ foo ] @ [ bar ]
diff --git a/test/formatters/samplecode/prettier/in.css b/test/formatters/samplecode/prettier/in.css
new file mode 100644
index 0000000..55d5d36
--- /dev/null
+++ b/test/formatters/samplecode/prettier/in.css
@@ -0,0 +1,13 @@
+ body
+
+{
+ padding-left : 11em;
+font-family
+ : Georgia,
+
+ "Times New Roman",
+ Times, serif;
+ color: purple;
+ background-color:
+ #d8da3d
+ }
diff --git a/test/formatters/samplecode/prettier/in.html b/test/formatters/samplecode/prettier/in.html
new file mode 100644
index 0000000..87c9e3e
--- /dev/null
+++ b/test/formatters/samplecode/prettier/in.html
@@ -0,0 +1 @@
+<h2>Minify <abbr title="HyperText Markup Language">HTML</abbr> and any <abbr title="Cascading Style Sheets">CSS</abbr> or <abbr title="JavaScript">JS</abbr> included in your markup</h2>
diff --git a/test/formatters/samplecode/prettier/in.js b/test/formatters/samplecode/prettier/in.js
new file mode 100644
index 0000000..fd56713
--- /dev/null
+++ b/test/formatters/samplecode/prettier/in.js
@@ -0,0 +1,4 @@
+function HelloWorld({greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) {
+
+ if(!greeting){return null};
+ }
diff --git a/test/formatters/samplecode/prettier/in.json b/test/formatters/samplecode/prettier/in.json
new file mode 100644
index 0000000..28dc75f
--- /dev/null
+++ b/test/formatters/samplecode/prettier/in.json
@@ -0,0 +1 @@
+{"arrowParens":"always","bracketSpacing":true,"embeddedLanguageFormatting":"auto","htmlWhitespaceSensitivity":"css","insertPragma":false,"jsxBracketSameLine":false,"jsxSingleQuote":false,"printWidth":80,"proseWrap":"preserve","quoteProps":"as-needed","requirePragma":false,"semi":true,"singleQuote":false,"tabWidth":2,"trailingComma":"es5","useTabs":false,"vueIndentScriptAndStyle":false}
diff --git a/test/formatters/samplecode/prettier/in.scss b/test/formatters/samplecode/prettier/in.scss
new file mode 100644
index 0000000..e824587
--- /dev/null
+++ b/test/formatters/samplecode/prettier/in.scss
@@ -0,0 +1 @@
+/* Define standard variables and values for website */$bgcolor: lightblue;$textcolor: darkblue;$fontsize: 18px;/* Use the variables */body{background-color: $bgcolor; color: $textcolor; font-size: $fontsize;}
diff --git a/test/formatters/samplecode/prettier/in.ts b/test/formatters/samplecode/prettier/in.ts
new file mode 100644
index 0000000..c75d40f
--- /dev/null
+++ b/test/formatters/samplecode/prettier/in.ts
@@ -0,0 +1 @@
+interface GreetingSettings{greeting: string; duration?: number; color?: string;}declare function greet(setting: GreetingSettings): void;
diff --git a/test/formatters/samplecode/prettier/in.yml b/test/formatters/samplecode/prettier/in.yml
new file mode 100644
index 0000000..19f33ef
--- /dev/null
+++ b/test/formatters/samplecode/prettier/in.yml
@@ -0,0 +1,13 @@
+---
+- hosts:
+ all
+
+ tasks:
+ - name:
+ Get software for apt repository management.
+ apt:
+ state: present
+
+
+ name:
+ - python3-pycurl
diff --git a/test/formatters/samplecode/prettier/out.css b/test/formatters/samplecode/prettier/out.css
new file mode 100644
index 0000000..9158996
--- /dev/null
+++ b/test/formatters/samplecode/prettier/out.css
@@ -0,0 +1,6 @@
+body {
+ padding-left: 11em;
+ font-family: Georgia, "Times New Roman", Times, serif;
+ color: purple;
+ background-color: #d8da3d;
+}
diff --git a/test/formatters/samplecode/prettier/out.html b/test/formatters/samplecode/prettier/out.html
new file mode 100644
index 0000000..7702be8
--- /dev/null
+++ b/test/formatters/samplecode/prettier/out.html
@@ -0,0 +1,5 @@
+<h2>
+ Minify <abbr title="HyperText Markup Language">HTML</abbr> and any
+ <abbr title="Cascading Style Sheets">CSS</abbr> or
+ <abbr title="JavaScript">JS</abbr> included in your markup
+</h2>
diff --git a/test/formatters/samplecode/prettier/out.js b/test/formatters/samplecode/prettier/out.js
new file mode 100644
index 0000000..ec9cfe4
--- /dev/null
+++ b/test/formatters/samplecode/prettier/out.js
@@ -0,0 +1,10 @@
+function HelloWorld({
+ greeting = "hello",
+ greeted = '"World"',
+ silent = false,
+ onMouseOver,
+}) {
+ if (!greeting) {
+ return null;
+ }
+}
diff --git a/test/formatters/samplecode/prettier/out.json b/test/formatters/samplecode/prettier/out.json
new file mode 100644
index 0000000..59bb3b4
--- /dev/null
+++ b/test/formatters/samplecode/prettier/out.json
@@ -0,0 +1,19 @@
+{
+ "arrowParens": "always",
+ "bracketSpacing": true,
+ "embeddedLanguageFormatting": "auto",
+ "htmlWhitespaceSensitivity": "css",
+ "insertPragma": false,
+ "jsxBracketSameLine": false,
+ "jsxSingleQuote": false,
+ "printWidth": 80,
+ "proseWrap": "preserve",
+ "quoteProps": "as-needed",
+ "requirePragma": false,
+ "semi": true,
+ "singleQuote": false,
+ "tabWidth": 2,
+ "trailingComma": "es5",
+ "useTabs": false,
+ "vueIndentScriptAndStyle": false
+}
diff --git a/test/formatters/samplecode/prettier/out.scss b/test/formatters/samplecode/prettier/out.scss
new file mode 100644
index 0000000..9ae1829
--- /dev/null
+++ b/test/formatters/samplecode/prettier/out.scss
@@ -0,0 +1,9 @@
+/* Define standard variables and values for website */
+$bgcolor: lightblue;
+$textcolor: darkblue;
+$fontsize: 18px; /* Use the variables */
+body {
+ background-color: $bgcolor;
+ color: $textcolor;
+ font-size: $fontsize;
+}
diff --git a/test/formatters/samplecode/prettier/out.ts b/test/formatters/samplecode/prettier/out.ts
new file mode 100644
index 0000000..143b5a7
--- /dev/null
+++ b/test/formatters/samplecode/prettier/out.ts
@@ -0,0 +1,6 @@
+interface GreetingSettings {
+ greeting: string;
+ duration?: number;
+ color?: string;
+}
+declare function greet(setting: GreetingSettings): void;
diff --git a/test/formatters/samplecode/prettier/out.yml b/test/formatters/samplecode/prettier/out.yml
new file mode 100644
index 0000000..4163e5e
--- /dev/null
+++ b/test/formatters/samplecode/prettier/out.yml
@@ -0,0 +1,10 @@
+---
+- hosts: all
+
+ tasks:
+ - name: Get software for apt repository management.
+ apt:
+ state: present
+
+ name:
+ - python3-pycurl
diff --git a/test/formatters/samplecode/rustfmt/in.rs b/test/formatters/samplecode/rustfmt/in.rs
new file mode 100644
index 0000000..e09c014
--- /dev/null
+++ b/test/formatters/samplecode/rustfmt/in.rs
@@ -0,0 +1,12 @@
+fn foo() {
+ println!("a");
+}
+
+
+
+fn bar() {
+ println!("b");
+
+
+ println!("c");
+}
diff --git a/test/formatters/samplecode/rustfmt/out.rs b/test/formatters/samplecode/rustfmt/out.rs
new file mode 100644
index 0000000..28db64c
--- /dev/null
+++ b/test/formatters/samplecode/rustfmt/out.rs
@@ -0,0 +1,9 @@
+fn foo() {
+ println!("a");
+}
+
+fn bar() {
+ println!("b");
+
+ println!("c");
+}
diff --git a/test/formatters/samplecode/terraform/in.tf b/test/formatters/samplecode/terraform/in.tf
new file mode 100644
index 0000000..7fd0456
--- /dev/null
+++ b/test/formatters/samplecode/terraform/in.tf
@@ -0,0 +1,6 @@
+ resource "google_sql_user" "user" {
+ name = "camunda"
+ instance =google_sql_database_instance.camunda-db.name
+
+ password ="futurice"
+ }
diff --git a/test/formatters/samplecode/terraform/out.tf b/test/formatters/samplecode/terraform/out.tf
new file mode 100644
index 0000000..ca64220
--- /dev/null
+++ b/test/formatters/samplecode/terraform/out.tf
@@ -0,0 +1,6 @@
+resource "google_sql_user" "user" {
+ name = "camunda"
+ instance = google_sql_database_instance.camunda-db.name
+
+ password = "futurice"
+}