Skip to content

Commit

Permalink
feat: STRF-10507 Scss autofix issue: Undefined variable
Browse files Browse the repository at this point in the history
  • Loading branch information
jairo-bc committed Mar 30, 2023
1 parent 5507b5e commit 4991e6f
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
13 changes: 11 additions & 2 deletions lib/nodeSass/AutoFixer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ const cssCompiler = require('../css/compile');
const BaseRulesFixer = require('./BaseRulesFixer');
const ConditionaImportFixer = require('./ConditionalImportFixer');
const CommaRemovalFixer = require('./CommaRemovalFixer');
const UndefinedVariableFixer = require('./UndefinedVariableFixer');

const CONDITIONAL_IMPORT = 'conditional-import';
const BASE_LEVEL_RULES = 'base-level-rules';
const POSSIBLE_WRONG_COMMA = 'possible-wrong-comma';
const UNDEFINED_VARIABLE = 'undefined-variable';

class AutoFixer {
/**
Expand Down Expand Up @@ -75,13 +77,17 @@ class AutoFixer {
const toFixFile = err.file === 'stdin' ? file : err.file;
const commaRemovalFixer = new CommaRemovalFixer(dirname, toFixFile);
files = await commaRemovalFixer.run();
} else if (problem === UNDEFINED_VARIABLE) {
const toFixFile = err.file === 'stdin' ? file : err.file;
const fixer = new UndefinedVariableFixer(dirname, toFixFile);
files = await fixer.run(err.message);
}
this.parseChangedFiles(files);
} else {
const filePath = path.join(this.themePath, 'assets/scss', file + '.scss');
console.log("Couldn't determine and autofix the problem. Please fix it manually.".red);
console.log('Found trying compile file:'.red, filePath);
throw new Error(err);
console.log('Found trying to compile file:'.red, filePath);
throw new Error(err.formatted ? err.formatted : err);
}
}

Expand All @@ -107,6 +113,9 @@ class AutoFixer {
) {
return POSSIBLE_WRONG_COMMA;
}
if (err.formatted.includes('Undefined variable')) {
return UNDEFINED_VARIABLE;
}
}

return null;
Expand Down
5 changes: 4 additions & 1 deletion lib/nodeSass/BaseRulesFixer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ class BaseRulesFixer extends BaseFixer {
return {
postcssPlugin: 'Transform Base Rules Issues into Comments',
Rule(rule, { Comment }) {
if (rule.parent.type === 'root' && rule.selector.startsWith('&--')) {
if (
rule.parent.type === 'root' &&
(rule.selector.startsWith('&--') || rule.selector.startsWith('&.'))
) {
const comment = new Comment({ text: rule.toString() });
rule.replaceWith(comment);
}
Expand Down
60 changes: 60 additions & 0 deletions lib/nodeSass/UndefinedVariableFixer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const fs = require('fs');
const BaseFixer = require('./BaseFixer');

class UndefinedVariableFixer extends BaseFixer {
async run(errorMessage) {
const varName = this.getUndefinedVariableName(errorMessage);
const value = await this.guessVariableValue(varName);

const scss = fs.readFileSync(this.filePath, 'utf8');
const processedFile = await this.processCss(scss, this.transform(varName, value));

return [{ filePath: this.filePath, data: processedFile.css }];
}

getUndefinedVariableName(errorMessage) {
const match = errorMessage.match(/\$([a-zA-Z]{1,})/gi);
if (!match) {
throw new Error("Couldn't detemine undefined variable name!");
}
return match[0];
}

transform(varName, value) {
return {
postcssPlugin: 'Declare unvariable variable value',
Once(root, { Declaration }) {
const newRule = new Declaration({
value,
prop: varName,
source: '',
});
root.prepend(newRule);
},
};
}

async guessVariableValue(varName) {
const scss = fs.readFileSync(this.filePath, 'utf8');
const processedFile = await this.processCss(
scss,
this.transformForGuessingVariableValue(varName),
);
return processedFile.varValue;
}

transformForGuessingVariableValue(varName) {
return {
postcssPlugin: 'Get first variable value found in the file',
Declaration: (decl, { result }) => {
if (decl.prop === varName) {
// eslint-disable-next-line no-param-reassign
result.varValue = decl.value;
// todo propertly break on first found declaration
}
},
};
}
}

module.exports = UndefinedVariableFixer;

0 comments on commit 4991e6f

Please sign in to comment.