├── its
├── plugin
│ ├── projects
│ │ ├── issues-project
│ │ │ └── src
│ │ │ │ ├── empty1.css
│ │ │ │ ├── empty2.less
│ │ │ │ ├── empty3.scss
│ │ │ │ ├── file-with-parsing-error.css
│ │ │ │ ├── file7.jsx
│ │ │ │ ├── file-with-parsing-error-excluded.css
│ │ │ │ ├── file4.foo
│ │ │ │ ├── file-with-parsing-error.less
│ │ │ │ ├── file5.htm
│ │ │ │ ├── file6.vue
│ │ │ │ ├── file5-1.html
│ │ │ │ ├── cssModules.css
│ │ │ │ ├── file2.less
│ │ │ │ └── file3.scss
│ │ ├── minified-project
│ │ │ └── src
│ │ │ │ ├── normal.css
│ │ │ │ ├── normal.min.css
│ │ │ │ └── oneline.css
│ │ ├── (dir with paren)
│ │ │ └── src
│ │ │ │ └── file1.css
│ │ ├── metrics-project
│ │ │ └── src
│ │ │ │ ├── file1.css
│ │ │ │ ├── file4.html
│ │ │ │ ├── file3.scss
│ │ │ │ └── file2.less
│ │ ├── php-project
│ │ │ └── src
│ │ │ │ └── index.php
│ │ └── external-report-project
│ │ │ ├── report.json
│ │ │ └── src
│ │ │ ├── file1.css
│ │ │ └── file2.css
│ ├── pom.xml
│ └── src
│ │ └── test
│ │ └── java
│ │ └── org
│ │ └── sonar
│ │ └── css
│ │ └── its
│ │ ├── MinifiedTest.java
│ │ ├── MetricsTest.java
│ │ ├── NoCssFileProjectTest.java
│ │ ├── StylelintReportTest.java
│ │ └── NonStandardPathTest.java
├── sources
│ └── custom
│ │ ├── S4662.scss
│ │ ├── S5362.less
│ │ ├── S5362.scss
│ │ ├── S4670.css
│ │ ├── S4660.scss
│ │ ├── test.css
│ │ ├── S4666.css
│ │ ├── S4654.scss
│ │ ├── S4654.css
│ │ └── S4653.scss
├── ruling
│ ├── src
│ │ └── test
│ │ │ └── resources
│ │ │ └── expected
│ │ │ ├── css-S4653.json
│ │ │ ├── css-S4670.json
│ │ │ ├── css-S4658.json
│ │ │ ├── css-S4667.json
│ │ │ ├── css-S4661.json
│ │ │ ├── css-S4648.json
│ │ │ ├── css-S4647.json
│ │ │ ├── css-S4654.json
│ │ │ ├── css-S4656.json
│ │ │ ├── css-S4662.json
│ │ │ └── css-S4666.json
│ └── pom.xml
└── pom.xml
├── sonar-css-plugin
├── css-bundle
│ ├── tests
│ │ ├── fixtures
│ │ │ ├── file.css
│ │ │ ├── file-bom.css
│ │ │ ├── stylelintconfig.json
│ │ │ ├── file.html
│ │ │ └── file.php
│ │ ├── utils.ts
│ │ └── server-mock-stylelint.test.ts
│ ├── package
│ │ ├── .gitignore
│ │ ├── node_modules
│ │ │ ├── .bin
│ │ │ │ └── run-node
│ │ │ ├── .yarn-integrity
│ │ │ └── run-node
│ │ │ │ ├── package.json
│ │ │ │ ├── license
│ │ │ │ ├── run-node
│ │ │ │ └── readme.md
│ │ ├── package.json
│ │ └── yarn.lock
│ ├── jest.config.js
│ ├── bin
│ │ └── server
│ ├── tsconfig.json
│ ├── package.json
│ └── src
│ │ └── server.ts
└── src
│ ├── test
│ ├── resources
│ │ ├── bundle
│ │ │ ├── invalid-zip-file.zip
│ │ │ └── test-css-bundle.zip
│ │ ├── stylelint-report
│ │ │ ├── file.css
│ │ │ ├── report-utf16.json
│ │ │ ├── report.json
│ │ │ ├── report-utf8-bom.json
│ │ │ └── invalid-file.json
│ │ └── mock-start-server
│ │ │ ├── throw.js
│ │ │ ├── testLogs.js
│ │ │ ├── failedClose.js
│ │ │ └── startServer.js
│ └── java
│ │ └── org
│ │ └── sonar
│ │ └── css
│ │ └── plugin
│ │ ├── server
│ │ ├── NetUtilsTest.java
│ │ └── bundle
│ │ │ ├── ZipTest.java
│ │ │ └── CssAnalyzerBundleTest.java
│ │ ├── CssLanguageTest.java
│ │ ├── SonarWayProfileTest.java
│ │ ├── CssPluginTest.java
│ │ ├── CssRulesDefinitionTest.java
│ │ ├── MinifiedFilesFilterTest.java
│ │ └── TestActiveRules.java
│ ├── main
│ ├── resources
│ │ ├── org
│ │ │ └── sonar
│ │ │ │ └── l10n
│ │ │ │ └── css
│ │ │ │ └── rules
│ │ │ │ └── css
│ │ │ │ ├── S4667.html
│ │ │ │ ├── S4663.html
│ │ │ │ ├── S4658.html
│ │ │ │ ├── S4653.json
│ │ │ │ ├── S4661.json
│ │ │ │ ├── S4662.json
│ │ │ │ ├── S4670.json
│ │ │ │ ├── S4647.json
│ │ │ │ ├── S4654.json
│ │ │ │ ├── S4656.json
│ │ │ │ ├── S4662.html
│ │ │ │ ├── S4667.json
│ │ │ │ ├── S4658.json
│ │ │ │ ├── S4659.json
│ │ │ │ ├── S4660.json
│ │ │ │ ├── S4666.json
│ │ │ │ ├── S4670.html
│ │ │ │ ├── S4648.json
│ │ │ │ ├── S4650.json
│ │ │ │ ├── S4652.json
│ │ │ │ ├── S4663.json
│ │ │ │ ├── S5362.json
│ │ │ │ ├── S1116.json
│ │ │ │ ├── S1128.json
│ │ │ │ ├── S4651.json
│ │ │ │ ├── S4655.json
│ │ │ │ ├── S4668.json
│ │ │ │ ├── S4649.json
│ │ │ │ ├── S4657.json
│ │ │ │ ├── S4664.json
│ │ │ │ ├── S4659.html
│ │ │ │ ├── S4660.html
│ │ │ │ ├── S1128.html
│ │ │ │ ├── Sonar_way_profile.json
│ │ │ │ ├── S4668.html
│ │ │ │ ├── S4661.html
│ │ │ │ ├── S4666.html
│ │ │ │ ├── S4656.html
│ │ │ │ ├── S4648.html
│ │ │ │ ├── S4653.html
│ │ │ │ ├── S4654.html
│ │ │ │ ├── S4650.html
│ │ │ │ ├── S4664.html
│ │ │ │ ├── S4655.html
│ │ │ │ ├── S4652.html
│ │ │ │ ├── S1116.html
│ │ │ │ ├── S4657.html
│ │ │ │ ├── S5362.html
│ │ │ │ ├── S4649.html
│ │ │ │ ├── S4647.html
│ │ │ │ └── S4651.html
│ │ └── static
│ │ │ └── documentation.md
│ └── java
│ │ └── org
│ │ └── sonar
│ │ └── css
│ │ └── plugin
│ │ ├── package-info.java
│ │ ├── rules
│ │ ├── package-info.java
│ │ ├── BlockNoEmpty.java
│ │ ├── NoEmptySource.java
│ │ ├── CommentNoEmpty.java
│ │ ├── StringNoNewline.java
│ │ ├── ColorNoInvalidHex.java
│ │ ├── NoExtraSemicolons.java
│ │ ├── CssRule.java
│ │ ├── NoDuplicateSelectors.java
│ │ ├── FunctionCalcNoInvalid.java
│ │ ├── NoDescendingSpecificity.java
│ │ ├── NoDuplicateAtImportRules.java
│ │ ├── FontFamilyNoDuplicateNames.java
│ │ ├── MediaFeatureNameNoUnknown.java
│ │ ├── NoInvalidDoubleSlashComments.java
│ │ ├── FunctionCalcNoUnspacedOperator.java
│ │ ├── KeyframeDeclarationNoImportant.java
│ │ ├── FontFamilyNoMissingGenericFamilyKeyword.java
│ │ ├── DeclarationBlockNoShorthandPropertyOverrides.java
│ │ ├── FunctionLinearGradientNoNonstandardDirection.java
│ │ ├── RuleUtils.java
│ │ ├── UnitNoUnknown.java
│ │ ├── DeclarationBlockNoDuplicateProperties.java
│ │ ├── AtRuleNoUnknown.java
│ │ ├── SelectorPseudoClassNoUnknown.java
│ │ ├── SelectorPseudoElementNoUnknown.java
│ │ ├── PropertyNoUnknown.java
│ │ └── SelectorTypeNoUnknown.java
│ │ ├── server
│ │ ├── package-info.java
│ │ ├── bundle
│ │ │ ├── package-info.java
│ │ │ ├── Bundle.java
│ │ │ ├── Zip.java
│ │ │ └── CssAnalyzerBundle.java
│ │ ├── NetUtils.java
│ │ └── NodeDeprecationWarning.java
│ │ ├── StylelintReport.java
│ │ ├── CssLanguage.java
│ │ ├── metrics
│ │ ├── CssTokenType.java
│ │ ├── Tokenizer.java
│ │ └── CssToken.java
│ │ ├── SonarWayProfile.java
│ │ ├── CssRulesDefinition.java
│ │ ├── MinifiedFilesFilter.java
│ │ └── CssPlugin.java
│ └── sonarcss-assembly.xml
├── .github
├── CODEOWNERS
└── workflows
│ └── release.yml
├── yarn.lock
├── .cirrus.star
├── .gitmodules
├── third-party-licenses.sh
├── sonarpedia.json
├── README.md
├── wss-unified-agent.config
├── .gitignore
└── .cirrus
├── nodejs-10.Dockerfile
└── nodejs-10.jdk17.Dockerfile
/its/plugin/projects/issues-project/src/empty1.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/empty2.less:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/empty3.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/tests/fixtures/file.css:
--------------------------------------------------------------------------------
1 | p { }
2 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/bundle/invalid-zip-file.zip:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/.gitignore:
--------------------------------------------------------------------------------
1 | !node_modules/
2 |
3 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/tests/fixtures/file-bom.css:
--------------------------------------------------------------------------------
1 | p {
2 | }
3 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | .github/CODEOWNERS @SonarSource/languages-team-jsts
2 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file-with-parsing-error.css:
--------------------------------------------------------------------------------
1 | a {
2 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file7.jsx:
--------------------------------------------------------------------------------
1 | // file is not analyzed
2 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file-with-parsing-error-excluded.css:
--------------------------------------------------------------------------------
1 | a {
2 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/node_modules/.bin/run-node:
--------------------------------------------------------------------------------
1 | ../run-node/run-node
--------------------------------------------------------------------------------
/its/plugin/projects/minified-project/src/normal.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: red;
3 | }
4 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/stylelint-report/file.css:
--------------------------------------------------------------------------------
1 | File content is set in test file
2 |
--------------------------------------------------------------------------------
/its/sources/custom/S4662.scss:
--------------------------------------------------------------------------------
1 | @use 'variables'; /* No FP */
2 |
3 | @@media {
4 | display: none;
5 | }
6 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 |
--------------------------------------------------------------------------------
/its/sources/custom/S5362.less:
--------------------------------------------------------------------------------
1 | .foo {
2 | height: calc(100% - (@a-height + @b-margin-top)); /* No FP */
3 | }
4 |
--------------------------------------------------------------------------------
/its/sources/custom/S5362.scss:
--------------------------------------------------------------------------------
1 | .foo {
2 | height: calc(100% - ($a-height + $b-margin-top)); /* No FP*/
3 | }
4 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4653.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:custom/S4653.scss':[
3 | 4,
4 | 5,
5 | ],
6 | }
7 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4670.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:custom/S4670.css':[
3 | 1,
4 | 2,
5 | ],
6 | }
7 |
--------------------------------------------------------------------------------
/its/sources/custom/S4670.css:
--------------------------------------------------------------------------------
1 | unknown {} /* Noncompliant */
2 | x-Foo {} /* Noncompliant */
3 | x-foo {} /* No FP */
4 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4658.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:custom/S4670.css':[
3 | 1,
4 | 2,
5 | 3,
6 | ],
7 | }
8 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/tests/fixtures/stylelintconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "block-no-empty": true
4 | }
5 | }
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/mock-start-server/throw.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | throw "Something wrong happened"
4 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file4.foo:
--------------------------------------------------------------------------------
1 | File required to test execution of analysis on a file with non-css extension
2 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4667.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:projects/normalize.css-8.0.1/test.html':[
3 | 253,
4 | ],
5 | }
6 |
--------------------------------------------------------------------------------
/.cirrus.star:
--------------------------------------------------------------------------------
1 | load("github.com/SonarSource/cirrus-modules@v2", "load_features")
2 |
3 | def main(ctx):
4 | return load_features(ctx)
5 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4661.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:projects/animate.css-4.1.1/docs/style.css':[
3 | 592,
4 | ],
5 | }
6 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "its/sources/projects"]
2 | path = its/sources/projects
3 | url = https://github.com/SonarSource/css-test-sources.git
4 |
--------------------------------------------------------------------------------
/its/sources/custom/S4660.scss:
--------------------------------------------------------------------------------
1 | & ::v-deep .q-tab__content {
2 | min-width: 0;
3 | }
4 |
5 | ion-select::part(icon) {
6 | display: none;
7 | }
8 |
--------------------------------------------------------------------------------
/its/plugin/projects/minified-project/src/normal.min.css:
--------------------------------------------------------------------------------
1 | /* content doesn't matter as file excluded based on filename */
2 | body {
3 | color: red;
4 | }
5 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4667.html:
--------------------------------------------------------------------------------
1 |
This rule raises an issue when a CSS file is empty (ie: containing only spaces).
2 |
3 |
--------------------------------------------------------------------------------
/its/plugin/projects/(dir with paren)/src/file1.css:
--------------------------------------------------------------------------------
1 | @import "a.css";
2 | @import "a.css"; /* S1128 | no-duplicate-at-import-rules */
3 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/bundle/test-css-bundle.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SonarSource/sonar-css/HEAD/sonar-css-plugin/src/test/resources/bundle/test-css-bundle.zip
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file-with-parsing-error.less:
--------------------------------------------------------------------------------
1 | .foo(@i : 1 ) when (@i <= 10){
2 | @num : @i *10 ;
3 | .height-@{num}{
4 | height : @num * 1%;
5 | }
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/stylelint-report/report-utf16.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SonarSource/sonar-css/HEAD/sonar-css-plugin/src/test/resources/stylelint-report/report-utf16.json
--------------------------------------------------------------------------------
/its/plugin/projects/metrics-project/src/file1.css:
--------------------------------------------------------------------------------
1 | .class1 {
2 | background-color: #2d5e8b;
3 | }
4 | .class1 .class2 {
5 | color: #2d5e8b;
6 | foo: "some text";
7 | }
8 |
9 | /* some comment */
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4648.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:custom/test.css':[
3 | 7,
4 | ],
5 | 'project:projects/normalize.css-8.0.1/normalize.css':[
6 | 65,
7 | 108,
8 | ],
9 | }
10 |
--------------------------------------------------------------------------------
/third-party-licenses.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | mvn org.codehaus.mojo:license-maven-plugin:aggregate-add-third-party -Dlicense.includedScopes=compile
3 |
4 | cat target/generated-sources/license/THIRD-PARTY.txt
5 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4647.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:projects/bulma-0.9.2/docs/_includes/global/native.html':[
3 | 45,
4 | 45,
5 | 45,
6 | 49,
7 | 53,
8 | 57,
9 | 58,
10 | 62,
11 | 63,
12 | ],
13 | }
14 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/tests/fixtures/file.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | /tests/**/*.test.ts"]
9 | };
10 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "run-node-bundle",
3 | "version": "1.0.0",
4 | "description": "Small nested project to provide run-node",
5 | "main": "index.js",
6 | "author": "",
7 | "license": "LGPL-3.0",
8 | "dependencies": {
9 | "run-node": "1.0.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/its/sources/custom/S4666.css:
--------------------------------------------------------------------------------
1 | .myclass, .myotherclass {
2 | font-size: 10px;
3 | /* < lots more styles > */
4 | }
5 |
6 | /* particular override for myclass */
7 | .myclass { /* No FP */
8 | color: red;
9 | }
10 | /* particular override for myotherclass */
11 | .myotherclass { /* No FP */
12 | color: blue;
13 | }
14 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4663.html:
--------------------------------------------------------------------------------
1 | An empty multi-line comment is likely to be a mistake and doesn't help to improve the readability of the code. For these reasons, it should be
2 | removed.
3 | Noncompliant Code Example
4 |
5 | /* */
6 |
7 | /*
8 |
9 | */
10 |
11 |
12 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file6.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | hello
4 |
5 |
8 |
13 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file5-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Page Title
6 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | run-node@1.0.0:
6 | version "1.0.0"
7 | resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e"
8 | integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==
9 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4658.html:
--------------------------------------------------------------------------------
1 | Leftover empty blocks are usually introduced by mistake. They are useless and prevent readability of the code. They should be removed or completed
2 | with real code.
3 | Noncompliant Code Example
4 |
5 | a { }
6 |
7 | Compliant Solution
8 |
9 | a { color: pink; }
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/bin/server:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /*
4 | * This script expects following arguments
5 | *
6 | * port - port number on which server should listen
7 | * host - host address on which server should listen
8 | */
9 |
10 | const server = require("../lib/src/server");
11 |
12 | const port = process.argv[2];
13 | const host = process.argv[3];
14 |
15 | server.start(port, host);
16 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4653.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Units should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "5min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Blocker",
13 | "ruleSpecification": "RSPEC-4653",
14 | "sqKey": "S4653",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4661.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Media features should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4661",
14 | "sqKey": "S4661",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4662.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "\"at-rules\" should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4662",
14 | "sqKey": "S4662",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4670.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Selectors should be known",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "5min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Critical",
13 | "ruleSpecification": "RSPEC-4670",
14 | "sqKey": "S4670",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4647.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Color definitions should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Blocker",
13 | "ruleSpecification": "RSPEC-4647",
14 | "sqKey": "S4647",
15 | "scope": "All"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4654.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "CSS properties should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "5min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Blocker",
13 | "ruleSpecification": "RSPEC-4654",
14 | "sqKey": "S4654",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4656.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Properties should not be duplicated",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4656",
14 | "sqKey": "S4656",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4662.html:
--------------------------------------------------------------------------------
1 | The W3C specifications define the valid at-rules. Only the official and browser-specific at-rules should be used to get
2 | the expected impact in the final rendering.
3 | Noncompliant Code Example
4 |
5 | @encoding "utf-8";
6 |
7 | Compliant Solution
8 |
9 | @charset "utf-8";
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4667.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "CSS files should not be empty",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4667",
14 | "sqKey": "S4667",
15 | "scope": "All"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4658.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Empty blocks should be removed",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4658",
14 | "sqKey": "S4658",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4659.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Pseudo-class selectors should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4659",
14 | "sqKey": "S4659",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4660.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Pseudo-element selectors should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4660",
14 | "sqKey": "S4660",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4666.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Selectors should not be duplicated",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4666",
14 | "sqKey": "S4666",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4670.html:
--------------------------------------------------------------------------------
1 | HTML, SVG, and MathML define the selectors which can be used in a CSS. A selector that is not part of them is likely to be a typo or a
2 | misunderstanding of the CSS syntax.
3 | Noncompliant Code Example
4 |
5 | field {}
6 |
7 | ul list {}
8 |
9 | Compliant Solution
10 |
11 | input {}
12 |
13 | ul li {}
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4648.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Duplicated font names should be removed",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4648",
14 | "sqKey": "S4648",
15 | "scope": "All"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4650.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "\"calc\" operands should be correctly spaced",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Blocker",
13 | "ruleSpecification": "RSPEC-4650",
14 | "sqKey": "S4650",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4652.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Strings should not contain new lines",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4652",
14 | "sqKey": "S4652",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4663.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Multi-line comments should not be empty",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Minor",
13 | "ruleSpecification": "RSPEC-4663",
14 | "sqKey": "S4663",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S5362.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Expressions within \"calc\" should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "5min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Critical",
13 | "ruleSpecification": "RSPEC-5362",
14 | "sqKey": "S5362",
15 | "scope": "All"
16 | }
17 |
--------------------------------------------------------------------------------
/its/sources/custom/S4654.scss:
--------------------------------------------------------------------------------
1 | $light-blue-10: #c0e7f3;
2 | $light-blue-40: #4bc7e7;
3 | $teal: #23B8A7;
4 | :export {
5 | lightBlue10: $light-blue-10; /* No FP */
6 | lightBlue40: $light-blue-40; /* No FP */
7 | teal: $teal; /* No FP */
8 | }
9 |
10 | my-export-class {
11 | lightBlue10: $light-blue-10; /* Noncompliant */
12 | lightBlue40: $light-blue-40; /* Noncompliant */
13 | teal: $teal; /* Noncompliant */
14 | }
15 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S1116.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Extra semicolons should be removed",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "2min"
8 | },
9 | "tags": [
10 | "unused"
11 | ],
12 | "defaultSeverity": "Minor",
13 | "ruleSpecification": "RSPEC-1116",
14 | "sqKey": "S1116",
15 | "scope": "All"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S1128.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Duplicate imports should be removed",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "2min"
8 | },
9 | "tags": [
10 | "unused"
11 | ],
12 | "defaultSeverity": "Minor",
13 | "ruleSpecification": "RSPEC-1128",
14 | "sqKey": "S1128",
15 | "scope": "All"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4651.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "\"linear-gradient\" directions should be valid",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Critical",
13 | "ruleSpecification": "RSPEC-4651",
14 | "sqKey": "S4651",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4655.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "\"!important\" should not be used on \"keyframes\"",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4655",
14 | "sqKey": "S4655",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4668.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Single line comment syntax should not be used",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Blocker",
13 | "ruleSpecification": "RSPEC-4668",
14 | "sqKey": "S4668",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/stylelint-report/report.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "source": "file.css",
4 | "warnings": [
5 | {
6 | "line": 1,
7 | "rule": "color-no-invalid-hex",
8 | "text": "external issue message (color-no-invalid-hex)"
9 | },
10 | {
11 | "line": 1,
12 | "rule": "comment-no-empty",
13 | "text": "external issue message (comment-no-empty)"
14 | }
15 | ]
16 | }
17 | ]
18 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4649.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Font declarations should contain at least one generic font family",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "1min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Major",
13 | "ruleSpecification": "RSPEC-4649",
14 | "sqKey": "S4649",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/its/sources/custom/S4654.css:
--------------------------------------------------------------------------------
1 | a {
2 | colr: blue; /* Noncompliant */
3 | content-visibility: auto; /* No FP */
4 | contain-intrinsic-size: 400px; /* No FP */
5 | }
6 |
7 |
8 | img {
9 | -ms-interpolation-mode: bicubic; /* No FP */
10 | }
11 |
12 | table {
13 | mso-table-lspace: 0pt; /* No FP */
14 | mso-table-rspace: 0pt; /* No FP */
15 | }
16 |
17 | p, a, li, td, blockquote {
18 | mso-line-height-rule: exactly; /* No FP */
19 | }
20 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/stylelint-report/report-utf8-bom.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "source": "file.css",
4 | "warnings": [
5 | {
6 | "line": 1,
7 | "rule": "color-no-invalid-hex",
8 | "text": "external issue message (color-no-invalid-hex)"
9 | },
10 | {
11 | "line": 1,
12 | "rule": "comment-no-empty",
13 | "text": "external issue message (comment-no-empty)"
14 | }
15 | ]
16 | }
17 | ]
18 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/node_modules/.yarn-integrity:
--------------------------------------------------------------------------------
1 | {
2 | "systemParams": "darwin-x64-57",
3 | "modulesFolders": [
4 | "node_modules"
5 | ],
6 | "flags": [],
7 | "linkedModules": [],
8 | "topLevelPatterns": [
9 | "run-node@1.0.0"
10 | ],
11 | "lockfileEntries": {
12 | "run-node@1.0.0": "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e"
13 | },
14 | "files": [],
15 | "artifacts": {}
16 | }
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4657.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Shorthand properties that override related longhand properties should be avoided",
3 | "type": "BUG",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "5min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Critical",
13 | "ruleSpecification": "RSPEC-4657",
14 | "sqKey": "S4657",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4664.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Selectors of lower specificity should come before overriding selectors of higher specificity",
3 | "type": "CODE_SMELL",
4 | "status": "ready",
5 | "remediation": {
6 | "func": "Constant\/Issue",
7 | "constantCost": "5min"
8 | },
9 | "tags": [
10 |
11 | ],
12 | "defaultSeverity": "Critical",
13 | "ruleSpecification": "RSPEC-4664",
14 | "sqKey": "S4664",
15 | "scope": "Main"
16 | }
17 |
--------------------------------------------------------------------------------
/its/plugin/projects/minified-project/src/oneline.css:
--------------------------------------------------------------------------------
1 | /* Styles */ @import url(extra.css);ul li{list-style:square;margin:2em 20% 15px 0}#content{-webkit-font-smoothing:antialiased;background:url(img/gradient.png);background:linear-gradient(to bottom,red,rgba(255,0,0,0))}@media only screen and (min-width:35em){#content{width:50%}}.item+.item,.item~.item{margin-left:-15px}#buttons .lotsofcontent,#buttons>*,input[type=submit]{border-radius:.3rem}a:focus,a:hover{color:green}blockquote::after,blockquote::before{content:"\201d"}
2 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4659.html:
--------------------------------------------------------------------------------
1 | The W3C specifications define the valid pseudo-class selectors. Only the official and browser-specific pseudo-class selectors should be used to get
2 | the expected impact in the final rendering.
3 | Noncompliant Code Example
4 |
5 | a:hoverr { /* Noncompliant; there is a typo on the word "hover" */
6 | ...
7 | }
8 |
9 | Compliant Solution
10 |
11 | a:hover {
12 | ...
13 | }
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4660.html:
--------------------------------------------------------------------------------
1 | The W3C specifications define the valid pseudo-element selectors. Only the official and browser-specific pseudo-element selectors should be used to
2 | get the expected impact in the final rendering.
3 | Noncompliant Code Example
4 |
5 | a::beforre { /* Noncompliant; there is a typo on the word "before" */
6 | ...
7 | }
8 |
9 | Compliant Solution
10 |
11 | a::before {
12 | ...
13 | }
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "commonjs",
5 | "lib": ["dom", "es2017"],
6 | "declaration": true,
7 | "outDir": "./lib",
8 | "strict": true,
9 | "sourceMap": true,
10 | "noUnusedLocals": true,
11 | "noUnusedParameters": true,
12 | "allowSyntheticDefaultImports": true,
13 | "composite": true,
14 | "typeRoots": ["./node_modules/@types"],
15 | "skipLibCheck": true
16 | },
17 | "include": ["src/**/*"]
18 | }
19 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: sonar-release
3 | # This workflow is triggered when publishing a new github release
4 | # yamllint disable-line rule:truthy
5 | on:
6 | release:
7 | types:
8 | - published
9 |
10 | jobs:
11 | release:
12 | permissions:
13 | id-token: write
14 | contents: write
15 | uses: SonarSource/gh-action_release/.github/workflows/main.yaml@v5
16 | with:
17 | publishToBinaries: true
18 | mavenCentralSync: true
19 | slackChannel: team-lang-js-ts-css
20 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S1128.html:
--------------------------------------------------------------------------------
1 | Having the import of the same file twice, makes one of them useless. Leaving them in reduces the code's readability, since their presence can be
2 | confusing.
3 | Noncompliant Code Example
4 |
5 | @import 'a.css';
6 | @import 'a.css'; // Noncompliant
7 |
8 | @import url("a.css");
9 | @import url("a.css"); // Noncompliant
10 |
11 | Exceptions
12 | This rule ignores @import in less files.
13 |
14 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/stylelint-report/invalid-file.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "source": "not-exist.css",
4 | "warnings": [
5 | {
6 | "line": 1,
7 | "rule": "color-no-invalid-hex",
8 | "text": "external issue message"
9 | }
10 | ]
11 | },
12 | {
13 | "source": "file.css",
14 | "warnings": [
15 | {
16 | "line": 1,
17 | "rule": "comment-no-empty",
18 | "text": "external issue message (comment-no-empty)"
19 | }
20 | ]
21 | }
22 | ]
23 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/Sonar_way_profile.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Sonar way",
3 | "ruleKeys": [
4 | "S1116",
5 | "S1128",
6 | "S4647",
7 | "S4648",
8 | "S4649",
9 | "S4651",
10 | "S4652",
11 | "S4653",
12 | "S4654",
13 | "S4655",
14 | "S4656",
15 | "S4657",
16 | "S4658",
17 | "S4659",
18 | "S4660",
19 | "S4661",
20 | "S4662",
21 | "S4663",
22 | "S4666",
23 | "S4667",
24 | "S4668",
25 | "S4670",
26 | "S5362"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/mock-start-server/testLogs.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const http = require('http');
4 | const port = process.argv[2];
5 |
6 | console.log(`DEBUG testing debug log`)
7 | console.log(`WARN testing warn log`)
8 | console.log(`testing info log`)
9 | console.error(`testing error log`)
10 |
11 |
12 | const server = http.createServer(() => {});
13 |
14 | server.listen(port, (err) => {
15 | if (err) {
16 | return console.log('something bad happened', err)
17 | }
18 |
19 | console.log(`server is listening on ${port}`)
20 | });
21 |
--------------------------------------------------------------------------------
/its/sources/custom/S4653.scss:
--------------------------------------------------------------------------------
1 | $i: 1;
2 |
3 | .parent {
4 | width: $i/1.3+px; // FP (issue-160)
5 | height: $i/1.3+0px; // FP (issue-160)
6 |
7 | height: $i/1.3*1px; // this is OK and no issue is raised, recommended workaround
8 | }
9 |
10 | $ee-icons: (
11 | 1gb : "\e06e",
12 | 3g : "\e06d",
13 | 3gb : "\e06c",
14 | 4g : "\e06b",
15 | 4gee : "\e06a",
16 | 4gee-resumptive : "\e069",
17 | 4gee-streaming : "\e068",
18 | )
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DEPRECATED
2 | This project is deprecated. Now analysis for CSS code is provided by [SonarJS](https://github.com/SonarSource/SonarJS) analyzer.
3 | ## Code Quality and Security for CSS
4 |
5 | ### Building
6 |
7 | ```bash
8 | mvn package
9 | ```
10 |
11 | ### Feedback
12 | Please use https://community.sonarsource.com/ to provide any kind of feedback about CSS analysis in SonarQube/SonarCloud/SonarLint.
13 | ### License
14 |
15 | Copyright 2018-2021 SonarSource.
16 |
17 | Licensed under the [GNU Lesser General Public License, Version 3.0](http://www.gnu.org/licenses/lgpl.txt)
18 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4668.html:
--------------------------------------------------------------------------------
1 | The W3C specifications say comments should be defined using /* ... */. The use of // is not supported on all browsers and
2 | can lead to unexpected results.
3 | Noncompliant Code Example
4 |
5 | // some comment
6 | a { color: pink; }
7 |
8 | Compliant Solution
9 |
10 | /* some comment */
11 | a { color: pink; }
12 |
13 | Exceptions
14 | This rule ignores single line comments in less and scss files.
15 |
16 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4656.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:projects/animate.css-4.1.1/animate.css':[
3 | 16,
4 | 28,
5 | 34,
6 | 40,
7 | 46,
8 | 52,
9 | 58,
10 | 64,
11 | 70,
12 | 76,
13 | 82,
14 | 88,
15 | 94,
16 | 861,
17 | 1296,
18 | 1655,
19 | 2792,
20 | 2838,
21 | 3370,
22 | ],
23 | 'project:projects/bulma-0.9.2/css/bulma-rtl.css':[
24 | 1776,
25 | ],
26 | 'project:projects/bulma-0.9.2/css/bulma.css':[
27 | 1776,
28 | ],
29 | 'project:projects/bulma-0.9.2/docs/css/bulma-docs.css':[
30 | 1777,
31 | 13114,
32 | 13116,
33 | 13118,
34 | 15810,
35 | 15813,
36 | 15816,
37 | 15817,
38 | ],
39 | }
40 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4661.html:
--------------------------------------------------------------------------------
1 | The W3C specifications define the valid media features. Only the official and browser-specific media features should be used to get the expected
2 | impact in the final rendering.
3 | Noncompliant Code Example
4 |
5 | @media screen and (unknown: 1000px) { .. }
6 |
7 | Compliant Solution
8 |
9 | @media screen and (width: 1000px) { .. }
10 |
11 | See
12 |
15 |
16 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4666.html:
--------------------------------------------------------------------------------
1 | Duplication of selectors might indicate a copy-paste mistake. The rule detects the following kinds of duplications:
2 |
3 | within a list of selectors in a single rule set
4 | for duplicated selectors in different rule sets within a single stylesheet.
5 |
6 | Noncompliant Code Example
7 |
8 | .foo, .bar, .foo { ... } /* Noncompliant */
9 |
10 | .class1 { ... }
11 | .class1 { ... } /* Noncompliant */
12 |
13 | Compliant Solution
14 |
15 | .foo, .bar { ... }
16 |
17 | .class1 { ... }
18 | .class2 { ... }
19 |
20 |
21 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4656.html:
--------------------------------------------------------------------------------
1 | CSS allows duplicate property names but only the last instance of a duplicated name determines the actual value that will be used for it.
2 | Therefore, changing values of other occurrences of a duplicated name will have no effect and may cause misunderstandings and bugs.
3 | This rule ignores $sass, @less, and var(--custom-property) variable syntaxes.
4 | Noncompliant Code Example
5 |
6 | a {
7 | color: pink;
8 | background: orange;
9 | color: orange
10 | }
11 |
12 | Compliant Solution
13 |
14 | a {
15 | color: pink;
16 | background: orange
17 | }
18 |
19 |
20 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4648.html:
--------------------------------------------------------------------------------
1 | Having duplicated font names doesn't help to read the font declaration and may be an indicator the author of the line was not sure how to configure
2 | it. This rule raises an issue when font or font-family properties contain a duplicated font name. This rule ignores
3 | $sass, @less, and var(--custom-property) variable syntaxes.
4 | Noncompliant Code Example
5 |
6 | a {
7 | font-family: 'Georgia', Georgia, serif; /* Noncompliant; 'Georgia' is duplicated */
8 | }
9 |
10 | Compliant Solution
11 |
12 | a {
13 | font-family: Georgia, serif;
14 | }
15 |
16 |
17 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4653.html:
--------------------------------------------------------------------------------
1 | The W3C specifications define the units that can be used with lengths. A unit that is not part of the list of supported ones is likely
2 | to be a typo and will be seen as a UI bug by the user.
3 | This rule raises an issue each time a unit is not officially supported.
4 | Noncompliant Code Example
5 |
6 | a {
7 | width: 10pixels; /* Noncompliant; "pixels" is not a valid unit */
8 | }
9 |
10 | Compliant Solution
11 |
12 | a {
13 | width: 10px;
14 | }
15 |
16 | See
17 |
20 |
21 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4654.html:
--------------------------------------------------------------------------------
1 | The W3C specifications define the valid CSS properties. Only the official and browser-specific properties should be used to get the expected impact
2 | in the final rendering.
3 | This rule ignores:
4 |
5 | $sass, @less, and var(--custom-property) variable syntaxes.
6 | vendor-prefixed properties (e.g., -moz-align-self, -webkit-align-self).
7 |
8 | Noncompliant Code Example
9 |
10 | a {
11 | colour: blue; /* Noncompliant; colour is not part of the specifications */
12 | }
13 |
14 | Compliant Solution
15 |
16 | a {
17 | color: blue;
18 | }
19 |
20 |
21 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4650.html:
--------------------------------------------------------------------------------
1 | calc is a CSS3 function that provides the possibility to do simple math in CSS (add, subtract, divide, multiply). Without spaces
2 | around operators, calc will have no effect.
3 | More precisely, before an operator, there must be a single whitespace or a newline plus indentation. After an operator, there must be a single
4 | whitespace or a newline.
5 | Noncompliant Code Example
6 |
7 | #div1 {
8 | position: absolute;
9 | width: calc(100%- 100px); /* Noncompliant; no space after the % sign */
10 | }
11 |
12 | Compliant Solution
13 |
14 | #div1 {
15 | position: absolute;
16 | width: calc(100% - 100px);
17 | }
18 |
19 |
20 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/mock-start-server/failedClose.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const http = require('http');
4 | const port = process.argv[2];
5 |
6 | const requestHandler = (request, response) => {
7 | let data = [];
8 | request.on('data', chunk => {
9 | data.push(chunk);
10 | });
11 | if (request.url === '/status') {
12 | response.writeHead(200, {'Content-Type': 'text/plain'});
13 | response.end('OK!');
14 | } else {
15 | throw "Failure";
16 | }
17 | };
18 |
19 | const server = http.createServer(requestHandler);
20 |
21 | server.listen(port, (err) => {
22 | if (err) {
23 | return console.log('something bad happened', err)
24 | }
25 |
26 | console.log(`server is listening on ${port}`)
27 | });
28 |
29 |
--------------------------------------------------------------------------------
/wss-unified-agent.config:
--------------------------------------------------------------------------------
1 | # WhiteSource documentation https://whitesource.atlassian.net/wiki/spaces/WD/pages/1544880156/Unified+Agent+Configuration+Parameters
2 |
3 | excludes=**/*sources.jar **/*javadoc.jar **/its/sources/** **/its/plugin/projects/**
4 | fileSystemScan=False
5 | resolveAllDependencies=False
6 |
7 | maven.aggregateModules=True
8 | maven.downloadMissingDependencies=False
9 | maven.m2RepositoryPath=.m2/repository
10 | maven.resolveDependencies=True
11 | maven.runPreStep=False
12 |
13 | npm.includeDevDependencies=True
14 | npm.resolveDependencies=True
15 | npm.resolveLockFile=False
16 | npm.runPreStep=False
17 | npm.yarnProject=True
18 |
19 | wss.url=https://saas-eu.whitesourcesoftware.com/agent
20 |
21 | forceUpdate=true
22 | checkPolicies=true
23 | forceUpdate.failBuildOnPolicyViolation=true
24 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/node_modules/run-node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "run-node",
3 | "version": "1.0.0",
4 | "description": "Run the Node.js binary no matter what",
5 | "license": "MIT",
6 | "repository": "sindresorhus/run-node",
7 | "author": {
8 | "name": "Sindre Sorhus",
9 | "email": "sindresorhus@gmail.com",
10 | "url": "sindresorhus.com"
11 | },
12 | "bin": "run-node",
13 | "engines": {
14 | "node": ">=4"
15 | },
16 | "scripts": {
17 | "test": "./run-node --version"
18 | },
19 | "files": [
20 | "run-node"
21 | ],
22 | "keywords": [
23 | "run",
24 | "node",
25 | "nodejs",
26 | "node.js",
27 | "find",
28 | "binary",
29 | "bin",
30 | "execute",
31 | "which",
32 | "detect",
33 | "path",
34 | "env",
35 | "bash",
36 | "shell",
37 | "sh"
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ---- Mac OS X
2 | .DS_Store
3 | Icon?
4 | # Thumbnails
5 | ._*
6 | # Files that might appear on external disk
7 | .Spotlight-V100
8 | .Trashes
9 |
10 | # ---- Windows
11 | # Windows image file caches
12 | Thumbs.db
13 | # Folder config file
14 | Desktop.ini
15 |
16 | # ---- IntelliJ IDEA
17 | *.iws
18 | *.iml
19 | *.ipr
20 | .idea/
21 | out/
22 |
23 | # ---- Eclipse
24 | .project
25 | .settings/
26 | .classpath
27 |
28 | # --- SonarQube
29 | .sonar/
30 | .sonarlint/
31 | .scannerwork/
32 |
33 | # --- Gradle
34 | .gradle/
35 | build/
36 |
37 | # --- Maven and Orchestrator
38 | target/
39 |
40 | # npm
41 | node_modules/
42 |
43 | # Visual Studio
44 | .vs/
45 |
46 | # CSS-bundle
47 | sonar-css-plugin/css-bundle/test-report.xml
48 | sonar-css-plugin/css-bundle/coverage/
49 | sonar-css-plugin/css-bundle/lib/
50 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4662.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:projects/tailwindcss-2.0.3/__tests__/fixtures/tailwind-input-import.css':[
3 | 7,
4 | ],
5 | 'project:projects/tailwindcss-2.0.3/__tests__/fixtures/tailwind-input-with-explicit-screen-utilities.css':[
6 | 1,
7 | 7,
8 | ],
9 | 'project:projects/tailwindcss-2.0.3/__tests__/fixtures/tailwind-input.css':[
10 | 1,
11 | 3,
12 | 5,
13 | 7,
14 | ],
15 | 'project:projects/tailwindcss-2.0.3/base.css':[
16 | 1,
17 | ],
18 | 'project:projects/tailwindcss-2.0.3/components.css':[
19 | 1,
20 | ],
21 | 'project:projects/tailwindcss-2.0.3/perf/fixture.css':[
22 | 1,
23 | 3,
24 | 5,
25 | ],
26 | 'project:projects/tailwindcss-2.0.3/screens.css':[
27 | 1,
28 | ],
29 | 'project:projects/tailwindcss-2.0.3/tailwind.css':[
30 | 1,
31 | 3,
32 | 5,
33 | ],
34 | 'project:projects/tailwindcss-2.0.3/utilities.css':[
35 | 1,
36 | ],
37 | }
38 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4664.html:
--------------------------------------------------------------------------------
1 | Order of instructions in CSS is important: instructions with equal specificity that occur later in the file take the priority. But when a selector
2 | with a higher specificity (e.g. p a { color: green;}) comes before the selector it overrides (e.g.: a { color: green;}), the
3 | priority is given to the first one. Even if it works properly, this is harder to anticipate the behaviour of the stylesheet while reading as it goes
4 | against the principle that the last instruction takes the priority.
5 | Noncompliant Code Example
6 |
7 | p a {
8 | color: green;
9 | }
10 |
11 | a {
12 | color: blue;
13 | }
14 |
15 | Compliant Solution
16 |
17 | a {
18 | color: blue;
19 | }
20 |
21 | p a {
22 | color: green;
23 | }
24 |
25 |
26 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4655.html:
--------------------------------------------------------------------------------
1 | !important within keyframes declarations is completely ignored in some browsers and therefore it should not be used to be consistent
2 | among all browsers.
3 | Noncompliant Code Example
4 |
5 | @keyframes kf {
6 | from { margin-top: 50px; }
7 | 50% { margin-top: 150px !important; } /* Noncompliant; ignored */
8 | to { margin-top: 100px; }
9 | }
10 |
11 | Compliant Solution
12 |
13 | @keyframes kf {
14 | from { margin-top: 50px; }
15 | 50% { margin-top: 150px; }
16 | to { margin-top: 100px; }
17 | }
18 |
19 | See
20 |
24 |
25 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/tests/utils.ts:
--------------------------------------------------------------------------------
1 | import * as http from "http";
2 | import { Server } from "http";
3 | import { AddressInfo } from "net";
4 |
5 | export function postToServer(
6 | data: string,
7 | endpoint: string,
8 | server: Server
9 | ): Promise {
10 | const options = {
11 | host: "localhost",
12 | port: (server.address()).port,
13 | path: endpoint,
14 | method: "POST",
15 | headers: {
16 | "Content-Type": "application/json"
17 | }
18 | };
19 |
20 | return new Promise((resolve, reject) => {
21 | let response = "";
22 |
23 | const req = http.request(options, res => {
24 | res.on("data", chunk => {
25 | response += chunk;
26 | });
27 |
28 | res.on("end", () => resolve(response));
29 | });
30 |
31 | req.on("error", reject);
32 |
33 | req.write(data);
34 | req.end();
35 | });
36 | }
37 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4652.html:
--------------------------------------------------------------------------------
1 | According to the W3C specifications:
2 |
3 | A string cannot directly contain a newline. To include a newline in a string, use an escape representing the line feed character in ISO-10646
4 | (U+000A), such as "\A" or "\00000a".
5 | [...]
6 | It is possible to break strings over several lines, for aesthetic or other reasons, but in such a case the newline itself has to be escaped with
7 | a backslash (\).
8 |
9 | Noncompliant Code Example
10 |
11 | a {
12 | content: "first
13 | second";
14 | }
15 |
16 | Compliant Solution
17 |
18 | a {
19 | content: "first\Asecond";
20 | }
21 |
22 | See
23 |
26 |
27 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S1116.html:
--------------------------------------------------------------------------------
1 | Extra semicolons are usually introduced by mistake, for example because:
2 |
3 | It was meant to be replaced by one more property declaration, but this was forgotten.
4 | There was a typo which lead the semicolon to be doubled, i.e. ;;.
5 |
6 | See
7 |
8 | CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
9 |
10 | CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while
11 | condition
12 | CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while
13 | statement
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/sonarcss-assembly.xml:
--------------------------------------------------------------------------------
1 |
4 | sonarcss-assembly
5 |
6 | zip
7 |
8 | false
9 |
10 |
11 | css-bundle
12 |
13 | lib/**/*
14 |
15 | package/**/*
16 | bin/**/*
17 | node_modules/**/*
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4657.html:
--------------------------------------------------------------------------------
1 | A shorthand property defined after a longhand property will completely override the value defined in the longhand property making the longhand one
2 | useless. The code should be refactored to consider the longhand property or to remove it completely.
3 | Noncompliant Code Example
4 |
5 | a {
6 | padding-left: 10px;
7 | padding: 20px; /* Noncompliant; padding is overriding padding-left making it useless */
8 | }
9 |
10 | Compliant Solution
11 |
12 | a {
13 | padding: 10px; /* Compliant; padding is defining a general behaviour and padding-left, just after, is precising the left case */
14 | padding-left: 20px;
15 | }
16 |
17 | See
18 |
22 |
23 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/cssModules.css:
--------------------------------------------------------------------------------
1 | /* Adding one standard issue to make sure we analyze this file */
2 | @unknown { /* S4662 | at-rule-no-unknown */
3 | width: 1px;
4 | }
5 |
6 | /* ignored by S4662 | at-rule-no-unknown */
7 | @value colors: "./colors.css";
8 | @value blue, red, green from colors;
9 |
10 | .className {
11 | color: green;
12 | background: red;
13 | }
14 | .otherClassName {
15 | /* ignored by S4654 | property-no-unknown */
16 | composes: className;
17 | color: yellow;
18 | }
19 |
20 | /* ignored by S4659 | selector-pseudo-class-no-unknown */
21 | :export {
22 | /* ignored by S4654 | property-no-unknown */
23 | exportedKey: exportedValue;
24 | /* ... */
25 | }
26 |
27 | /* ignored by S4659 | selector-pseudo-class-no-unknown */
28 | :import("path/to/dep.css") {
29 | /* ignored by S4654 | property-no-unknown */
30 | localAlias: keyFromDep;
31 | /* ... */
32 | }
33 |
--------------------------------------------------------------------------------
/.cirrus/nodejs-10.Dockerfile:
--------------------------------------------------------------------------------
1 | ARG CIRRUS_AWS_ACCOUNT=275878209202
2 | FROM ${CIRRUS_AWS_ACCOUNT}.dkr.ecr.eu-central-1.amazonaws.com/base:j11-latest
3 |
4 | USER root
5 |
6 | ENV NODE_VERSION v10.23.2
7 |
8 | RUN wget -U "nodejs" -q -O nodejs.tar.gz https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-x64.tar.gz \
9 | && tar -xzf "nodejs.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \
10 | && rm nodejs.tar.gz \
11 | && ln -s /usr/local/bin/node /usr/local/bin/nodejs
12 |
13 | ENV YARN_VERSION 1.22.5
14 |
15 | RUN curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
16 | && mkdir -p /opt \
17 | && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \
18 | && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \
19 | && ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \
20 | && rm yarn-v$YARN_VERSION.tar.gz
21 |
22 |
23 | USER sonarsource
24 |
--------------------------------------------------------------------------------
/.cirrus/nodejs-10.jdk17.Dockerfile:
--------------------------------------------------------------------------------
1 | ARG CIRRUS_AWS_ACCOUNT=275878209202
2 | FROM ${CIRRUS_AWS_ACCOUNT}.dkr.ecr.eu-central-1.amazonaws.com/base:j17-latest
3 |
4 | USER root
5 |
6 | ENV NODE_VERSION v10.23.2
7 |
8 | RUN wget -U "nodejs" -q -O nodejs.tar.gz https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-x64.tar.gz \
9 | && tar -xzf "nodejs.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \
10 | && rm nodejs.tar.gz \
11 | && ln -s /usr/local/bin/node /usr/local/bin/nodejs
12 |
13 | ENV YARN_VERSION 1.22.5
14 |
15 | RUN curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
16 | && mkdir -p /opt \
17 | && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \
18 | && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \
19 | && ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \
20 | && rm yarn-v$YARN_VERSION.tar.gz
21 |
22 |
23 | USER sonarsource
24 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S5362.html:
--------------------------------------------------------------------------------
1 | To perform calculations when specifying a CSS property calc() function can be used. This function takes single expression as
2 | parameter. When writing this expression some rules must be respected:
3 |
4 | no empty calc()
5 | there should be an operator between the arguments, spacing should be respected
6 | there should not be any division by zero
7 | the resolved type should be valid for where the expression is placed
8 |
9 | Otherwise calc() function will be invalid and the entire rule using it will be ignored.
10 | Noncompliant Code Example
11 |
12 | .btn {
13 | border: solid black 1px;
14 | width: calc(100% 80px); /* Noncompliant */
15 | }
16 |
17 | Compliant Solution
18 |
19 | .btn {
20 | border: solid black 1px;
21 | width: calc(100% - 80px);
22 | }
23 |
24 |
25 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | @javax.annotation.ParametersAreNonnullByDefault
21 | package org.sonar.css.plugin;
22 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | @javax.annotation.ParametersAreNonnullByDefault
21 | package org.sonar.css.plugin.rules;
22 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/server/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | @javax.annotation.ParametersAreNonnullByDefault
21 | package org.sonar.css.plugin.server;
22 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/static/documentation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: CSS
3 | key: css
4 | ---
5 |
6 |
7 |
8 |
9 |
10 |
11 | ## Prerequisites
12 | In order to analyze CSS code, you need to have Node.js >= 8 installed on the machine running the scan. Set property `sonar.nodejs.executable` to an absolute path to Node.js executable, if standard `node` is not available.
13 |
14 | If you have a community plugin that handles CSS installed on your SonarQube instance it will conflict with analysis of CSS, so it should be removed.
15 |
16 | ## Language-Specific Properties
17 |
18 | Discover and update the CSS-specific [properties](/analysis/analysis-parameters/) in: Project **[Administration > General Settings > CSS](/#sonarqube-admin#/admin/settings?category=css)**
19 |
20 | ## Supported Languages
21 | * CSS, SCSS, Less
22 | * Also 'style' inside PHP, HTML and VueJS files
23 |
24 | ## Related Pages
25 | * [Importing External Issues](/analysis/external-issues/) (StyleLint.io)
26 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-bundle",
3 | "version": "1.0.0",
4 | "description": "Simple node project to run stylelint",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "yarn install && yarn check-format && yarn clear && yarn compile",
8 | "prepare-package": "rm -rf node_modules && yarn install --prod",
9 | "clear": "tsc -b . --clean",
10 | "compile": "tsc -b .",
11 | "check-format": "prettier --list-different \"{src,tests}/**/*.ts\"",
12 | "format": "prettier --write \"{src,tests}/**/*.ts\"",
13 | "test": "jest"
14 | },
15 | "author": "",
16 | "license": "LGPL-3.0",
17 | "dependencies": {
18 | "express": "4.17.1",
19 | "stylelint": "13.10.0",
20 | "body-parser": "1.19.0"
21 | },
22 | "devDependencies": {
23 | "@types/express": "4.17.2",
24 | "@types/jest": "26.0.14",
25 | "@types/stylelint": "9.10.1",
26 | "jest": "26.4.2",
27 | "jest-sonar-reporter": "1.3.0",
28 | "prettier": "1.19.1",
29 | "ts-jest": "26.4.1",
30 | "typescript": "4.0.3"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/server/bundle/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | @javax.annotation.ParametersAreNonnullByDefault
21 | package org.sonar.css.plugin.server.bundle;
22 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4649.html:
--------------------------------------------------------------------------------
1 | If none of the font names defined in a font or font-family declaration are available on the browser of the user, the
2 | browser will display the text using its default font. It's recommended to always define a generic font family for each declaration of
3 | font or font-family to get a less degraded situation than relying on the default browser font. All browsers should implement
4 | a list of generic font matching these families: Serif, Sans-serif, cursive, fantasy,
5 | Monospace.
6 | Noncompliant Code Example
7 |
8 | a {
9 | font-family: Helvetica, Arial, Verdana, Tahoma; /* Noncompliant; there is no generic font family in the list */
10 | }
11 |
12 | Compliant Solution
13 |
14 | a {
15 | font-family: Helvetica, Arial, Verdana, Tahoma, sans-serif;
16 | }
17 |
18 | See
19 |
22 |
23 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/node_modules/run-node/license:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Sindre Sorhus (sindresorhus.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4647.html:
--------------------------------------------------------------------------------
1 | An invalid color definition will by default be interpreted as black, which is likely to have unintended impacts on the expected look and feel of
2 | the website.
3 | This rule raises an issue when a color definition (color, background-color) is not valid. The color definition is
4 | considered valid when it is made of hexadecimal characters:
5 |
6 | longhand: 6 or 8 characters (when alpha is defined)
7 | shorthand variant: 3 or 4 characters (when alpha is defined)
8 |
9 | Noncompliant Code Example
10 |
11 | a {
12 | color: #3c; /* Noncompliant; shorthand should be made of 3 characters */
13 | }
14 | div {
15 | background-color: #3cb371a; /* Noncompliant; alpha should have 2 characters */
16 | }
17 |
18 | Compliant Solution
19 |
20 | a {
21 | color: #3cc;
22 | }
23 | div {
24 | background-color: #3cb371ac;
25 | }
26 |
27 | See
28 |
31 |
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/BlockNoEmpty.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4658")
25 | public class BlockNoEmpty implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "block-no-empty";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/NoEmptySource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4667")
25 | public class NoEmptySource implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "no-empty-source";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/CommentNoEmpty.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4663")
25 | public class CommentNoEmpty implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "comment-no-empty";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/StringNoNewline.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4652")
25 | public class StringNoNewline implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "string-no-newline";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/node_modules/run-node/run-node:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # MIT License © Sindre Sorhus
3 |
4 | if [[ -z $RUN_NODE_CACHE_PATH ]]; then
5 | PATH_CACHE="$HOME"/.node_path
6 | else
7 | PATH_CACHE="$RUN_NODE_CACHE_PATH"
8 | fi
9 |
10 | get_user_path() {
11 | [[ -x "/usr/libexec/path_helper" ]] && eval $(/usr/libexec/path_helper -s)
12 | echo "$($SHELL -i -l -c 'echo -e "\n"PATH=\"$PATH:\$PATH\""\n"' 2>/dev/null | grep "^PATH=")" > "$PATH_CACHE"
13 | }
14 |
15 | set_path() {
16 | if [[ -f "$PATH_CACHE" ]]; then
17 | . "$PATH_CACHE"
18 | else
19 | get_user_path
20 | . "$PATH_CACHE"
21 | fi
22 |
23 | export PATH
24 | }
25 |
26 | has_node() {
27 | command -v node >/dev/null 2>&1
28 | }
29 |
30 | # Check if we have node, otherwise inherit path from user shell
31 | if ! has_node; then
32 | set_path
33 |
34 | # Retry by deleting old path cache
35 | if ! has_node; then
36 | rm "$PATH_CACHE"
37 | set_path
38 | fi
39 | fi
40 |
41 | if has_node; then
42 | node "$@"
43 | else
44 | if [[ -z $RUN_NODE_ERROR_MSG ]]; then
45 | echo "Couldn't find the Node.js binary. Ensure you have Node.js installed. Open an issue on https://github.com/sindresorhus/run-node"
46 | else
47 | echo "$RUN_NODE_ERROR_MSG"
48 | fi
49 | fi
50 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/ColorNoInvalidHex.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4647")
25 | public class ColorNoInvalidHex implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "color-no-invalid-hex";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/NoExtraSemicolons.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S1116")
25 | public class NoExtraSemicolons implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "no-extra-semicolons";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/CssRule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import java.util.Collections;
23 | import java.util.List;
24 |
25 | public interface CssRule {
26 |
27 | String stylelintKey();
28 |
29 | default List stylelintOptions() {
30 | return Collections.emptyList();
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/NoDuplicateSelectors.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4666")
25 | public class NoDuplicateSelectors implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "no-duplicate-selectors";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/FunctionCalcNoInvalid.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S5362")
25 | public class FunctionCalcNoInvalid implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "function-calc-no-invalid";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/NoDescendingSpecificity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4664")
25 | public class NoDescendingSpecificity implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "no-descending-specificity";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/NoDuplicateAtImportRules.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S1128")
25 | public class NoDuplicateAtImportRules implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "no-duplicate-at-import-rules";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/FontFamilyNoDuplicateNames.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4648")
25 | public class FontFamilyNoDuplicateNames implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "font-family-no-duplicate-names";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/MediaFeatureNameNoUnknown.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4661")
25 | public class MediaFeatureNameNoUnknown implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "media-feature-name-no-unknown";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/NoInvalidDoubleSlashComments.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4668")
25 | public class NoInvalidDoubleSlashComments implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "no-invalid-double-slash-comments";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/FunctionCalcNoUnspacedOperator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4650")
25 | public class FunctionCalcNoUnspacedOperator implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "function-calc-no-unspaced-operator";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/KeyframeDeclarationNoImportant.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4655")
25 | public class KeyframeDeclarationNoImportant implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "keyframe-declaration-no-important";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/StylelintReport.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | public class StylelintReport {
23 |
24 | private StylelintReport(){
25 | }
26 |
27 | static class IssuesPerFile {
28 | String source;
29 | Issue[] warnings;
30 | }
31 |
32 | static class Issue {
33 | int line;
34 | String rule;
35 | String text;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/FontFamilyNoMissingGenericFamilyKeyword.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4649")
25 | public class FontFamilyNoMissingGenericFamilyKeyword implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "font-family-no-missing-generic-family-keyword";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/DeclarationBlockNoShorthandPropertyOverrides.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4657")
25 | public class DeclarationBlockNoShorthandPropertyOverrides implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "declaration-block-no-shorthand-property-overrides";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/FunctionLinearGradientNoNonstandardDirection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | @Rule(key = "S4651")
25 | public class FunctionLinearGradientNoNonstandardDirection implements CssRule {
26 |
27 | @Override
28 | public String stylelintKey() {
29 | return "function-linear-gradient-no-nonstandard-direction";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/its/ruling/src/test/resources/expected/css-S4666.json:
--------------------------------------------------------------------------------
1 | {
2 | 'project:projects/animate.css-4.1.1/docs/style.css':[
3 | 598,
4 | 602,
5 | ],
6 | 'project:projects/bulma-0.9.2/css/bulma-rtl.css':[
7 | 304,
8 | ],
9 | 'project:projects/bulma-0.9.2/css/bulma.css':[
10 | 304,
11 | ],
12 | 'project:projects/bulma-0.9.2/docs/css/bulma-docs.css':[
13 | 305,
14 | 12108,
15 | 12114,
16 | 13821,
17 | 14283,
18 | 14354,
19 | 15992,
20 | 16007,
21 | 16014,
22 | 16029,
23 | 16034,
24 | 16085,
25 | 16090,
26 | 16095,
27 | 16175,
28 | 16182,
29 | 16189,
30 | 16258,
31 | 16265,
32 | ],
33 | 'project:projects/normalize.css-8.0.1/test.html':[
34 | 50,
35 | ],
36 | 'project:projects/tailwindcss-2.0.3/__tests__/fixtures/tailwind-output-flagged.css':[
37 | 56,
38 | 366,
39 | 376,
40 | 420,
41 | 453,
42 | 485,
43 | 502,
44 | 19542,
45 | ],
46 | 'project:projects/tailwindcss-2.0.3/__tests__/fixtures/tailwind-output-important.css':[
47 | 56,
48 | 366,
49 | 376,
50 | 420,
51 | 453,
52 | 485,
53 | 502,
54 | 19542,
55 | ],
56 | 'project:projects/tailwindcss-2.0.3/__tests__/fixtures/tailwind-output-no-color-opacity.css':[
57 | 56,
58 | 366,
59 | 376,
60 | 420,
61 | 453,
62 | 485,
63 | 502,
64 | 17696,
65 | ],
66 | 'project:projects/tailwindcss-2.0.3/__tests__/fixtures/tailwind-output.css':[
67 | 56,
68 | 366,
69 | 376,
70 | 420,
71 | 453,
72 | 485,
73 | 502,
74 | 19542,
75 | ],
76 | }
77 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/server/NetUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.server;
21 |
22 | import java.io.IOException;
23 | import java.net.ServerSocket;
24 |
25 | public class NetUtils {
26 |
27 | private NetUtils() {
28 | }
29 |
30 | public static int findOpenPort() throws IOException {
31 | try (ServerSocket socket = new ServerSocket(0)) {
32 | return socket.getLocalPort();
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/server/bundle/Bundle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.server.bundle;
21 |
22 | import java.nio.file.Path;
23 | import org.sonarsource.nodejs.BundlePathResolver;
24 |
25 | public interface Bundle extends BundlePathResolver {
26 |
27 | void deploy(Path deployLocation);
28 |
29 | /**
30 | * should be called after deploy(Path deployLocation)
31 | */
32 | String startServerScript();
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4651.html:
--------------------------------------------------------------------------------
1 | linear-gradient was standardized with CSS3. Before that, it was possible to use different non-standard values to define the gradient's
2 | direction. Because these values are not standard, they are not supported in all browsers and therefore they should no longer be used in order to get
3 | the expected gradient in the latest browser versions that support CSS3.
4 | This rule raises an issue when the first parameter of a linear-gradient is not a valid <side-or-corner> or
5 | angle.
6 | Noncompliant Code Example
7 |
8 | .foo {
9 | background: -webkit-linear-gradient(to top, #fff, #000);
10 | background: linear-gradient(top, #fff, #000);
11 | }
12 |
13 | .bar {
14 | background: linear-gradient(45, #fff, #000);
15 | }
16 |
17 | Compliant Solution
18 |
19 | .foo {
20 | background: -webkit-linear-gradient(top, #fff, #000);
21 | background: linear-gradient(to top, #fff, #000);
22 | }
23 |
24 | .bar {
25 | background: linear-gradient(45deg, #fff, #000);
26 | }
27 |
28 | See
29 |
33 |
34 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/RuleUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import java.util.Arrays;
23 | import java.util.List;
24 | import java.util.stream.Collectors;
25 |
26 | public class RuleUtils {
27 |
28 | private RuleUtils(){
29 | }
30 |
31 | public static List splitAndTrim(String parameterValue) {
32 | String[] split = parameterValue.split(",");
33 | return Arrays.stream(split).map(String::trim).collect(Collectors.toList());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/server/NetUtilsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.server;
21 |
22 | import java.io.IOException;
23 | import org.junit.Test;
24 |
25 | import static org.assertj.core.api.Assertions.assertThat;
26 |
27 | public class NetUtilsTest {
28 |
29 | @Test
30 | public void findOpenPort_should_not_return_zero() throws IOException {
31 | assertThat(NetUtils.findOpenPort())
32 | .isGreaterThan(0)
33 | .isLessThanOrEqualTo(65535);
34 | }
35 |
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/its/ruling/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | its
7 | org.sonarsource.css
8 | 1.4.3-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | ruling
13 |
14 |
15 |
16 |
17 | org.sonarsource.orchestrator
18 | sonar-orchestrator
19 |
20 |
21 | org.sonarsource.sonarqube
22 | sonar-ws
23 | ${sonar.version}
24 | test
25 |
26 |
27 | junit
28 | junit
29 |
30 |
31 | org.assertj
32 | assertj-core
33 |
34 |
35 | org.sonarsource.css
36 | sonar-css-plugin
37 | ${version}
38 | test
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssLanguage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.sonar.api.config.Configuration;
23 | import org.sonar.api.resources.AbstractLanguage;
24 |
25 | public class CssLanguage extends AbstractLanguage {
26 |
27 | public static final String KEY = "css";
28 |
29 | private Configuration configuration;
30 |
31 | public CssLanguage(Configuration configuration) {
32 | super(KEY, "CSS");
33 | this.configuration = configuration;
34 | }
35 |
36 | @Override
37 | public String[] getFileSuffixes() {
38 | return configuration.getStringArray(CssPlugin.FILE_SUFFIXES_KEY);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/UnitNoUnknown.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import java.util.Arrays;
23 | import java.util.List;
24 | import org.sonar.check.Rule;
25 |
26 | @Rule(key = "S4653")
27 | public class UnitNoUnknown implements CssRule {
28 |
29 | @Override
30 | public String stylelintKey() {
31 | return "unit-no-unknown";
32 | }
33 |
34 | @Override
35 | public List stylelintOptions() {
36 | return Arrays.asList(true, new StylelintIgnoreOption());
37 | }
38 |
39 | private static class StylelintIgnoreOption {
40 | // Used by GSON serialization
41 | private final String[] ignoreUnits = {"x"};
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/metrics/CssTokenType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.metrics;
21 |
22 | import com.sonar.sslr.api.AstNode;
23 | import com.sonar.sslr.api.TokenType;
24 |
25 | public enum CssTokenType implements TokenType {
26 | COMMENT,
27 | PUNCTUATOR,
28 | NUMBER,
29 | STRING,
30 | AT_IDENTIFIER,
31 | HASH_IDENTIFIER,
32 | DOLLAR_IDENTIFIER,
33 | IDENTIFIER;
34 |
35 | @Override
36 | public String getName() {
37 | return name();
38 | }
39 |
40 | @Override
41 | public String getValue() {
42 | return name();
43 | }
44 |
45 | @Override
46 | public boolean hasToBeSkippedFromAst(AstNode node) {
47 | return false;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/metrics/Tokenizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.metrics;
21 |
22 | import com.sonar.sslr.api.Token;
23 | import java.util.ArrayList;
24 | import java.util.List;
25 | import java.util.stream.Collectors;
26 |
27 | public class Tokenizer {
28 |
29 | public List tokenize(String css) {
30 | List tokenList = CssLexer.create().lex(css);
31 |
32 | // remove last token (EOF token)
33 | List cloneTokenList = new ArrayList<>(tokenList);
34 | cloneTokenList.remove(cloneTokenList.size() - 1);
35 |
36 | return cloneTokenList.stream().map(CssToken::new).collect(Collectors.toList());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/its/plugin/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | its
7 | org.sonarsource.css
8 | 1.4.3-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | plugin
13 |
14 |
15 |
16 |
17 | maven-surefire-plugin
18 |
19 |
20 | **/Tests.java
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | org.sonarsource.orchestrator
30 | sonar-orchestrator
31 |
32 |
33 | org.sonarsource.sonarqube
34 | sonar-ws
35 | ${sonar.version}
36 | test
37 |
38 |
39 | org.assertj
40 | assertj-core
41 |
42 |
43 | org.sonarsource.css
44 | sonar-css-plugin
45 | ${version}
46 | test
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssLanguageTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.junit.Test;
23 | import org.sonar.api.config.internal.MapSettings;
24 |
25 | import static org.assertj.core.api.Assertions.assertThat;
26 |
27 | public class CssLanguageTest {
28 |
29 | @Test
30 | public void test() {
31 | MapSettings settings = new MapSettings();
32 | settings.setProperty(CssPlugin.FILE_SUFFIXES_KEY, CssPlugin.FILE_SUFFIXES_DEFVALUE);
33 | CssLanguage language = new CssLanguage(settings.asConfig());
34 | assertThat(language.getKey()).isEqualTo("css");
35 | assertThat(language.getName()).isEqualTo("CSS");
36 | assertThat(language.getFileSuffixes()).containsOnly(".css", ".less", ".scss");
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/its/plugin/projects/external-report-project/report.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "source": "src/file1.css",
4 | "deprecations": [],
5 | "invalidOptionWarnings": [],
6 | "parseErrors": [],
7 | "errored": true,
8 | "warnings": [
9 | {
10 | "line": 111,
11 | "column": 1,
12 | "rule": "no-missing-end-of-source-newline",
13 | "severity": "error",
14 | "text": "Unexpected missing end-of-source newline (no-missing-end-of-source-newline)"
15 | },
16 | {
17 | "line": 81,
18 | "column": 1,
19 | "rule": "rule-empty-line-before",
20 | "severity": "error",
21 | "text": "Expected empty line before rule (rule-empty-line-before)"
22 | },
23 | {
24 | "line": 55,
25 | "column": 20,
26 | "rule": "selector-pseudo-element-colon-notation",
27 | "severity": "error",
28 | "text": "Expected double colon pseudo-element notation (selector-pseudo-element-colon-notation)"
29 | }
30 | ]
31 | },
32 | {
33 | "source": "src/file2.css",
34 | "deprecations": [],
35 | "invalidOptionWarnings": [],
36 | "parseErrors": [],
37 | "errored": true,
38 | "warnings": [
39 | {
40 | "line": 58,
41 | "column": 28,
42 | "rule": "block-no-empty",
43 | "severity": "error",
44 | "text": "Unexpected empty block (block-no-empty)"
45 | },
46 | {
47 | "line": 114,
48 | "column": 1,
49 | "rule": "no-missing-end-of-source-newline",
50 | "severity": "error",
51 | "text": "Unexpected missing end-of-source newline (no-missing-end-of-source-newline)"
52 | }
53 | ]
54 | }
55 | ]
56 |
--------------------------------------------------------------------------------
/its/plugin/src/test/java/org/sonar/css/its/MinifiedTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.its;
21 |
22 | import com.sonar.orchestrator.Orchestrator;
23 | import org.junit.BeforeClass;
24 | import org.junit.ClassRule;
25 | import org.junit.Test;
26 |
27 | import static org.assertj.core.api.Assertions.assertThat;
28 | import static org.sonar.css.its.Tests.getProjectMeasureAsDouble;
29 |
30 | public class MinifiedTest {
31 |
32 | private static String PROJECT_KEY = "minified-project";
33 |
34 | @ClassRule
35 | public static Orchestrator orchestrator = Tests.ORCHESTRATOR;
36 |
37 | @BeforeClass
38 | public static void prepare() {
39 | orchestrator.executeBuild(Tests.createScanner(PROJECT_KEY));
40 | }
41 |
42 | @Test
43 | public void test() {
44 | assertThat(getProjectMeasureAsDouble("files", PROJECT_KEY)).isEqualTo(1);
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/tests/server-mock-stylelint.test.ts:
--------------------------------------------------------------------------------
1 | import { start, setLogHandlersForTests } from "../src/server";
2 | import { Server } from "http";
3 | import * as path from "path";
4 | import { promisify } from "util";
5 | import * as stylelint from "stylelint";
6 | import { postToServer } from "./utils";
7 |
8 | const filePath = path.join(__dirname, "fixtures", "file.css");
9 |
10 | const request = JSON.stringify({
11 | filePath,
12 | configFile: path.join(__dirname, "fixtures", "stylelintconfig.json")
13 | });
14 |
15 | jest.mock("stylelint");
16 |
17 | describe("server", () => {
18 | let server: Server;
19 | let close: () => Promise;
20 | const logSpy = jest.fn();
21 | const errorSpy = jest.fn();
22 |
23 | beforeAll(async () => {
24 | setLogHandlersForTests(logSpy, errorSpy);
25 | server = await start();
26 | close = promisify(server.close.bind(server));
27 | });
28 |
29 | afterAll(async () => {
30 | jest.restoreAllMocks();
31 | await close();
32 | });
33 |
34 | it("should not return issues for not original file", async () => {
35 | (stylelint.lint as any).mockResolvedValue({
36 | results: [{ source: "foo.bar" }]
37 | });
38 | const response = await postToServer(request, "/analyze", server);
39 | expect(JSON.parse(response)).toEqual([]);
40 | expect(logSpy).toHaveBeenCalledWith(
41 | `DEBUG For file [${filePath}] received issues with [foo.bar] as a source. They will not be reported.`
42 | );
43 | });
44 |
45 | it("should not return issues when failed promise returned", async () => {
46 | (stylelint.lint as any).mockRejectedValue("some reason");
47 | const response = await postToServer(request, "/analyze", server);
48 | expect(JSON.parse(response)).toEqual([]);
49 | expect(errorSpy).toHaveBeenCalledWith("some reason");
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/metrics/CssToken.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.metrics;
21 |
22 | import com.sonar.sslr.api.Token;
23 | import com.sonar.sslr.api.TokenType;
24 | import org.sonarsource.analyzer.commons.TokenLocation;
25 |
26 | public class CssToken {
27 | CssTokenType type;
28 | String text;
29 | Integer startLine;
30 | Integer startColumn;
31 | Integer endLine;
32 | Integer endColumn;
33 |
34 | public CssToken(Token token) {
35 | TokenType tokenType = token.getType();
36 | this.type = (CssTokenType)tokenType;
37 | this.text = token.getValue();
38 |
39 | TokenLocation tokenLocation = new TokenLocation(token.getLine(), token.getColumn(), token.getValue());
40 | this.startLine = tokenLocation.startLine();
41 | this.startColumn = tokenLocation.startLineOffset();
42 | this.endLine = tokenLocation.endLine();
43 | this.endColumn = tokenLocation.endLineOffset();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
23 | import org.sonarsource.analyzer.commons.BuiltInQualityProfileJsonLoader;
24 |
25 | import static org.sonar.css.plugin.CssRulesDefinition.REPOSITORY_KEY;
26 | import static org.sonar.css.plugin.CssRulesDefinition.RESOURCE_FOLDER;
27 |
28 | public class SonarWayProfile implements BuiltInQualityProfilesDefinition {
29 |
30 | public static final String PROFILE_NAME = "Sonar way";
31 | public static final String PROFILE_PATH = RESOURCE_FOLDER + CssRulesDefinition.REPOSITORY_KEY + "/Sonar_way_profile.json";
32 |
33 | @Override
34 | public void define(Context context) {
35 | NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(PROFILE_NAME, CssLanguage.KEY);
36 | BuiltInQualityProfileJsonLoader.load(profile, REPOSITORY_KEY, PROFILE_PATH);
37 | profile.done();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRulesDefinition.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.sonar.api.server.rule.RulesDefinition;
23 | import org.sonarsource.analyzer.commons.RuleMetadataLoader;
24 |
25 | import static org.sonar.css.plugin.SonarWayProfile.PROFILE_PATH;
26 |
27 | public class CssRulesDefinition implements RulesDefinition {
28 |
29 | public static final String REPOSITORY_KEY = "css";
30 | public static final String RULE_REPOSITORY_NAME = "SonarAnalyzer";
31 |
32 | public static final String RESOURCE_FOLDER = "org/sonar/l10n/css/rules/";
33 |
34 | @Override
35 | public void define(Context context) {
36 | NewRepository repository = context
37 | .createRepository(REPOSITORY_KEY, CssLanguage.KEY)
38 | .setName(RULE_REPOSITORY_NAME);
39 |
40 | RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_FOLDER + REPOSITORY_KEY, PROFILE_PATH);
41 | ruleMetadataLoader.addRulesByAnnotatedClass(repository, CssRules.getRuleClasses());
42 | repository.done();
43 |
44 | StylelintReportSensor.getStylelintRuleLoader().createExternalRuleRepository(context);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/SonarWayProfileTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.junit.Test;
23 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInQualityProfile;
24 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.Context;
25 |
26 | import static org.assertj.core.api.Assertions.assertThat;
27 |
28 | public class SonarWayProfileTest {
29 |
30 | @Test
31 | public void should_create_sonar_way_profile() {
32 | SonarWayProfile definition = new SonarWayProfile();
33 | Context context = new Context();
34 | definition.define(context);
35 |
36 | BuiltInQualityProfile profile = context.profile("css", SonarWayProfile.PROFILE_NAME);
37 |
38 | assertThat(profile.language()).isEqualTo(CssLanguage.KEY);
39 | assertThat(profile.name()).isEqualTo(SonarWayProfile.PROFILE_NAME);
40 | assertThat(profile.rules()).extracting("repoKey").containsOnly(CssRulesDefinition.REPOSITORY_KEY);
41 | // org.sonar.css.plugin.rules.FunctionCalcNoUnspacedOperator is not part of SonarWay
42 | assertThat(profile.rules()).extracting("ruleKey").hasSize(CssRules.getRuleClasses().size() - 2);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssPluginTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.junit.Test;
23 | import org.sonar.api.Plugin;
24 | import org.sonar.api.SonarEdition;
25 | import org.sonar.api.SonarQubeSide;
26 | import org.sonar.api.SonarRuntime;
27 | import org.sonar.api.internal.SonarRuntimeImpl;
28 | import org.sonar.api.utils.Version;
29 |
30 | import static org.assertj.core.api.Assertions.assertThat;
31 |
32 | public class CssPluginTest {
33 |
34 | @Test
35 | public void count_extensions() {
36 | SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(7, 9), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY);
37 | Plugin.Context context = new Plugin.Context(runtime);
38 | Plugin underTest = new CssPlugin();
39 | underTest.define(context);
40 | assertThat(context.getExtensions()).hasSize(12);
41 | }
42 |
43 | @Test
44 | public void count_extensions_sonarlint() {
45 | SonarRuntime runtime = SonarRuntimeImpl.forSonarLint(Version.create(7, 9));
46 | Plugin.Context context = new Plugin.Context(runtime);
47 | Plugin underTest = new CssPlugin();
48 | underTest.define(context);
49 | assertThat(context.getExtensions()).hasSize(12);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/DeclarationBlockNoDuplicateProperties.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import java.util.Arrays;
23 | import java.util.Collections;
24 | import java.util.List;
25 | import org.sonar.check.Rule;
26 | import org.sonar.check.RuleProperty;
27 |
28 | @Rule(key = "S4656")
29 | public class DeclarationBlockNoDuplicateProperties implements CssRule {
30 |
31 | private static final boolean DEFAULT_IGNORE_FALLBACKS = true;
32 |
33 | @RuleProperty(
34 | key = "ignoreFallbacks",
35 | description = "Ignore consecutive duplicated properties with different values.",
36 | defaultValue = "" + DEFAULT_IGNORE_FALLBACKS)
37 | boolean ignoreFallbacks = DEFAULT_IGNORE_FALLBACKS;
38 |
39 | @Override
40 | public String stylelintKey() {
41 | return "declaration-block-no-duplicate-properties";
42 | }
43 |
44 | @Override
45 | public List stylelintOptions() {
46 | return ignoreFallbacks ? Arrays.asList(true, new StylelintIgnoreOption()) : Collections.emptyList();
47 | }
48 |
49 | private static class StylelintIgnoreOption {
50 | private final List ignore = Collections.singletonList("consecutive-duplicates-with-different-values");
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRulesDefinitionTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.junit.Test;
23 | import org.sonar.api.server.rule.RulesDefinition;
24 |
25 | import static org.assertj.core.api.Assertions.assertThat;
26 |
27 | public class CssRulesDefinitionTest {
28 |
29 | @Test
30 | public void test_with_external_rules() {
31 | CssRulesDefinition rulesDefinition = new CssRulesDefinition();
32 | RulesDefinition.Context context = new RulesDefinition.Context();
33 | rulesDefinition.define(context);
34 |
35 | assertThat(context.repositories()).hasSize(2);
36 | RulesDefinition.Repository mainRepository = context.repository("css");
37 | RulesDefinition.Repository externalRepository = context.repository("external_stylelint");
38 |
39 | assertThat(externalRepository.name()).isEqualTo("stylelint");
40 | assertThat(externalRepository.language()).isEqualTo("css");
41 | assertThat(externalRepository.isExternal()).isEqualTo(true);
42 | assertThat(externalRepository.rules()).hasSize(170);
43 |
44 | assertThat(mainRepository.name()).isEqualTo("SonarAnalyzer");
45 | assertThat(mainRepository.language()).isEqualTo("css");
46 | assertThat(mainRepository.isExternal()).isEqualTo(false);
47 | assertThat(mainRepository.rules()).hasSize(CssRules.getRuleClasses().size());
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/AtRuleNoUnknown.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import java.util.Arrays;
23 | import java.util.List;
24 | import org.sonar.check.Rule;
25 | import org.sonar.check.RuleProperty;
26 |
27 | import static org.sonar.css.plugin.rules.RuleUtils.splitAndTrim;
28 |
29 | @Rule(key = "S4662")
30 | public class AtRuleNoUnknown implements CssRule {
31 |
32 | private static final String DEFAULT_IGNORED_AT_RULES = "value,at-root,content,debug,each,else,error,for,function,if,include,mixin,return,warn,while,extend,use,/^@.*/";
33 |
34 | @RuleProperty(
35 | key = "ignoreAtRules",
36 | description = "Comma-separated list of \"at-rules\" to consider as valid.",
37 | defaultValue = "" + DEFAULT_IGNORED_AT_RULES)
38 | String ignoredAtRules = DEFAULT_IGNORED_AT_RULES;
39 |
40 | @Override
41 | public String stylelintKey() {
42 | return "at-rule-no-unknown";
43 | }
44 |
45 | @Override
46 | public List stylelintOptions() {
47 | return Arrays.asList(true, new StylelintIgnoreOption(splitAndTrim(ignoredAtRules)));
48 | }
49 |
50 | private static class StylelintIgnoreOption {
51 | // Used by GSON serialization
52 | private final List ignoreAtRules;
53 |
54 | StylelintIgnoreOption(List ignoreAtRules) {
55 | this.ignoreAtRules = ignoreAtRules;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/its/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | css
7 | org.sonarsource.css
8 | 1.4.3-SNAPSHOT
9 |
10 |
11 | 4.0.0
12 |
13 | its
14 | pom
15 |
16 |
17 | plugin
18 | ruling
19 |
20 |
21 |
22 |
23 | qa
24 |
25 |
26 | env.SONARSOURCE_QA
27 | true
28 |
29 |
30 |
31 |
32 |
33 | org.apache.maven.plugins
34 | maven-dependency-plugin
35 | 2.10
36 |
37 |
38 | copy-plugin
39 | generate-test-resources
40 |
41 | copy
42 |
43 |
44 |
45 |
46 | ${project.groupId}
47 | sonar-css-plugin
48 | ${project.version}
49 | sonar-plugin
50 | true
51 |
52 |
53 | ../../sonar-css-plugin/target
54 | true
55 | true
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/SelectorPseudoClassNoUnknown.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import java.util.Arrays;
23 | import java.util.List;
24 | import org.sonar.check.Rule;
25 | import org.sonar.check.RuleProperty;
26 |
27 | import static org.sonar.css.plugin.rules.RuleUtils.splitAndTrim;
28 |
29 | @Rule(key = "S4659")
30 | public class SelectorPseudoClassNoUnknown implements CssRule {
31 |
32 | private static final String DEFAULT_IGNORED_PSEUDO_CLASSES = "local,global,export,import";
33 |
34 | @RuleProperty(
35 | key = "ignorePseudoClasses",
36 | description = "Comma-separated list of strings and/or regular expressions for pseudo classes to consider as valid.",
37 | defaultValue = "" + DEFAULT_IGNORED_PSEUDO_CLASSES)
38 | String ignoredPseudoClasses = DEFAULT_IGNORED_PSEUDO_CLASSES;
39 |
40 | @Override
41 | public String stylelintKey() {
42 | return "selector-pseudo-class-no-unknown";
43 | }
44 |
45 | @Override
46 | public List stylelintOptions() {
47 | return Arrays.asList(true, new StylelintIgnoreOption(splitAndTrim(ignoredPseudoClasses)));
48 | }
49 |
50 |
51 | private static class StylelintIgnoreOption {
52 | // Used by GSON serialization
53 | private final List ignorePseudoClasses;
54 |
55 | StylelintIgnoreOption(List ignorePseudoClasses) {
56 | this.ignorePseudoClasses = ignorePseudoClasses;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/SelectorPseudoElementNoUnknown.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import java.util.Arrays;
23 | import java.util.List;
24 | import org.sonar.check.Rule;
25 | import org.sonar.check.RuleProperty;
26 |
27 | import static org.sonar.css.plugin.rules.RuleUtils.splitAndTrim;
28 |
29 | @Rule(key = "S4660")
30 | public class SelectorPseudoElementNoUnknown implements CssRule {
31 |
32 | private static final String DEFAULT_IGNORE_PSEUDO_ELEMENTS = "ng-deep,v-deep";
33 |
34 | @Override
35 | public String stylelintKey() {
36 | return "selector-pseudo-element-no-unknown";
37 | }
38 |
39 | @RuleProperty(
40 | key = "ignorePseudoElements",
41 | description = "Comma-separated list of regular expressions or strings to ignore (e.g. /^custom-/).",
42 | defaultValue = "" + DEFAULT_IGNORE_PSEUDO_ELEMENTS)
43 | String ignorePseudoElements = DEFAULT_IGNORE_PSEUDO_ELEMENTS;
44 |
45 | @Override
46 | public List stylelintOptions() {
47 | return Arrays.asList(true, new StylelintIgnorePseudoElementsOption(splitAndTrim(ignorePseudoElements)));
48 | }
49 |
50 | private static class StylelintIgnorePseudoElementsOption {
51 | // Used by GSON serialization
52 | private final List ignorePseudoElements;
53 |
54 | StylelintIgnorePseudoElementsOption(List ignorePseudoElements) {
55 | this.ignorePseudoElements = ignorePseudoElements;
56 | }
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/MinifiedFilesFilterTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.junit.Test;
23 | import org.sonar.api.batch.fs.internal.DefaultInputFile;
24 | import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
25 |
26 | import static org.assertj.core.api.Assertions.assertThat;
27 |
28 | public class MinifiedFilesFilterTest {
29 |
30 | private static final MinifiedFilesFilter MINIFIED_FILES_FILTER = new MinifiedFilesFilter();
31 |
32 | @Test
33 | public void should_exclude_by_name() throws Exception {
34 | DefaultInputFile jsFile = TestInputFileBuilder.create("", "foo.min.css")
35 | .setLanguage("css")
36 | .setContents("short content")
37 | .build();
38 | assertThat(MINIFIED_FILES_FILTER.accept(jsFile)).isFalse();
39 | }
40 |
41 | @Test
42 | public void should_keep_other_lang() throws Exception {
43 | DefaultInputFile jsFile = TestInputFileBuilder.create("", "foo.min.css").setLanguage("js").build();
44 | assertThat(MINIFIED_FILES_FILTER.accept(jsFile)).isTrue();
45 | }
46 |
47 | @Test
48 | public void should_exclude_by_content() throws Exception {
49 | String longContent = new String(new char[500]).replace("\0", "a") + "\n";
50 |
51 | DefaultInputFile jsFile = TestInputFileBuilder.create("", "foo.css")
52 | .setLanguage("css")
53 | .setContents(longContent)
54 | .build();
55 | assertThat(MINIFIED_FILES_FILTER.accept(jsFile)).isFalse();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/server/bundle/Zip.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.server.bundle;
21 |
22 | import java.io.IOException;
23 | import java.io.InputStream;
24 | import java.nio.file.Files;
25 | import java.nio.file.Path;
26 | import java.nio.file.StandardCopyOption;
27 | import java.util.zip.ZipEntry;
28 | import java.util.zip.ZipInputStream;
29 |
30 | public class Zip {
31 |
32 | private Zip() {
33 | // utility class
34 | }
35 |
36 | public static void extract(InputStream bundle, Path destination) throws IOException {
37 | try (ZipInputStream zip = new ZipInputStream(bundle)) {
38 | ZipEntry entry = zip.getNextEntry();
39 | if (entry == null) {
40 | throw new IllegalStateException("At least one entry expected.");
41 | }
42 | while (entry != null) {
43 | Path entryDestination = entryPath(destination, entry);
44 | if (entry.isDirectory()) {
45 | Files.createDirectories(entryDestination);
46 | } else {
47 | Files.copy(zip, entryDestination, StandardCopyOption.REPLACE_EXISTING);
48 | }
49 | zip.closeEntry();
50 | entry = zip.getNextEntry();
51 | }
52 | }
53 | }
54 |
55 | private static Path entryPath(Path targetPath, ZipEntry entry) {
56 | Path entryPath = targetPath.resolve(entry.getName()).normalize();
57 | if (!entryPath.startsWith(targetPath)) {
58 | throw new IllegalStateException("Archive entry " + entry.getName() + " is not within " + targetPath);
59 | }
60 | return entryPath;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/MinifiedFilesFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import java.io.IOException;
23 | import org.sonar.api.batch.fs.InputFile;
24 | import org.sonar.api.batch.fs.InputFileFilter;
25 | import org.sonar.api.utils.log.Logger;
26 | import org.sonar.api.utils.log.Loggers;
27 |
28 | public class MinifiedFilesFilter implements InputFileFilter {
29 |
30 | private static final int AVERAGE_LINE_LENGTH_THRESHOLD = 200;
31 |
32 | private static final Logger LOG = Loggers.get(MinifiedFilesFilter.class);
33 |
34 | @Override
35 | public boolean accept(InputFile file) {
36 | if (!CssLanguage.KEY.equals(file.language())) {
37 | return true;
38 | }
39 |
40 | try {
41 | boolean isMinified = hasMinifiedFileName(file) || hasExcessiveAverageLineLength(file);
42 | if (isMinified) {
43 | LOG.debug("File [" + file.uri() + "] looks like a minified file and will not be analyzed");
44 | }
45 | return !isMinified;
46 |
47 | } catch (IOException e) {
48 | throw new IllegalStateException("Failed to read input file", e);
49 | }
50 | }
51 |
52 | private static boolean hasMinifiedFileName(InputFile file) {
53 | String fileName = file.filename();
54 | return fileName.endsWith("-min.css") || fileName.endsWith(".min.css");
55 | }
56 |
57 | private static boolean hasExcessiveAverageLineLength(InputFile file) throws IOException {
58 | int averageLineLength = file.contents().length() / file.lines();
59 | return averageLineLength > AVERAGE_LINE_LENGTH_THRESHOLD;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/package/node_modules/run-node/readme.md:
--------------------------------------------------------------------------------
1 | # run-node [](https://travis-ci.org/sindresorhus/run-node)
2 |
3 | > Run the Node.js binary no matter what
4 |
5 | You can't always assume running `$ node file.js` will just work. The user might have the `node` binary in a non-standard location. They might be using a Node.js version manager like `nvm`, which is sourced in a subshell and not available from the outside. It also depends from where you're trying to run it. For example, GUI apps on macOS doesn't inherit the [`$PATH`](https://en.wikipedia.org/wiki/PATH_(variable)), so the `node` binary would not be found. Most projects that depend on Node.js just end up telling the user to manually set the full path to the `node` binary in some project specific settings. Now every project has to do this. [Ugh...](https://gist.github.com/cookrn/4015437) I prefer things to *just* work. With this module it will.
6 |
7 | This Bash script uses some tricks to find the Node.js binary on your system and run it.
8 |
9 | Can be used from any environment that can spawn a process (Shell, Python, Ruby, Swift, Objective-C, etc).
10 |
11 |
12 | ### npm
13 |
14 | #### Install
15 |
16 | ```
17 | $ npm install run-node
18 | ```
19 |
20 | #### Usage
21 |
22 | ```
23 | $ ./node_modules/.bin/run-node file.js
24 | ```
25 |
26 | Or in an [npm run script](https://docs.npmjs.com/cli/run-script):
27 |
28 | ```json
29 | {
30 | "start": "run-node file.js"
31 | }
32 | ```
33 |
34 | ### Manually
35 |
36 | #### Install
37 |
38 | Download the [run-node](run-node) file:
39 |
40 | ```
41 | $ curl -sSLO https://github.com/sindresorhus/run-node/raw/master/run-node && chmod +x run-node
42 | ```
43 |
44 | #### Usage
45 |
46 | ```
47 | ./run-node file.js
48 | ```
49 |
50 | #### Customizable cache path and error message
51 |
52 | The cache path and error message are defined by the `RUN_NODE_CACHE_PATH` and `RUN_NODE_ERROR_MSG` environment variables. You could use them in a script or add them to your `~.bashrc`.
53 |
54 | Default config:
55 |
56 | ```sh
57 | export RUN_NODE_ERROR_MSG="Couldn't find the Node.js binary. Ensure you have Node.js installed. Open an issue on https://github.com/sindresorhus/run-node"
58 | export RUN_NODE_CACHE_PATH="/home/username/.node_path"
59 | ```
60 |
61 |
62 | ## Created by
63 |
64 | - [Sindre Sorhus](https://github.com/sindresorhus)
65 | - [Mathias Fredriksson](https://github.com/mafredri)
66 |
67 |
68 | ## License
69 |
70 | MIT © [Sindre Sorhus](https://sindresorhus.com)
71 |
--------------------------------------------------------------------------------
/its/plugin/src/test/java/org/sonar/css/its/MetricsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.its;
21 |
22 | import com.sonar.orchestrator.Orchestrator;
23 | import org.junit.BeforeClass;
24 | import org.junit.ClassRule;
25 | import org.junit.Test;
26 |
27 | import static org.assertj.core.api.Assertions.assertThat;
28 | import static org.sonar.css.its.Tests.getMeasure;
29 | import static org.sonar.css.its.Tests.getProjectMeasureAsDouble;
30 |
31 | public class MetricsTest {
32 |
33 | private static String PROJECT_KEY = "metrics-project";
34 |
35 | @ClassRule
36 | public static Orchestrator orchestrator = Tests.ORCHESTRATOR;
37 |
38 | @BeforeClass
39 | public static void prepare() {
40 | orchestrator.executeBuild(Tests.createScanner(PROJECT_KEY));
41 | }
42 |
43 | @Test
44 | public void test() {
45 | assertThat(getProjectMeasureAsDouble("lines", PROJECT_KEY)).isEqualTo(43);
46 | assertThat(getProjectMeasureAsDouble("ncloc", PROJECT_KEY)).isEqualTo(32);
47 | assertThat(getMeasure("ncloc_language_distribution", PROJECT_KEY).getValue()).isEqualTo("css=22;web=10");
48 | assertThat(getProjectMeasureAsDouble("comment_lines", PROJECT_KEY)).isEqualTo(4);
49 |
50 | assertThat(getMeasure("ncloc_data", PROJECT_KEY + ":src/file1.css").getValue())
51 | .contains("1=1;", "2=1;", "3=1;", "4=1;", "5=1;", "6=1;", "7=1");
52 |
53 | assertThat(getMeasure("ncloc_data", PROJECT_KEY + ":src/file2.less").getValue())
54 | .contains("1=1;", "2=1;", "3=1;", "4=1;", "5=1;", "6=1;", "7=1;", "8=1;", "9=1");
55 |
56 | assertThat(getMeasure("ncloc_data", PROJECT_KEY + ":src/file3.scss").getValue())
57 | .contains("1=1;", "3=1;", "5=1;", "6=1;", "7=1;", "8=1");
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/its/plugin/src/test/java/org/sonar/css/its/NoCssFileProjectTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.its;
21 |
22 | import com.sonar.orchestrator.Orchestrator;
23 | import com.sonar.orchestrator.build.SonarScanner;
24 | import java.util.Collections;
25 | import java.util.List;
26 | import java.util.stream.Collectors;
27 | import org.junit.BeforeClass;
28 | import org.junit.ClassRule;
29 | import org.junit.Test;
30 | import org.sonarqube.ws.Issues;
31 | import org.sonarqube.ws.client.issues.SearchRequest;
32 |
33 | import static org.assertj.core.api.Assertions.assertThat;
34 | import static org.assertj.core.api.Assertions.tuple;
35 | import static org.sonar.css.its.Tests.newWsClient;
36 |
37 | public class NoCssFileProjectTest {
38 |
39 | private static String PROJECT_KEY = "php-project";
40 |
41 | @ClassRule
42 | public static Orchestrator orchestrator = Tests.ORCHESTRATOR;
43 |
44 | @BeforeClass
45 | public static void prepare() {
46 | orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
47 | SonarScanner scanner = Tests.createScanner(PROJECT_KEY);
48 | orchestrator.executeBuild(scanner);
49 | }
50 |
51 | @Test
52 | public void test() {
53 | SearchRequest request = new SearchRequest();
54 | request.setComponentKeys(Collections.singletonList(PROJECT_KEY));
55 | List issuesList = newWsClient().issues().search(request).getIssuesList().stream()
56 | .filter(i -> i.getRule().startsWith("css:"))
57 | .collect(Collectors.toList());
58 |
59 | assertThat(issuesList).extracting(Issues.Issue::getRule, Issues.Issue::getLine, Issues.Issue::getComponent).containsExactlyInAnyOrder(
60 | tuple("css:S4658", 7, "php-project:src/index.php"));
61 |
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/resources/mock-start-server/startServer.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const http = require('http');
4 | const port = process.argv[2];
5 |
6 | const requestHandler = (request, response) => {
7 | let data = [];
8 | request.on('data', chunk => {
9 | data.push(chunk);
10 | });
11 | request.on('end', () => {
12 | let fileName = null;
13 | let fileContent = null;
14 | if (data.length > 0) {
15 | const analysisRequest = JSON.parse(data.join());
16 | fileName = analysisRequest.filePath.replace(/.*[\/\\]/g,"");
17 | fileContent = analysisRequest.fileContent;
18 | }
19 | if (request.url === '/status') {
20 | response.writeHead(200, { 'Content-Type': 'text/plain' });
21 | response.end('OK!');
22 | } else {
23 | switch (fileName) {
24 | case "file.css":
25 | case "file.web":
26 | case "file.php":
27 | case "file.vue":
28 | case "file.js": // to test that we will not save this issue even if it's provided by response
29 | response.end(JSON.stringify([
30 | {line: 2, rule: "block-no-empty", text: "Unexpected empty block"}
31 | ]));
32 | break;
33 | case "file-with-rule-id-message.css":
34 | response.end(JSON.stringify([
35 | {line: 2, rule: "color-no-invalid-hex", text: "some message (color-no-invalid-hex)"}
36 | ]));
37 | break;
38 | case "empty.css":
39 | response.end(JSON.stringify([]));
40 | break;
41 | case "syntax-error.css":
42 | case "syntax-error.web":
43 | response.end(JSON.stringify([
44 | {line: 2, rule: "CssSyntaxError", text: "Missed semicolon (CssSyntaxError)"}
45 | ]));
46 | break;
47 | case "unknown-rule.css":
48 | response.end(JSON.stringify([
49 | {line: 2, rule: "unknown-rule-key", text: "some message"}
50 | ]));
51 | break;
52 | case "invalid-json-response.css":
53 | response.end("[");
54 | break;
55 | case "copy-file-content-into-issue-message.css":
56 | response.end(JSON.stringify([
57 | {line: 1, rule: "block-no-empty", text: "" + fileContent}
58 | ]));
59 | break;
60 | default:
61 | throw "Unexpected fileName: " + fileName;
62 | }
63 | }
64 | });
65 | };
66 |
67 | const server = http.createServer(requestHandler);
68 |
69 | server.listen(port, (err) => {
70 | if (err) {
71 | return console.log('something bad happened', err)
72 | }
73 |
74 | console.log(`server is listening on ${port}`)
75 | });
76 |
--------------------------------------------------------------------------------
/its/plugin/src/test/java/org/sonar/css/its/StylelintReportTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.its;
21 |
22 | import com.sonar.orchestrator.Orchestrator;
23 | import java.util.Collections;
24 | import java.util.List;
25 | import org.junit.BeforeClass;
26 | import org.junit.ClassRule;
27 | import org.junit.Test;
28 | import org.sonarqube.ws.Issues.Issue;
29 | import org.sonarqube.ws.client.issues.SearchRequest;
30 |
31 | import static org.assertj.core.api.Assertions.assertThat;
32 | import static org.sonar.css.its.Tests.newWsClient;
33 |
34 | public class StylelintReportTest {
35 |
36 | private static String PROJECT_KEY = "external-report-project";
37 |
38 | @ClassRule
39 | public static Orchestrator orchestrator = Tests.ORCHESTRATOR;
40 |
41 | @BeforeClass
42 | public static void prepare() {
43 | orchestrator.executeBuild(Tests.createScanner(PROJECT_KEY).setProperty("sonar.css.stylelint.reportPaths", "report.json"));
44 | }
45 |
46 | @Test
47 | public void test() {
48 | if (orchestrator.getServer().version().isGreaterThanOrEquals(7, 2)) {
49 | SearchRequest request = new SearchRequest();
50 | request.setComponentKeys(Collections.singletonList(PROJECT_KEY));
51 | List issuesList = newWsClient().issues().search(request).getIssuesList();
52 |
53 | assertThat(issuesList).extracting("line").containsExactlyInAnyOrder(111, 81, 55, 58, 114);
54 | assertThat(issuesList).extracting("rule").containsExactlyInAnyOrder(
55 | "external_stylelint:no-missing-end-of-source-newline",
56 | "external_stylelint:no-missing-end-of-source-newline",
57 | "external_stylelint:rule-empty-line-before",
58 | "external_stylelint:selector-pseudo-element-colon-notation",
59 | "css:S4658");
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/its/plugin/projects/external-report-project/src/file1.css:
--------------------------------------------------------------------------------
1 | .navbar-search {
2 | position: relative;
3 | padding: calc((var(--globalNavHeight) - var(--globalNavContentHeight)) / 2) 0;
4 | }
5 |
6 | .navbar-search .search-box,
7 | .navbar-search .search-box-input {
8 | width: 26vw;
9 | max-width: 310px;
10 | min-width: 260px;
11 | height: var(--globalNavContentHeight);
12 | }
13 |
14 | .navbar-search .search-box-input {
15 | border-color: #fff;
16 | }
17 |
18 | .navbar-search .search-box-note {
19 | line-height: calc(var(--globalNavContentHeight) - 2px);
20 | }
21 |
22 | .navbar-search .search-box-magnifier,
23 | .navbar-search .search-box-clear {
24 | top: calc((var(--globalNavContentHeight) - 16px) / 2);
25 | }
26 |
27 | .navbar-search-input {
28 | vertical-align: middle;
29 | width: 310px;
30 | margin-top: 3px;
31 | margin-bottom: 3px;
32 | padding-left: 26px !important;
33 | }
34 |
35 | .navbar-search-input-hint {
36 | position: absolute;
37 | top: 1px;
38 | right: 27px;
39 | line-height: var(--controlHeight);
40 | font-size: var(--smallFontSize);
41 | color: var(--secondFontColor);
42 | }
43 |
44 | .navbar-search-icon {
45 | position: relative;
46 | z-index: var(--aboveNormalZIndex);
47 | vertical-align: middle;
48 | width: 16px;
49 | margin-left: 4px;
50 | margin-right: -20px;
51 | background-color: #fff;
52 | color: var(--secondFontColor);
53 | }
54 |
55 | .navbar-search-icon:before {
56 | font-size: var(--mediumFontSize);
57 | }
58 |
59 | .navbar-search-item-link {
60 | display: flex !important;
61 | }
62 |
63 | .navbar-search-item-match {
64 | flex-grow: 5;
65 | overflow: hidden;
66 | text-overflow: ellipsis;
67 | }
68 |
69 | .navbar-search-item-right {
70 | flex-grow: 1;
71 | padding-left: 10px;
72 | text-align: right;
73 | }
74 |
75 | .navbar-search-item-icons {
76 | position: relative;
77 | flex-shrink: 0;
78 | width: 16px;
79 | height: 16px;
80 | }
81 | .navbar-search-item-icons > * {
82 | position: absolute;
83 | z-index: 5;
84 | top: 0;
85 | left: 0;
86 | }
87 |
88 | .navbar-search-item-icons > .icon-outline,
89 | .navbar-search-item-icons > .icon-clock {
90 | z-index: 6;
91 | top: -4px;
92 | left: -5px;
93 | }
94 |
95 | .navbar-search-no-results {
96 | margin-top: 4px;
97 | padding: 5px 10px;
98 | }
99 |
100 | .global-navbar-search-dropdown {
101 | top: 100% !important;
102 | max-height: 80vh;
103 | width: 440px;
104 | padding: 0 !important;
105 | overflow-y: auto;
106 | overflow-x: hidden;
107 | }
108 |
109 | .global-navbar-search-dropdown .dropdown-bottom-hint {
110 | margin-bottom: 0;
111 | }
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/PropertyNoUnknown.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import org.sonar.check.Rule;
23 |
24 | import java.util.Arrays;
25 | import java.util.List;
26 | import org.sonar.check.RuleProperty;
27 |
28 | import static org.sonar.css.plugin.rules.RuleUtils.splitAndTrim;
29 |
30 |
31 | @Rule(key = "S4654")
32 | public class PropertyNoUnknown implements CssRule {
33 |
34 | private static final String DEFAULT_IGNORED_PROPERTIES = "composes, /^mso-/";
35 | private static final String DEFAULT_IGNORED_SELECTORS = "/^:export.*/, /^:import.*/";
36 |
37 | @RuleProperty(
38 | key = "ignoreTypes",
39 | description = "Comma-separated list of strings and/or regular expressions for properties to consider as valid.",
40 | defaultValue = "" + DEFAULT_IGNORED_PROPERTIES)
41 | String ignoreProperties = DEFAULT_IGNORED_PROPERTIES;
42 |
43 | @RuleProperty(
44 | key = "ignoreSelectors",
45 | description = "Comma-separated list of strings and/or regular expressions for selectors to consider as valid.",
46 | defaultValue = "" + DEFAULT_IGNORED_SELECTORS)
47 | String ignoreSelectors = DEFAULT_IGNORED_SELECTORS;
48 |
49 | @Override
50 | public String stylelintKey() {
51 | return "property-no-unknown";
52 | }
53 |
54 | @Override
55 | public List stylelintOptions() {
56 | return Arrays.asList(true, new StylelintIgnoreOption(splitAndTrim(ignoreProperties), splitAndTrim(ignoreSelectors)));
57 | }
58 |
59 | private static class StylelintIgnoreOption {
60 | // Used by GSON serialization
61 | private final List ignoreProperties;
62 | private final List ignoreSelectors;
63 |
64 | private StylelintIgnoreOption(List ignoreProperties, List ignoreSelectors) {
65 | this.ignoreProperties = ignoreProperties;
66 | this.ignoreSelectors = ignoreSelectors;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/server/NodeDeprecationWarning.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.server;
21 |
22 | import javax.annotation.Nullable;
23 | import org.sonar.api.SonarEdition;
24 | import org.sonar.api.SonarProduct;
25 | import org.sonar.api.SonarRuntime;
26 | import org.sonar.api.notifications.AnalysisWarnings;
27 | import org.sonar.api.scanner.ScannerSide;
28 | import org.sonar.api.utils.log.Logger;
29 | import org.sonar.api.utils.log.Loggers;
30 | import org.sonarsource.api.sonarlint.SonarLintSide;
31 |
32 | @ScannerSide
33 | @SonarLintSide(lifespan = SonarLintSide.MULTIPLE_ANALYSES)
34 | public class NodeDeprecationWarning {
35 |
36 | private static final Logger LOG = Loggers.get(NodeDeprecationWarning.class);
37 | private static final int MIN_RECOMMENDED_NODE_VERSION = 12;
38 | private final SonarRuntime sonarRuntime;
39 | private final AnalysisWarnings analysisWarnings;
40 |
41 | public NodeDeprecationWarning(SonarRuntime sonarRuntime) {
42 | this(sonarRuntime, null);
43 | }
44 |
45 | public NodeDeprecationWarning(SonarRuntime sonarRuntime, @Nullable AnalysisWarnings analysisWarnings) {
46 | this.sonarRuntime = sonarRuntime;
47 | this.analysisWarnings = analysisWarnings;
48 | }
49 |
50 | void logNodeDeprecation(int actualNodeVersion) {
51 | if (actualNodeVersion < MIN_RECOMMENDED_NODE_VERSION) {
52 | String msg = String.format("You are using Node.js version %d, which reached end-of-life. " +
53 | "Support for this version will be dropped in future release, please upgrade Node.js to more recent version.",
54 | actualNodeVersion);
55 | LOG.warn(msg);
56 | if (isSonarQube() && analysisWarnings != null) {
57 | analysisWarnings.addUnique(msg);
58 | }
59 | }
60 | }
61 |
62 | private boolean isSonarQube() {
63 | return sonarRuntime.getProduct() == SonarProduct.SONARQUBE && sonarRuntime.getEdition() != SonarEdition.SONARCLOUD;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/its/plugin/projects/external-report-project/src/file2.css:
--------------------------------------------------------------------------------
1 | .date-input-control {
2 | position: relative;
3 | display: inline-block;
4 | cursor: pointer;
5 | }
6 |
7 | .date-input-control-input {
8 | width: 130px;
9 | padding-left: var(--controlHeight) !important;
10 | cursor: pointer;
11 | }
12 |
13 | .date-input-control-input.is-filled {
14 | padding-right: 16px !important;
15 | }
16 |
17 | .date-input-control-icon {
18 | position: absolute;
19 | top: 4px;
20 | left: 4px;
21 | }
22 |
23 | .date-input-control-icon path {
24 | fill: var(--gray80);
25 | transition: fill 0.3s ease;
26 | }
27 |
28 | .date-input-control-input:focus + .date-input-control-icon path {
29 | fill: var(--blue);
30 | }
31 |
32 | .date-input-control-reset {
33 | position: absolute;
34 | top: 4px;
35 | right: 4px;
36 | border: none;
37 | }
38 |
39 | .date-input-calendar {
40 | position: absolute;
41 | z-index: var(--dropdownMenuZIndex);
42 | top: 100%;
43 | left: 0;
44 | border: 1px solid var(--barBorderColor);
45 | background-color: #fff;
46 | box-shadow: var(--defaultShadow);
47 | }
48 |
49 | .date-input-calendar-nav {
50 | display: flex;
51 | justify-content: space-between;
52 | align-items: center;
53 | padding-top: var(--gridSize);
54 | padding-left: var(--gridSize);
55 | padding-right: var(--gridSize);
56 | }
57 |
58 | .date-input-calender-month {
59 | }
60 |
61 | .date-input-calender-month-select {
62 | width: 70px;
63 | }
64 |
65 | .button.boolean-toggle {
66 | display: inline-block;
67 | vertical-align: middle;
68 | width: 48px;
69 | height: var(--controlHeight);
70 | padding: 1px;
71 | border: 1px solid var(--gray80);
72 | border-radius: var(--controlHeight);
73 | box-sizing: border-box;
74 | background-color: #fff;
75 | cursor: pointer;
76 | transition: all 0.3s ease;
77 | }
78 |
79 | .button.boolean-toggle:hover {
80 | background-color: #fff;
81 | }
82 |
83 | .button.boolean-toggle:focus {
84 | border-color: var(--blue);
85 | background-color: #f6f6f6;
86 | }
87 |
88 | .boolean-toggle-handle {
89 | width: 20px;
90 | height: 20px;
91 | border: 1px solid var(--gray80);
92 | border-radius: 22px;
93 | box-sizing: border-box;
94 | background-color: #f6f6f6;
95 | transition: transform 0.3s cubic-bezier(0.87, -0.41, 0.19, 1.44), border 0.3s ease;
96 | }
97 |
98 | .button.boolean-toggle-on {
99 | border-color: var(--darkBlue);
100 | background-color: var(--darkBlue);
101 | }
102 |
103 | .button.boolean-toggle-on:hover {
104 | background-color: var(--darkBlue);
105 | }
106 |
107 | .button.boolean-toggle-on:focus {
108 | background-color: var(--darkBlue);
109 | }
110 |
111 | .button.boolean-toggle-on .boolean-toggle-handle {
112 | border-color: #f6f6f6;
113 | transform: translateX(var(--controlHeight));
114 | }
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/SelectorTypeNoUnknown.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.rules;
21 |
22 | import java.util.Arrays;
23 | import java.util.List;
24 | import org.sonar.check.Rule;
25 | import org.sonar.check.RuleProperty;
26 |
27 | import static org.sonar.css.plugin.rules.RuleUtils.splitAndTrim;
28 |
29 | @Rule(key = "S4670")
30 | public class SelectorTypeNoUnknown implements CssRule {
31 |
32 | // prefixes for Angular Material (mat, md), Font Awesome (fa)
33 | private static final String DEFAULT_IGNORED_TYPES = "/^(mat|md|fa)-/";
34 |
35 | private static final String DEFAULT_IGNORE = "custom-elements";
36 |
37 | @RuleProperty(
38 | key = "ignoreTypes",
39 | description = "Comma-separated list of regular expressions for selector types to consider as valid.",
40 | defaultValue = "" + DEFAULT_IGNORED_TYPES)
41 | String ignoreTypes = DEFAULT_IGNORED_TYPES;
42 |
43 | @RuleProperty(
44 | key = "ignore",
45 | description = "Comma-separated list of ignored elements. The possible values are:\n" +
46 | "\"custom-elements\": Allow custom elements (e.g \"x-foo\").\n" +
47 | "\"default-namespace\": Allow unknown type selectors if they belong to the default namespace.",
48 | defaultValue = "" + DEFAULT_IGNORE)
49 | String ignore = DEFAULT_IGNORE;
50 |
51 | @Override
52 | public String stylelintKey() {
53 | return "selector-type-no-unknown";
54 | }
55 |
56 | @Override
57 | public List stylelintOptions() {
58 | return Arrays.asList(true, new StylelintIgnoreOption(splitAndTrim(ignoreTypes), splitAndTrim(ignore)));
59 | }
60 |
61 | private static class StylelintIgnoreOption {
62 | // Used by GSON serialization
63 | private final List ignoreTypes;
64 | private final List ignore;
65 |
66 | StylelintIgnoreOption(List ignoreTypes, List ignore) {
67 | this.ignoreTypes = ignoreTypes;
68 | this.ignore = ignore;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file2.less:
--------------------------------------------------------------------------------
1 | @import "a.css";
2 | @import "a.css"; /* S1128 | no-duplicate-at-import-rules */
3 |
4 | b a {
5 | color: pink;; /* S1116 | no-extra-semicolons */
6 | }
7 |
8 | a { /* S4664 | no-descending-specificity */
9 | color: red;
10 | }
11 |
12 | a::pseudo { /* S4660 | selector-pseudo-element-no-unknown */
13 | color: red;
14 | }
15 |
16 | a:unknown { /* S4659 | selector-pseudo-class-no-unknown */
17 | background-color: #ffw; /* S4647 | color-no-invalid-hex */
18 | /* */ /* S4663 | comment-no-empty */
19 | content: "first
20 | second"; /* S4652 | string-no-newline */
21 | color: pink;
22 | color: pink; /* S4656 | declaration-block-no-duplicate-properties */
23 | color: orange; /* S4656 | declaration-block-no-duplicate-properties | Not raised because property has a different value */
24 | font: 1em/1.3 Times; /* S4649 | font-family-no-missing-generic-family-keyword */
25 | font-family: serif, serif; /* S4648 | font-family-no-duplicate-names */
26 | heigth: 100%; /* S4654 | property-no-unknown */
27 | padding-left: 10px;
28 | padding: 20px; /* S4657 | declaration-block-no-shorthand-property-overrides */
29 | top: calc(1px+2px); /* S4650 | function-calc-no-unspaced-operator */ /* S4653 | unit-no-unknown */
30 | width: calc(100% 80px); /* S5362 | function-calc-no-invalid */
31 | }
32 |
33 | // color: pink; /* S4668 | no-invalid-double-slash-comments | Doesn't raise for LESS */
34 |
35 | .class1 {
36 | width: 100px;
37 | background: linear-gradient(top, #fff, #000); /* S4651 | function-linear-gradient-no-nonstandard-direction */
38 | }
39 |
40 | .class1 { /* S4666 | no-duplicate-selectors */
41 | padding: 100px;
42 | }
43 |
44 | unknown { /* S4670 | selector-type-no-unknown */
45 | color: black;
46 | }
47 |
48 | @unknown { /* S4662 | at-rule-no-unknown */
49 | width: 1px;
50 | }
51 |
52 | @keyframes important1 {
53 | from {
54 | margin-top: 50px;
55 | }
56 | to {
57 | margin-top: 100px !important; /* S4655 | keyframe-declaration-no-important */
58 | }
59 | }
60 |
61 | .class2 { } /* S4658 | block-no-empty */
62 |
63 | @media screen and (unknown) { /* S4661 | media-feature-name-no-unknown */
64 | width: 2px;
65 | }
66 |
--------------------------------------------------------------------------------
/its/plugin/src/test/java/org/sonar/css/its/NonStandardPathTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.its;
21 |
22 | import com.sonar.orchestrator.Orchestrator;
23 | import com.sonar.orchestrator.build.SonarScanner;
24 | import com.sonar.orchestrator.locator.FileLocation;
25 | import java.io.File;
26 | import java.util.Collections;
27 | import java.util.List;
28 | import java.util.stream.Collectors;
29 | import org.junit.BeforeClass;
30 | import org.junit.ClassRule;
31 | import org.junit.Test;
32 | import org.sonarqube.ws.Issues.Issue;
33 | import org.sonarqube.ws.client.issues.SearchRequest;
34 | import org.sonarsource.analyzer.commons.ProfileGenerator;
35 | import org.sonarsource.analyzer.commons.ProfileGenerator.RulesConfiguration;
36 |
37 | import static org.assertj.core.api.Assertions.assertThat;
38 | import static org.assertj.core.api.Assertions.tuple;
39 | import static org.sonar.css.its.Tests.newWsClient;
40 |
41 | public class NonStandardPathTest {
42 |
43 | private static String PROJECT_KEY = "dir-with-paren";
44 |
45 | @ClassRule
46 | public static Orchestrator orchestrator = Tests.ORCHESTRATOR;
47 |
48 | @BeforeClass
49 | public static void prepare() {
50 | RulesConfiguration rulesConfiguration = new RulesConfiguration();
51 | File profile = ProfileGenerator.generateProfile(orchestrator.getServer().getUrl(), "css", "css", rulesConfiguration, Collections.emptySet());
52 | orchestrator.getServer().restoreProfile(FileLocation.of(profile));
53 |
54 | orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
55 | orchestrator.getServer().associateProjectToQualityProfile(PROJECT_KEY, "css", "rules");
56 |
57 | File projectDir = FileLocation.of("projects" + File.separator + "(dir with paren)").getFile();
58 | SonarScanner scanner = Tests.createScanner(PROJECT_KEY, projectDir);
59 | orchestrator.executeBuild(scanner);
60 | }
61 |
62 | @Test
63 | public void test() {
64 | SearchRequest request = new SearchRequest();
65 | request.setComponentKeys(Collections.singletonList(PROJECT_KEY));
66 | List issuesList = newWsClient().issues().search(request).getIssuesList().stream()
67 | .filter(i -> i.getRule().startsWith("css:"))
68 | .collect(Collectors.toList());
69 |
70 | assertThat(issuesList).extracting(Issue::getRule, Issue::getComponent).containsExactly(
71 | tuple("css:S1128", "dir-with-paren:src/file1.css")
72 | );
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssPlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import org.sonar.api.Plugin;
23 | import org.sonar.api.config.PropertyDefinition;
24 | import org.sonar.api.resources.Qualifiers;
25 | import org.sonar.css.plugin.server.NodeDeprecationWarning;
26 | import org.sonar.css.plugin.server.bundle.CssAnalyzerBundle;
27 | import org.sonar.css.plugin.metrics.MetricSensor;
28 | import org.sonar.css.plugin.server.CssAnalyzerBridgeServer;
29 |
30 | public class CssPlugin implements Plugin {
31 |
32 | static final String FILE_SUFFIXES_KEY = "sonar.css.file.suffixes";
33 | public static final String FILE_SUFFIXES_DEFVALUE = ".css,.less,.scss";
34 |
35 | public static final String STYLELINT_REPORT_PATHS = "sonar.css.stylelint.reportPaths";
36 | public static final String STYLELINT_REPORT_PATHS_DEFAULT_VALUE = "";
37 |
38 | public static final String FORMER_NODE_EXECUTABLE = "sonar.css.node";
39 |
40 | private static final String CSS_CATEGORY = "CSS";
41 | private static final String LINTER_SUBCATEGORY = "Popular Rule Engines";
42 | private static final String GENERAL_SUBCATEGORY = "General";
43 |
44 | @Override
45 | public void define(Context context) {
46 | context.addExtensions(
47 | MetricSensor.class,
48 | CssLanguage.class,
49 | SonarWayProfile.class,
50 | CssRulesDefinition.class,
51 | CssAnalyzerBundle.class,
52 | CssAnalyzerBridgeServer.class,
53 | CssRuleSensor.class,
54 | StylelintReportSensor.class,
55 | MinifiedFilesFilter.class,
56 | NodeDeprecationWarning.class,
57 |
58 | PropertyDefinition.builder(FILE_SUFFIXES_KEY)
59 | .defaultValue(FILE_SUFFIXES_DEFVALUE)
60 | .name("File Suffixes")
61 | .description("List of suffixes for files to analyze.")
62 | .subCategory(GENERAL_SUBCATEGORY)
63 | .category(CSS_CATEGORY)
64 | .onQualifiers(Qualifiers.PROJECT)
65 | .multiValues(true)
66 | .build()
67 | );
68 |
69 | context.addExtension(
70 | PropertyDefinition.builder(STYLELINT_REPORT_PATHS)
71 | .defaultValue(STYLELINT_REPORT_PATHS_DEFAULT_VALUE)
72 | .name("Stylelint Report Files")
73 | .description("Paths (absolute or relative) to the JSON files with stylelint issues.")
74 | .onQualifiers(Qualifiers.PROJECT)
75 | .subCategory(LINTER_SUBCATEGORY)
76 | .category(CSS_CATEGORY)
77 | .multiValues(true)
78 | .build());
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/server/bundle/ZipTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.server.bundle;
21 |
22 | import java.nio.file.Files;
23 | import java.nio.file.Path;
24 | import java.util.zip.ZipEntry;
25 | import java.util.zip.ZipOutputStream;
26 | import org.junit.Rule;
27 | import org.junit.Test;
28 | import org.sonar.api.utils.internal.JUnitTempFolder;
29 |
30 | import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
31 | import static org.assertj.core.api.Java6Assertions.assertThat;
32 |
33 | public class ZipTest {
34 |
35 | @Rule
36 | public JUnitTempFolder tempFolder = new JUnitTempFolder();
37 |
38 | @Test
39 | public void test() throws Exception {
40 | Path zipFile = tempFolder.newFile().toPath();
41 | try (ZipOutputStream zout = new ZipOutputStream(Files.newOutputStream(zipFile))) {
42 | ZipEntry dir = new ZipEntry("dir/");
43 | zout.putNextEntry(dir);
44 | zout.closeEntry();
45 | ZipEntry zipEntry = new ZipEntry("dir/file.txt");
46 | zout.putNextEntry(zipEntry);
47 | zout.write("Hello World".getBytes());
48 | zout.closeEntry();
49 | }
50 | Path out = tempFolder.newDir().toPath();
51 | Zip.extract(Files.newInputStream(zipFile), out);
52 | assertThat(out.resolve("dir/file.txt").toFile()).hasContent("Hello World");
53 | }
54 |
55 | @Test
56 | public void test_empty_zip() throws Exception {
57 | Path zipFile = tempFolder.newFile().toPath();
58 | try (ZipOutputStream zout = new ZipOutputStream(Files.newOutputStream(zipFile))) {
59 |
60 | }
61 | Path out = tempFolder.newDir().toPath();
62 | assertThatThrownBy(() -> Zip.extract(Files.newInputStream(zipFile), out))
63 | .isInstanceOf(IllegalStateException.class)
64 | .hasMessage("At least one entry expected.");
65 | }
66 |
67 | @Test
68 | public void test_invalid_entry() throws Exception {
69 | Path zipFile = tempFolder.newFile().toPath();
70 | try (ZipOutputStream zout = new ZipOutputStream(Files.newOutputStream(zipFile))) {
71 | ZipEntry zipEntry = new ZipEntry("../file.txt");
72 | zout.putNextEntry(zipEntry);
73 | zout.write("Hello World".getBytes());
74 | zout.closeEntry();
75 | }
76 | Path out = tempFolder.newDir().toPath();
77 | assertThatThrownBy(() -> Zip.extract(Files.newInputStream(zipFile), out))
78 | .isInstanceOf(IllegalStateException.class)
79 | .hasMessage("Archive entry ../file.txt is not within " + out);
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/TestActiveRules.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin;
21 |
22 | import java.util.Arrays;
23 | import java.util.Collection;
24 | import java.util.Collections;
25 | import java.util.List;
26 | import java.util.Map;
27 | import java.util.stream.Collectors;
28 | import javax.annotation.CheckForNull;
29 | import org.sonar.api.batch.rule.ActiveRule;
30 | import org.sonar.api.batch.rule.ActiveRules;
31 | import org.sonar.api.rule.RuleKey;
32 |
33 | public class TestActiveRules implements ActiveRules {
34 |
35 | private final List activeRules;
36 |
37 | public TestActiveRules(String... activeRules) {
38 | this.activeRules = Arrays.stream(activeRules).map(TestActiveRule::new).collect(Collectors.toList());
39 | }
40 |
41 | @CheckForNull
42 | @Override
43 | public ActiveRule find(RuleKey ruleKey) {
44 | return null;
45 | }
46 |
47 | @Override
48 | public Collection findAll() {
49 | return activeRules;
50 | }
51 |
52 | @Override
53 | public Collection findByRepository(String repository) {
54 | return activeRules;
55 | }
56 |
57 | @Override
58 | public Collection findByLanguage(String language) {
59 | return activeRules;
60 | }
61 |
62 | @CheckForNull
63 | @Override
64 | public ActiveRule findByInternalKey(String repository, String internalKey) {
65 | return null;
66 | }
67 |
68 | class TestActiveRule implements ActiveRule {
69 |
70 | final RuleKey ruleKey;
71 |
72 | public TestActiveRule(String key) {
73 | ruleKey = RuleKey.of(CssRulesDefinition.REPOSITORY_KEY, key);
74 | }
75 |
76 | @Override
77 | public RuleKey ruleKey() {
78 | return ruleKey;
79 | }
80 |
81 | @Override
82 | public String severity() {
83 | return null;
84 | }
85 |
86 | @Override
87 | public String language() {
88 | return null;
89 | }
90 |
91 | @CheckForNull
92 | @Override
93 | public String param(String key) {
94 | return null;
95 | }
96 |
97 | @Override
98 | public Map params() {
99 | return Collections.emptyMap();
100 | }
101 |
102 | @CheckForNull
103 | @Override
104 | public String internalKey() {
105 | return null;
106 | }
107 |
108 | @CheckForNull
109 | @Override
110 | public String templateRuleKey() {
111 | return null;
112 | }
113 |
114 | @Override
115 | public String qpKey() {
116 | return null;
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/main/java/org/sonar/css/plugin/server/bundle/CssAnalyzerBundle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.server.bundle;
21 |
22 | import java.io.InputStream;
23 | import java.nio.file.Path;
24 | import java.nio.file.Paths;
25 | import org.sonar.api.internal.google.common.annotations.VisibleForTesting;
26 | import org.sonar.api.scanner.ScannerSide;
27 | import org.sonar.api.utils.log.Logger;
28 | import org.sonar.api.utils.log.Loggers;
29 | import org.sonar.api.utils.log.Profiler;
30 | import org.sonarsource.api.sonarlint.SonarLintSide;
31 |
32 | import static org.sonarsource.api.sonarlint.SonarLintSide.MULTIPLE_ANALYSES;
33 |
34 | @ScannerSide
35 | @SonarLintSide(lifespan = MULTIPLE_ANALYSES)
36 | public class CssAnalyzerBundle implements Bundle {
37 |
38 | private static final Logger LOG = Loggers.get(CssAnalyzerBundle.class);
39 | private static final Profiler PROFILER = Profiler.createIfDebug(LOG);
40 |
41 | // this archive is created in css-bundle module
42 | private static final String DEFAULT_BUNDLE_LOCATION = "/css-bundle.zip";
43 | private static final Path DEFAULT_STARTUP_SCRIPT = Paths.get("css-bundle", "bin", "server");
44 |
45 | final String bundleLocation;
46 |
47 | private String startServerScript = DEFAULT_STARTUP_SCRIPT.toString();
48 | private Path deployLocation;
49 |
50 | public CssAnalyzerBundle() {
51 | this(DEFAULT_BUNDLE_LOCATION);
52 | }
53 |
54 | @VisibleForTesting
55 | CssAnalyzerBundle(String bundleLocation) {
56 | this.bundleLocation = bundleLocation;
57 | }
58 |
59 | @Override
60 | public void deploy(Path deployLocation) {
61 | this.deployLocation = deployLocation;
62 | PROFILER.startDebug("Deploying bundle");
63 | LOG.debug("Deploying css-bundle into {}", deployLocation);
64 | InputStream bundle = getClass().getResourceAsStream(bundleLocation);
65 | if (bundle == null) {
66 | throw new IllegalStateException("css-bundle not found in " + bundleLocation);
67 | }
68 | try {
69 | LOG.debug("Deploying css-bundle to {}", deployLocation.toAbsolutePath());
70 | Zip.extract(bundle, deployLocation);
71 | startServerScript = deployLocation.resolve(DEFAULT_STARTUP_SCRIPT).toAbsolutePath().toString();
72 | } catch (Exception e) {
73 | throw new IllegalStateException("Failed to deploy css-bundle (with classpath '" + bundleLocation + "')", e);
74 | }
75 | PROFILER.stopDebug();
76 | }
77 |
78 | @Override
79 | public String startServerScript() {
80 | return startServerScript;
81 | }
82 |
83 | @Override
84 | public String resolve(String relativePath) {
85 | return deployLocation.resolve("css-bundle").resolve(relativePath).toString();
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/its/plugin/projects/issues-project/src/file3.scss:
--------------------------------------------------------------------------------
1 | @import "a.css";
2 | @import "a.css"; /* S1128 | no-duplicate-at-import-rules */
3 |
4 | b a {
5 | color: pink;; /* S1116 | no-extra-semicolons */
6 | }
7 |
8 | a { /* S4664 | no-descending-specificity */
9 | color: red;
10 | }
11 |
12 | a::pseudo { /* S4660 | selector-pseudo-element-no-unknown */
13 | color: red;
14 | }
15 |
16 | a:unknown { /* S4659 | selector-pseudo-class-no-unknown */
17 | background-color: #ffw; /* S4647 | color-no-invalid-hex */
18 | /* */ /* S4663 | comment-no-empty */
19 | content: "first
20 | second"; /* S4652 | string-no-newline */
21 | color: pink;
22 | color: pink; /* S4656 | declaration-block-no-duplicate-properties */
23 | color: orange; /* S4656 | declaration-block-no-duplicate-properties | Not raised because property has a different value */
24 | font: 1em/1.3 Times; /* S4649 | font-family-no-missing-generic-family-keyword */
25 | font-family: serif, serif; /* S4648 | font-family-no-duplicate-names */
26 | heigth: 100%; /* S4654 | property-no-unknown */
27 | padding-left: 10px;
28 | padding: 20px; /* S4657 | declaration-block-no-shorthand-property-overrides */
29 | top: calc(1px+2px); /* S4650 | function-calc-no-unspaced-operator */ /* S4653 | unit-no-unknown */
30 | width: calc(100% 80px); /* S5362 | function-calc-no-invalid */
31 | }
32 |
33 | // color: pink; /* S4668 | no-invalid-double-slash-comments | Doesn't raise for SCSS */
34 |
35 | .class1 {
36 | width: 100px;
37 | background: linear-gradient(top, #fff, #000); /* S4651 | function-linear-gradient-no-nonstandard-direction */
38 | }
39 |
40 | .class1 { /* S4666 | no-duplicate-selectors */
41 | padding: 100px;
42 | }
43 |
44 | unknown { /* S4670 | selector-type-no-unknown */
45 | color: black;
46 | }
47 |
48 | @unknown { /* S4662 | at-rule-no-unknown */
49 | width: 1px;
50 | }
51 |
52 | @keyframes important1 {
53 | from {
54 | margin-top: 50px;
55 | }
56 | to {
57 | margin-top: 100px !important; /* S4655 | keyframe-declaration-no-important */
58 | }
59 | }
60 |
61 | .class2 { } /* S4658 | block-no-empty */
62 |
63 | @media screen and (unknown) { /* S4661 | media-feature-name-no-unknown */
64 | width: 2px;
65 | }
66 |
67 | @mixin adjust-location($x, $y) {
68 | @if unitless($x) {
69 | color: blue;
70 | @debug "";
71 | @warn "";
72 | @error "";
73 | @at-root [dir="ltr"] { color: blue; }
74 | } @else {
75 | color: black;
76 | }
77 | }
78 |
79 | @for $i from 1 through 3 {
80 | .item-#{$i} { width: 2em * $i; }
81 | }
82 |
83 | @each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
84 | #{$header} {
85 | font-size: $size;
86 | @include large-text;
87 | }
88 | }
89 |
90 | $i: 6;
91 | @while $i > 0 {
92 | .item-#{$i} { width: 2em * $i; }
93 | $i: $i - 2;
94 | }
95 |
--------------------------------------------------------------------------------
/sonar-css-plugin/css-bundle/src/server.ts:
--------------------------------------------------------------------------------
1 | import { Server } from "http";
2 | import * as express from "express";
3 | import { AddressInfo } from "net";
4 | import * as stylelint from "stylelint";
5 | import * as fs from "fs";
6 | import * as bodyParser from "body-parser";
7 |
8 | // for testing purposes
9 | let log = console.log;
10 | let logError = console.error;
11 |
12 | const MAX_REQUEST_SIZE = "50mb";
13 |
14 | export function setLogHandlersForTests(
15 | logHandler: typeof console.log,
16 | errorHandler: typeof console.error
17 | ) {
18 | log = logHandler;
19 | logError = errorHandler;
20 | }
21 |
22 | export function start(port = 0, host = "127.0.0.1"): Promise {
23 | return new Promise(resolve => {
24 | log("DEBUG starting stylelint-bridge server at port", port);
25 | const app = express();
26 | app.use(bodyParser.json({ limit: MAX_REQUEST_SIZE }));
27 | app.post("/analyze", analyzeWithStylelint);
28 | app.get("/status", (_: express.Request, resp: express.Response) =>
29 | resp.send("OK!")
30 | );
31 |
32 | app.post("/close", (_req: express.Request, resp: express.Response) => {
33 | console.log("DEBUG stylelint-bridge server will shutdown");
34 | resp.end(() => {
35 | server.close();
36 | });
37 | });
38 |
39 | // every time something is wrong we log error and send empty response (with 0 issues)
40 | // it's important to keep this call last in configuring "app"
41 | app.use(
42 | (
43 | error: any,
44 | _req: express.Request,
45 | response: express.Response,
46 | _next: any
47 | ) => processError(error, response)
48 | );
49 |
50 | const server = app.listen(port, host, () => {
51 | log(
52 | "DEBUG stylelint-bridge server is running at port",
53 | (server.address() as AddressInfo).port
54 | );
55 | resolve(server);
56 | });
57 | });
58 | }
59 |
60 | function analyzeWithStylelint(
61 | request: express.Request,
62 | response: express.Response
63 | ) {
64 | const parsedRequest = request.body as AnalysisInput;
65 | const { filePath, fileContent, configFile } = parsedRequest;
66 | const code =
67 | typeof fileContent == "string" ? fileContent : getFileContent(filePath);
68 | const options = {
69 | code,
70 | codeFilename: filePath,
71 | configFile
72 | };
73 |
74 | stylelint
75 | .lint(options)
76 | .then(result => response.json(toIssues(result.results, filePath)))
77 | .catch(error => processError(error, response));
78 | }
79 |
80 | function processError(error: any, response: express.Response) {
81 | logError(error);
82 | response.json([]);
83 | }
84 |
85 | function toIssues(results: stylelint.LintResult[], filePath: string): Issue[] {
86 | const analysisResponse: Issue[] = [];
87 | // we should have only one element in 'results' as we are analyzing only 1 file
88 | results.forEach(result => {
89 | // to avoid reporting on "fake" source like
90 | if (result.source !== filePath) {
91 | log(
92 | `DEBUG For file [${filePath}] received issues with [${result.source}] as a source. They will not be reported.`
93 | );
94 | return;
95 | }
96 | result.warnings.forEach(warning =>
97 | analysisResponse.push({
98 | line: warning.line,
99 | text: warning.text,
100 | rule: warning.rule
101 | })
102 | );
103 | });
104 | return analysisResponse;
105 | }
106 |
107 | function getFileContent(filePath: string) {
108 | const fileContent = fs.readFileSync(filePath, { encoding: "utf8" });
109 | // strip BOM
110 | if (fileContent.charCodeAt(0) === 0xfeff) {
111 | return fileContent.slice(1);
112 | }
113 | return fileContent;
114 | }
115 |
116 | export interface AnalysisInput {
117 | filePath: string;
118 | fileContent: string | undefined;
119 | configFile: string;
120 | }
121 |
122 | export interface Issue {
123 | line: number;
124 | rule: string;
125 | text: string;
126 | }
127 |
--------------------------------------------------------------------------------
/sonar-css-plugin/src/test/java/org/sonar/css/plugin/server/bundle/CssAnalyzerBundleTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SonarCSS
3 | * Copyright (C) 2018-2021 SonarSource SA
4 | * mailto:info AT sonarsource DOT com
5 | *
6 | * This program is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 3 of the License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this program; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 | package org.sonar.css.plugin.server.bundle;
21 |
22 | import java.io.File;
23 | import java.nio.charset.StandardCharsets;
24 | import java.nio.file.Files;
25 | import java.nio.file.Path;
26 | import java.nio.file.Paths;
27 | import org.junit.Rule;
28 | import org.junit.Test;
29 | import org.sonar.api.utils.internal.JUnitTempFolder;
30 |
31 | import static org.assertj.core.api.Assertions.assertThat;
32 | import static org.assertj.core.api.Assertions.assertThatCode;
33 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
34 |
35 | public class CssAnalyzerBundleTest {
36 |
37 | @Rule
38 | public JUnitTempFolder tempFolder = new JUnitTempFolder();
39 |
40 | @Test
41 | public void default_css_bundle_location() throws Exception {
42 | CssAnalyzerBundle bundle = new CssAnalyzerBundle();
43 | assertThat(bundle.bundleLocation).isEqualTo("/css-bundle.zip");
44 | }
45 |
46 | @Test
47 | public void almost_empty_css_bundle() throws Exception {
48 | Bundle bundle = new CssAnalyzerBundle("/bundle/test-css-bundle.zip");
49 | Path deployLocation = tempFolder.newDir().toPath();
50 | String expectedStartServer = deployLocation.resolve(Paths.get("css-bundle", "bin", "server")).toString();
51 | bundle.deploy(deployLocation);
52 | String script = bundle.startServerScript();
53 | assertThat(script).isEqualTo(expectedStartServer);
54 | File scriptFile = new File(script);
55 | assertThat(scriptFile).exists();
56 | String content = new String(Files.readAllBytes(scriptFile.toPath()), StandardCharsets.UTF_8);
57 | assertThat(content).startsWith("#!/usr/bin/env node");
58 | }
59 |
60 | @Test
61 | public void missing_bundle() throws Exception {
62 | Bundle bundle = new CssAnalyzerBundle("/bundle/invalid-bundle-path.zip");
63 | assertThatThrownBy(() -> bundle.deploy(tempFolder.newDir().toPath()))
64 | .isInstanceOf(IllegalStateException.class)
65 | .hasMessage("css-bundle not found in /bundle/invalid-bundle-path.zip");
66 | }
67 |
68 | @Test
69 | public void invalid_bundle_zip() throws Exception {
70 | Bundle bundle = new CssAnalyzerBundle("/bundle/invalid-zip-file.zip");
71 | assertThatThrownBy(() -> bundle.deploy(tempFolder.newDir().toPath()))
72 | .isInstanceOf(IllegalStateException.class)
73 | .hasMessage("Failed to deploy css-bundle (with classpath '/bundle/invalid-zip-file.zip')");
74 | }
75 |
76 | @Test
77 | public void should_not_fail_when_deployed_twice() throws Exception {
78 | Bundle bundle = new CssAnalyzerBundle("/bundle/test-css-bundle.zip");
79 | Path deployLocation = tempFolder.newDir().toPath();
80 | assertThatCode(() -> {
81 | bundle.deploy(deployLocation);
82 | bundle.deploy(deployLocation);
83 | }).doesNotThrowAnyException();
84 | }
85 |
86 | @Test
87 | public void test_resolve() {
88 | Bundle bundle = new CssAnalyzerBundle("/bundle/test-css-bundle.zip");
89 | Path deployLocation = tempFolder.newDir().toPath();
90 | bundle.deploy(deployLocation);
91 | assertThat(bundle.resolve("relative/path"))
92 | .contains("css-bundle")
93 | .endsWith("path")
94 | .startsWith(deployLocation.toString());
95 |
96 | }
97 | }
98 |
--------------------------------------------------------------------------------