Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Use relative paths with stylelint #448

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lint/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ alias(
visibility = ["//visibility:public"],
)

alias(
name = "stylelint.compact-formatter",
actual = "//lint/js:stylelint.compact-formatter",
visibility = ["//visibility:public"],
)

bzl_library(
name = "eslint",
srcs = ["eslint.bzl"],
Expand Down
6 changes: 6 additions & 0 deletions lint/js/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ js_library(
visibility = ["//visibility:public"],
)

js_library(
name = "stylelint.compact-formatter",
srcs = ["stylelint.compactFormatter.mjs"],
visibility = ["//visibility:public"],
)

138 changes: 138 additions & 0 deletions lint/js/stylelint.compactFormatter.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Fork of 'compactFormatter' plugin, changed so that it prints relative paths.
// 3 files have been combined into 1
// https://github.com/stylelint/stylelint/blob/b2c99cef764643f3bd9539b34cdec58af882db88/lib/formatters/compactFormatter.mjs
// https://github.com/stylelint/stylelint/blob/b2c99cef764643f3bd9539b34cdec58af882db88/lib/formatters/preprocessWarnings.mjs
// https://github.com/stylelint/stylelint/blob/b2c99cef764643f3bd9539b34cdec58af882db88/lib/constants.mjs


/***************************************************************************************************************
* The following is vendored from:
* https://github.com/stylelint/stylelint/blob/b2c99cef764643f3bd9539b34cdec58af882db88/lib/constants.mjs
***************************************************************************************************************/
import { relative, sep } from 'node:path';

export const DEFAULT_CACHE_LOCATION = './.stylelintcache';
export const CACHE_STRATEGY_METADATA = 'metadata';
export const CACHE_STRATEGY_CONTENT = 'content';
export const DEFAULT_CACHE_STRATEGY = CACHE_STRATEGY_METADATA;

export const DEFAULT_IGNORE_FILENAME = '.stylelintignore';

export const DEFAULT_FORMATTER = 'string';

// NOTE: Partially based on `sysexits.h`.
export const EXIT_CODE_SUCCESS = 0;
export const EXIT_CODE_FATAL_ERROR = 1;
export const EXIT_CODE_LINT_PROBLEM = 2;
export const EXIT_CODE_INVALID_USAGE = 64;
export const EXIT_CODE_INVALID_CONFIG = 78;

export const RULE_NAME_ALL = 'all';

export const SEVERITY_ERROR = 'error';
export const SEVERITY_WARNING = 'warning';
export const DEFAULT_SEVERITY = SEVERITY_ERROR;

/***************************************************************************************************************
* The following is vendored from:
* https://github.com/stylelint/stylelint/blob/b2c99cef764643f3bd9539b34cdec58af882db88/lib/formatters/preprocessWarnings.mjs
***************************************************************************************************************/
/** @import {LintResult} from 'stylelint' */
/** @typedef {LintResult['parseErrors'][0]} ParseError */
/** @typedef {LintResult['warnings'][0]} Warning */
/** @typedef {Warning['severity']} Severity */

/**
* Preprocess warnings in a given lint result.
* Note that this function has a side-effect.
*
* @param {LintResult} result
* @returns {LintResult}
*/
export function preprocessWarnings(result) {
for (const error of result.parseErrors || []) {
result.warnings.push(parseErrorToWarning(error));
}

for (const warning of result.warnings) {
warning.severity = normalizeSeverity(warning);
}

result.warnings.sort(byLocationOrder);

return result;
}

/**
* @param {ParseError} error
* @returns {Warning}
*/
function parseErrorToWarning(error) {
return {
line: error.line,
column: error.column,
rule: error.stylelintType,
severity: SEVERITY_ERROR,
text: `${error.text} (${error.stylelintType})`,
};
}

/**
* @param {Warning} warning
* @returns {Severity}
*/
function normalizeSeverity(warning) {
// NOTE: Plugins may add a warning without severity, for example,
// by directly using the PostCSS `Result#warn()` API.
return warning.severity || DEFAULT_SEVERITY;
}

/**
* @param {Warning} a
* @param {Warning} b
* @returns {number}
*/
function byLocationOrder(a, b) {
// positionless first
if (!a.line && b.line) return -1;

// positionless first
if (a.line && !b.line) return 1;

if (a.line < b.line) return -1;

if (a.line > b.line) return 1;

if (a.column < b.column) return -1;

if (a.column > b.column) return 1;

return 0;
}

/***************************************************************************************************************
* The following is vendored from:
* https://github.com/stylelint/stylelint/blob/b2c99cef764643f3bd9539b34cdec58af882db88/lib/formatters/compactFormatter.mjs
***************************************************************************************************************/
/**
* @type {import('stylelint').Formatter}
* @param {import('stylelint').Warning[]} messages
* @param {string} source
* @param {string} cwd
*/
export default function compactFormatter(results, returnValue) {
return results
.flatMap((result) => {
const { warnings } = preprocessWarnings(result);

return warnings.map(
(warning) =>
`${relative((returnValue && returnValue.cwd) || process.cwd(), result.source).split(sep).join('/')}: ` +
`line ${warning.line}, ` +
`col ${warning.column}, ` +
`${warning.severity} - ` +
`${warning.text}`,
);
})
.join('\n');
}
25 changes: 19 additions & 6 deletions lint/stylelint.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@ load("//lint/private:lint_aspect.bzl", "LintOptionsInfo", "filter_srcs", "output

_MNEMONIC = "AspectRulesLintStylelint"

def _gather_inputs(ctx, srcs):
def _gather_inputs(ctx, srcs, files = []):
inputs = copy_files_to_bin_actions(ctx, srcs)

# Add the config file along with any deps it has on npm packages
if "gather_files_from_js_providers" in dir(js_lib_helpers):
# rules_js 1.x
js_inputs = js_lib_helpers.gather_files_from_js_providers(
[ctx.attr._config_file],
[ctx.attr._config_file] + files,
include_transitive_sources = True,
include_declarations = False,
include_npm_linked_packages = True,
)
else:
# rules_js 2.x
js_inputs = js_lib_helpers.gather_files_from_js_infos(
[ctx.attr._config_file],
[ctx.attr._config_file] + files,
include_sources = True,
include_transitive_sources = True,
include_types = False,
Expand All @@ -68,7 +68,7 @@ def _gather_inputs(ctx, srcs):
inputs.extend(js_inputs.to_list())
return inputs

def stylelint_action(ctx, executable, srcs, stderr, exit_code = None, env = {}, options = []):
def stylelint_action(ctx, executable, srcs, stderr, exit_code = None, env = {}, options = [], format = None):
"""Spawn stylelint as a Bazel action

Args:
Expand All @@ -86,6 +86,7 @@ def stylelint_action(ctx, executable, srcs, stderr, exit_code = None, env = {},
78 - invalid configuration file
env: environment variables for stylelint
options: additional command-line arguments
format: a formatter to add as a command line argument
"""
outputs = [stderr]

Expand All @@ -101,8 +102,15 @@ def stylelint_action(ctx, executable, srcs, stderr, exit_code = None, env = {},
# Create empty file on success, as Bazel expects one
command = "{stylelint} $@ && touch {stderr}"

file_inputs = []
if type(format) == "string":
args.add_all(["--formatter", format])
elif format != None:
args.add_all(["--custom-formatter", "../../../" + format.files.to_list()[0].path])
file_inputs.append(format)

ctx.actions.run_shell(
inputs = _gather_inputs(ctx, srcs),
inputs = _gather_inputs(ctx, srcs, file_inputs),
outputs = outputs,
command = command.format(stylelint = executable._stylelint.path, stderr = stderr.path),
arguments = [args],
Expand Down Expand Up @@ -181,7 +189,7 @@ def _stylelint_aspect_impl(target, ctx):
stylelint_action(ctx, ctx.executable, files_to_lint, outputs.human.out, outputs.human.exit_code, options = color_options)

# TODO(alex): if we run with --fix, this will report the issues that were fixed. Does a machine reader want to know about them?
stylelint_action(ctx, ctx.executable, files_to_lint, outputs.machine.out, outputs.machine.exit_code, options = ["--formatter", "compact"])
stylelint_action(ctx, ctx.executable, files_to_lint, outputs.machine.out, outputs.machine.exit_code, format = ctx.attr._compact_formatter)

return [info]

Expand Down Expand Up @@ -216,6 +224,11 @@ def lint_stylelint_aspect(binary, config, rule_kinds = ["css_library"], filegrou
default = config,
allow_files = True,
),
"_compact_formatter": attr.label(
default = "@aspect_rules_lint//lint:stylelint.compact-formatter",
allow_single_file = True,
cfg = "exec",
),
"_patcher": attr.label(
default = "@aspect_rules_lint//lint/private:patcher",
executable = True,
Expand Down
Loading