Use filenamePatterns in seti update script. Fixes #131650

This commit is contained in:
Martin Aeschlimann 2021-08-31 18:13:18 +02:00
parent 2b0b4032a3
commit 554182620f
No known key found for this signature in database
GPG key ID: 2609A01E695523E3
3 changed files with 92 additions and 74 deletions

View file

@ -5,14 +5,15 @@
'use strict'; 'use strict';
let path = require('path'); const path = require('path');
let fs = require('fs'); const fs = require('fs');
let https = require('https'); const https = require('https');
let url = require('url'); const url = require('url');
const minimatch = require('minimatch');
// list of languagesId not shipped with VSCode. The information is used to associate an icon with a language association // list of languagesId not shipped with VSCode. The information is used to associate an icon with a language association
// Please try and keep this list in alphabetical order! Thank you. // Please try and keep this list in alphabetical order! Thank you.
let nonBuiltInLanguages = { // { fileNames, extensions } const nonBuiltInLanguages = { // { fileNames, extensions }
"argdown": { extensions: ['ad', 'adown', 'argdown', 'argdn'] }, "argdown": { extensions: ['ad', 'adown', 'argdown', 'argdn'] },
"bicep": { extensions: ['bicep'] }, "bicep": { extensions: ['bicep'] },
"elixir": { extensions: ['ex'] }, "elixir": { extensions: ['ex'] },
@ -41,13 +42,13 @@ let nonBuiltInLanguages = { // { fileNames, extensions }
}; };
// list of languagesId that inherit the icon from another language // list of languagesId that inherit the icon from another language
let inheritIconFromLanguage = { const inheritIconFromLanguage = {
"jsonc": 'json', "jsonc": 'json',
"postcss": 'css', "postcss": 'css',
"django-html": 'html' "django-html": 'html'
} }
let FROM_DISK = true; // set to true to take content from a repo checked out next to the vscode repo const FROM_DISK = true; // set to true to take content from a repo checked out next to the vscode repo
let font, fontMappingsFile, fileAssociationFile, colorsFile; let font, fontMappingsFile, fileAssociationFile, colorsFile;
if (!FROM_DISK) { if (!FROM_DISK) {
@ -63,10 +64,10 @@ if (!FROM_DISK) {
} }
function getCommitSha(repoId) { function getCommitSha(repoId) {
let commitInfo = 'https://api.github.com/repos/' + repoId + '/commits/master'; const commitInfo = 'https://api.github.com/repos/' + repoId + '/commits/master';
return download(commitInfo).then(function (content) { return download(commitInfo).then(function (content) {
try { try {
let lastCommit = JSON.parse(content); const lastCommit = JSON.parse(content);
return Promise.resolve({ return Promise.resolve({
commitSha: lastCommit.sha, commitSha: lastCommit.sha,
commitDate: lastCommit.commit.author.date commitDate: lastCommit.commit.author.date
@ -86,8 +87,8 @@ function download(source) {
return readFile(source); return readFile(source);
} }
return new Promise((c, e) => { return new Promise((c, e) => {
let _url = url.parse(source); const _url = url.parse(source);
let options = { host: _url.host, port: _url.port, path: _url.path, headers: { 'User-Agent': 'NodeJS' } }; const options = { host: _url.host, port: _url.port, path: _url.path, headers: { 'User-Agent': 'NodeJS' } };
let content = ''; let content = '';
https.get(options, function (response) { https.get(options, function (response) {
response.on('data', function (data) { response.on('data', function (data) {
@ -122,7 +123,7 @@ function downloadBinary(source, dest) {
https.get(source, function (response) { https.get(source, function (response) {
switch (response.statusCode) { switch (response.statusCode) {
case 200: { case 200: {
let file = fs.createWriteStream(dest); const file = fs.createWriteStream(dest);
response.on('data', function (chunk) { response.on('data', function (chunk) {
file.write(chunk); file.write(chunk);
}).on('end', function () { }).on('end', function () {
@ -157,9 +158,9 @@ function copyFile(fileName, dest) {
cbCalled = true; cbCalled = true;
} }
} }
let rd = fs.createReadStream(fileName); const rd = fs.createReadStream(fileName);
rd.on("error", handleError); rd.on("error", handleError);
let wr = fs.createWriteStream(dest); const wr = fs.createWriteStream(dest);
wr.on("error", handleError); wr.on("error", handleError);
wr.on("close", function () { wr.on("close", function () {
if (!cbCalled) { if (!cbCalled) {
@ -174,8 +175,8 @@ function copyFile(fileName, dest) {
function darkenColor(color) { function darkenColor(color) {
let res = '#'; let res = '#';
for (let i = 1; i < 7; i += 2) { for (let i = 1; i < 7; i += 2) {
let newVal = Math.round(parseInt('0x' + color.substr(i, 2), 16) * 0.9); const newVal = Math.round(parseInt('0x' + color.substr(i, 2), 16) * 0.9);
let hex = newVal.toString(16); const hex = newVal.toString(16);
if (hex.length === 1) { if (hex.length === 1) {
res += '0'; res += '0';
} }
@ -195,28 +196,32 @@ function mergeMapping(to, from, property) {
} }
function getLanguageMappings() { function getLanguageMappings() {
let langMappings = {}; const langMappings = {};
let allExtensions = fs.readdirSync('..'); const allExtensions = fs.readdirSync('..');
for (let i = 0; i < allExtensions.length; i++) { for (let i = 0; i < allExtensions.length; i++) {
let dirPath = path.join('..', allExtensions[i], 'package.json'); const dirPath = path.join('..', allExtensions[i], 'package.json');
if (fs.existsSync(dirPath)) { if (fs.existsSync(dirPath)) {
let content = fs.readFileSync(dirPath).toString(); const content = fs.readFileSync(dirPath).toString();
let jsonContent = JSON.parse(content); const jsonContent = JSON.parse(content);
let languages = jsonContent.contributes && jsonContent.contributes.languages; const languages = jsonContent.contributes && jsonContent.contributes.languages;
if (Array.isArray(languages)) { if (Array.isArray(languages)) {
for (let k = 0; k < languages.length; k++) { for (let k = 0; k < languages.length; k++) {
let languageId = languages[k].id; const languageId = languages[k].id;
if (languageId) { if (languageId) {
let extensions = languages[k].extensions; const extensions = languages[k].extensions;
let mapping = {}; const mapping = {};
if (Array.isArray(extensions)) { if (Array.isArray(extensions)) {
mapping.extensions = extensions.map(function (e) { return e.substr(1).toLowerCase(); }); mapping.extensions = extensions.map(function (e) { return e.substr(1).toLowerCase(); });
} }
let filenames = languages[k].filenames; const filenames = languages[k].filenames;
if (Array.isArray(filenames)) { if (Array.isArray(filenames)) {
mapping.fileNames = filenames.map(function (f) { return f.toLowerCase(); }); mapping.fileNames = filenames.map(function (f) { return f.toLowerCase(); });
} }
let existing = langMappings[languageId]; const filenamePatterns = languages[k].filenamePatterns;
if (Array.isArray(filenamePatterns)) {
mapping.filenamePatterns = filenamePatterns.map(function (f) { return f.toLowerCase(); });
}
const existing = langMappings[languageId];
if (existing) { if (existing) {
// multiple contributions to the same language // multiple contributions to the same language
@ -224,10 +229,12 @@ function getLanguageMappings() {
if (languages[k].configuration) { if (languages[k].configuration) {
mergeMapping(mapping, existing, 'extensions'); mergeMapping(mapping, existing, 'extensions');
mergeMapping(mapping, existing, 'fileNames'); mergeMapping(mapping, existing, 'fileNames');
mergeMapping(mapping, existing, 'filenamePatterns');
langMappings[languageId] = mapping; langMappings[languageId] = mapping;
} else { } else {
mergeMapping(existing, mapping, 'extensions'); mergeMapping(existing, mapping, 'extensions');
mergeMapping(existing, mapping, 'fileNames'); mergeMapping(existing, mapping, 'fileNames');
mergeMapping(existing, mapping, 'filenamePatterns');
} }
} else { } else {
langMappings[languageId] = mapping; langMappings[languageId] = mapping;
@ -237,14 +244,12 @@ function getLanguageMappings() {
} }
} }
} }
for (let languageId in nonBuiltInLanguages) { for (const languageId in nonBuiltInLanguages) {
langMappings[languageId] = nonBuiltInLanguages[languageId]; langMappings[languageId] = nonBuiltInLanguages[languageId];
} }
return langMappings; return langMappings;
} }
exports.copyFont = function () { exports.copyFont = function () {
return downloadBinary(font, './icons/seti.woff'); return downloadBinary(font, './icons/seti.woff');
}; };
@ -252,27 +257,27 @@ exports.copyFont = function () {
exports.update = function () { exports.update = function () {
console.log('Reading from ' + fontMappingsFile); console.log('Reading from ' + fontMappingsFile);
let def2Content = {}; const def2Content = {};
let ext2Def = {}; const ext2Def = {};
let fileName2Def = {}; const fileName2Def = {};
let def2ColorId = {}; const def2ColorId = {};
let colorId2Value = {}; const colorId2Value = {};
let lang2Def = {}; const lang2Def = {};
function writeFileIconContent(info) { function writeFileIconContent(info) {
let iconDefinitions = {}; const iconDefinitions = {};
let allDefs = Object.keys(def2Content).sort(); const allDefs = Object.keys(def2Content).sort();
for (let i = 0; i < allDefs.length; i++) { for (let i = 0; i < allDefs.length; i++) {
let def = allDefs[i]; const def = allDefs[i];
let entry = { fontCharacter: def2Content[def] }; const entry = { fontCharacter: def2Content[def] };
let colorId = def2ColorId[def]; const colorId = def2ColorId[def];
if (colorId) { if (colorId) {
let colorValue = colorId2Value[colorId]; const colorValue = colorId2Value[colorId];
if (colorValue) { if (colorValue) {
entry.fontColor = colorValue; entry.fontColor = colorValue;
let entryInverse = { fontCharacter: entry.fontCharacter, fontColor: darkenColor(colorValue) }; const entryInverse = { fontCharacter: entry.fontCharacter, fontColor: darkenColor(colorValue) };
iconDefinitions[def + '_light'] = entryInverse; iconDefinitions[def + '_light'] = entryInverse;
} }
} }
@ -280,9 +285,9 @@ exports.update = function () {
} }
function getInvertSet(input) { function getInvertSet(input) {
let result = {}; const result = {};
for (let assoc in input) { for (const assoc in input) {
let invertDef = input[assoc] + '_light'; const invertDef = input[assoc] + '_light';
if (iconDefinitions[invertDef]) { if (iconDefinitions[invertDef]) {
result[assoc] = invertDef; result[assoc] = invertDef;
} }
@ -290,7 +295,7 @@ exports.update = function () {
return result; return result;
} }
let res = { const res = {
information_for_contributors: [ information_for_contributors: [
'This file has been generated from data in https://github.com/jesseweed/seti-ui', 'This file has been generated from data in https://github.com/jesseweed/seti-ui',
'- icon definitions: https://github.com/jesseweed/seti-ui/blob/master/styles/_fonts/seti.less', '- icon definitions: https://github.com/jesseweed/seti-ui/blob/master/styles/_fonts/seti.less',
@ -321,7 +326,7 @@ exports.update = function () {
version: 'https://github.com/jesseweed/seti-ui/commit/' + info.commitSha, version: 'https://github.com/jesseweed/seti-ui/commit/' + info.commitSha,
}; };
let path = './icons/vs-seti-icon-theme.json'; const path = './icons/vs-seti-icon-theme.json';
fs.writeFileSync(path, JSON.stringify(res, null, '\t')); fs.writeFileSync(path, JSON.stringify(res, null, '\t'));
console.log('written ' + path); console.log('written ' + path);
} }
@ -330,18 +335,18 @@ exports.update = function () {
let match; let match;
return download(fontMappingsFile).then(function (content) { return download(fontMappingsFile).then(function (content) {
let regex = /@([\w-]+):\s*'(\\E[0-9A-F]+)';/g; const regex = /@([\w-]+):\s*'(\\E[0-9A-F]+)';/g;
let contents = {}; const contents = {};
while ((match = regex.exec(content)) !== null) { while ((match = regex.exec(content)) !== null) {
contents[match[1]] = match[2]; contents[match[1]] = match[2];
} }
return download(fileAssociationFile).then(function (content) { return download(fileAssociationFile).then(function (content) {
let regex2 = /\.icon-(?:set|partial)\(['"]([\w-\.+]+)['"],\s*['"]([\w-]+)['"],\s*(@[\w-]+)\)/g; const regex2 = /\.icon-(?:set|partial)\(['"]([\w-\.+]+)['"],\s*['"]([\w-]+)['"],\s*(@[\w-]+)\)/g;
while ((match = regex2.exec(content)) !== null) { while ((match = regex2.exec(content)) !== null) {
let pattern = match[1]; const pattern = match[1];
let def = '_' + match[2]; let def = '_' + match[2];
let colorId = match[3]; const colorId = match[3];
let storedColorId = def2ColorId[def]; let storedColorId = def2ColorId[def];
let i = 1; let i = 1;
while (storedColorId && colorId !== storedColorId) { // different colors for the same def? while (storedColorId && colorId !== storedColorId) { // different colors for the same def?
@ -364,20 +369,30 @@ exports.update = function () {
} }
} }
// replace extensions for languageId // replace extensions for languageId
let langMappings = getLanguageMappings(); const langMappings = getLanguageMappings();
for (let lang in langMappings) { for (let lang in langMappings) {
let mappings = langMappings[lang]; const mappings = langMappings[lang];
let exts = mappings.extensions || []; const exts = mappings.extensions || [];
let fileNames = mappings.fileNames || []; const fileNames = mappings.fileNames || [];
const filenamePatterns = mappings.filenamePatterns || [];
let preferredDef = null; let preferredDef = null;
// use the first file association for the preferred definition // use the first file extension association for the preferred definition
for (let i1 = 0; i1 < exts.length && !preferredDef; i1++) { for (let i1 = 0; i1 < exts.length && !preferredDef; i1++) {
preferredDef = ext2Def[exts[i1]]; preferredDef = ext2Def[exts[i1]];
} }
// use the first file association for the preferred definition // use the first file name association for the preferred definition, if not availbale
for (let i1 = 0; i1 < fileNames.length && !preferredDef; i1++) { for (let i1 = 0; i1 < fileNames.length && !preferredDef; i1++) {
preferredDef = fileName2Def[fileNames[i1]]; preferredDef = fileName2Def[fileNames[i1]];
} }
for (let i1 = 0; i1 < filenamePatterns.length && !preferredDef; i1++) {
let pattern = filenamePatterns[i1];
for (const name in fileName2Def) {
if (minimatch(name, pattern)) {
preferredDef = fileName2Def[name];
break;
}
}
}
if (preferredDef) { if (preferredDef) {
lang2Def[lang] = preferredDef; lang2Def[lang] = preferredDef;
if (!nonBuiltInLanguages[lang] && !inheritIconFromLanguage[lang]) { if (!nonBuiltInLanguages[lang] && !inheritIconFromLanguage[lang]) {
@ -393,12 +408,21 @@ exports.update = function () {
delete fileName2Def[fileNames[i2]]; delete fileName2Def[fileNames[i2]];
} }
} }
for (let i2 = 0; i2 < filenamePatterns.length; i2++) {
let pattern = filenamePatterns[i2];
// remove the filenamePatterns association, unless it is different from the preferred
for (const name in fileName2Def) {
if (minimatch(name, pattern) && fileName2Def[name] === preferredDef) {
delete fileName2Def[name];
}
}
}
} }
} }
} }
for (let lang in inheritIconFromLanguage) { for (const lang in inheritIconFromLanguage) {
let superLang = inheritIconFromLanguage[lang]; const superLang = inheritIconFromLanguage[lang];
let def = lang2Def[superLang]; const def = lang2Def[superLang];
if (def) { if (def) {
lang2Def[lang] = def; lang2Def[lang] = def;
} else { } else {
@ -409,7 +433,7 @@ exports.update = function () {
return download(colorsFile).then(function (content) { return download(colorsFile).then(function (content) {
let regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g; const regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g;
while ((match = regex3.exec(content)) !== null) { while ((match = regex3.exec(content)) !== null) {
colorId2Value[match[1]] = match[2]; colorId2Value[match[1]] = match[2];
} }
@ -417,9 +441,9 @@ exports.update = function () {
try { try {
writeFileIconContent(info); writeFileIconContent(info);
let cgmanifestPath = './cgmanifest.json'; const cgmanifestPath = './cgmanifest.json';
let cgmanifest = fs.readFileSync(cgmanifestPath).toString(); const cgmanifest = fs.readFileSync(cgmanifestPath).toString();
let cgmanifestContent = JSON.parse(cgmanifest); const cgmanifestContent = JSON.parse(cgmanifest);
cgmanifestContent['registrations'][0]['component']['git']['commitHash'] = info.commitSha; cgmanifestContent['registrations'][0]['component']['git']['commitHash'] = info.commitSha;
fs.writeFileSync(cgmanifestPath, JSON.stringify(cgmanifestContent, null, '\t')); fs.writeFileSync(cgmanifestPath, JSON.stringify(cgmanifestContent, null, '\t'));
console.log('updated ' + cgmanifestPath); console.log('updated ' + cgmanifestPath);

View file

@ -1791,10 +1791,6 @@
"workspace.bazel": "_bazel", "workspace.bazel": "_bazel",
"bower.json": "_bower", "bower.json": "_bower",
"docker-healthcheck": "_docker_2", "docker-healthcheck": "_docker_2",
"docker-compose.yml": "_docker_3",
"docker-compose.yaml": "_docker_3",
"docker-compose.override.yml": "_docker_3",
"docker-compose.override.yaml": "_docker_3",
"firebase.json": "_firebase", "firebase.json": "_firebase",
"geckodriver": "_firefox", "geckodriver": "_firefox",
"gruntfile.js": "_grunt", "gruntfile.js": "_grunt",
@ -1878,6 +1874,7 @@
"typescript": "_typescript", "typescript": "_typescript",
"typescriptreact": "_typescript", "typescriptreact": "_typescript",
"xml": "_xml", "xml": "_xml",
"dockercompose": "_docker_3",
"yaml": "_yml", "yaml": "_yml",
"argdown": "_argdown", "argdown": "_argdown",
"bicep": "_bicep", "bicep": "_bicep",
@ -2189,6 +2186,7 @@
"typescript": "_typescript_light", "typescript": "_typescript_light",
"typescriptreact": "_typescript_light", "typescriptreact": "_typescript_light",
"xml": "_xml_light", "xml": "_xml_light",
"dockercompose": "_docker_3_light",
"yaml": "_yml_light", "yaml": "_yml_light",
"argdown": "_argdown_light", "argdown": "_argdown_light",
"bicep": "_bicep_light", "bicep": "_bicep_light",
@ -2241,10 +2239,6 @@
"workspace.bazel": "_bazel_light", "workspace.bazel": "_bazel_light",
"bower.json": "_bower_light", "bower.json": "_bower_light",
"docker-healthcheck": "_docker_2_light", "docker-healthcheck": "_docker_2_light",
"docker-compose.yml": "_docker_3_light",
"docker-compose.yaml": "_docker_3_light",
"docker-compose.override.yml": "_docker_3_light",
"docker-compose.override.yaml": "_docker_3_light",
"firebase.json": "_firebase_light", "firebase.json": "_firebase_light",
"geckodriver": "_firefox_light", "geckodriver": "_firefox_light",
"gruntfile.js": "_grunt_light", "gruntfile.js": "_grunt_light",