Build system changes (#721)
* Refactor manifest.json * Change end-of-line convention for built plain-text files * Ignore builds directory * Mark the "dev" directory as using the node environment * Create build script * Register build scripts * Remove old build script * Fix 64x64 icon * Add test to ensure manifest data is updated properly
This commit is contained in:
parent
14efd8a824
commit
04d47bf8a9
@ -134,7 +134,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"files": ["test/**/*.js"],
|
"files": [
|
||||||
|
"test/**/*.js",
|
||||||
|
"dev/**/*.js"
|
||||||
|
],
|
||||||
"excludedFiles": ["test/data/html/*.js"],
|
"excludedFiles": ["test/data/html/*.js"],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 8,
|
"ecmaVersion": 8,
|
||||||
|
8
.gitattributes
vendored
8
.gitattributes
vendored
@ -1 +1,7 @@
|
|||||||
*.handlebars text eol=lf
|
*.sh text eol=lf
|
||||||
|
ext/*.handlebars text eol=lf
|
||||||
|
ext/*.js text eol=lf
|
||||||
|
ext/*.json text eol=lf
|
||||||
|
ext/*.css text eol=lf
|
||||||
|
ext/*.html text eol=lf
|
||||||
|
ext/*.svg text eol=lf
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*.zip
|
*.zip
|
||||||
node_modules
|
node_modules
|
||||||
|
builds/
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
rm yomichan_source.zip
|
|
||||||
7za a yomichan_source.zip ./ext ./LICENSE ./README.md ./resources ./tmpl
|
|
||||||
|
|
||||||
rm yomichan_extension.zip
|
|
||||||
7za a yomichan_extension.zip ./ext/*
|
|
214
dev/build.js
Normal file
214
dev/build.js
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Yomichan Authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const readline = require('readline');
|
||||||
|
const childProcess = require('child_process');
|
||||||
|
const yomichanTest = require('../test/yomichan-test');
|
||||||
|
|
||||||
|
|
||||||
|
function getAllFiles(directory, relativeTo) {
|
||||||
|
const results = [];
|
||||||
|
const directories = [directory];
|
||||||
|
for (const dir of directories) {
|
||||||
|
const fileNames = fs.readdirSync(dir);
|
||||||
|
for (const fileName of fileNames) {
|
||||||
|
const fullFileName = path.join(dir, fileName);
|
||||||
|
const relativeFileName = path.relative(relativeTo, fullFileName);
|
||||||
|
const stats = fs.lstatSync(fullFileName);
|
||||||
|
if (stats.isFile()) {
|
||||||
|
results.push(relativeFileName);
|
||||||
|
} else if (stats.isDirectory()) {
|
||||||
|
directories.push(fullFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createZip(directory, outputFileName, sevenZipExes=[], onUpdate=null) {
|
||||||
|
for (const exe of sevenZipExes) {
|
||||||
|
try {
|
||||||
|
childProcess.execFileSync(
|
||||||
|
exe,
|
||||||
|
[
|
||||||
|
'a',
|
||||||
|
outputFileName,
|
||||||
|
'.'
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: directory
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return await createJSZip(directory, outputFileName, onUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createJSZip(directory, outputFileName, onUpdate) {
|
||||||
|
const JSZip = yomichanTest.JSZip;
|
||||||
|
const files = getAllFiles(directory, directory);
|
||||||
|
const zip = new JSZip();
|
||||||
|
for (const fileName of files) {
|
||||||
|
zip.file(
|
||||||
|
fileName.replace(/\\/g, '/'),
|
||||||
|
fs.readFileSync(path.join(directory, fileName), {encoding: null, flag: 'r'}),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof onUpdate !== 'function') {
|
||||||
|
onUpdate = () => {}; // NOP
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await zip.generateAsync({
|
||||||
|
type: 'nodebuffer',
|
||||||
|
compression: 'DEFLATE',
|
||||||
|
compressionOptions: {level: 9}
|
||||||
|
}, onUpdate);
|
||||||
|
process.stdout.write('\n');
|
||||||
|
|
||||||
|
fs.writeFileSync(outputFileName, data, {encoding: null, flag: 'w'});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createModifiedManifest(manifest, modifications) {
|
||||||
|
manifest = JSON.parse(JSON.stringify(manifest));
|
||||||
|
|
||||||
|
if (Array.isArray(modifications)) {
|
||||||
|
for (const modification of modifications) {
|
||||||
|
const {action, path: path2} = modification;
|
||||||
|
switch (action) {
|
||||||
|
case 'set':
|
||||||
|
{
|
||||||
|
const value = getObjectProperties(manifest, path2, path2.length - 1);
|
||||||
|
const last = path2[path2.length - 1];
|
||||||
|
value[last] = modification.value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'replace':
|
||||||
|
{
|
||||||
|
const value = getObjectProperties(manifest, path2, path2.length - 1);
|
||||||
|
const regex = new RegExp(modification.pattern, modification.patternFlags);
|
||||||
|
const last = path2[path2.length - 1];
|
||||||
|
let value2 = value[last];
|
||||||
|
value2 = `${value2}`.replace(regex, modification.replacement);
|
||||||
|
value[last] = value2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
{
|
||||||
|
const value = getObjectProperties(manifest, path2, path2.length - 1);
|
||||||
|
const last = path2[path2.length - 1];
|
||||||
|
delete value[last];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getObjectProperties(object, path2, count) {
|
||||||
|
for (let i = 0; i < count; ++i) {
|
||||||
|
object = object[path2[i]];
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadDefaultManifest() {
|
||||||
|
const {manifest} = loadDefaultManifestAndVariants();
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadDefaultManifestAndVariants() {
|
||||||
|
const fileName = path.join(__dirname, 'data', 'manifest-variants.json');
|
||||||
|
const {manifest, variants} = JSON.parse(fs.readFileSync(fileName));
|
||||||
|
return {manifest, variants};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createManifestString(manifest) {
|
||||||
|
return JSON.stringify(manifest, null, 4) + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const {manifest, variants} = loadDefaultManifestAndVariants();
|
||||||
|
|
||||||
|
const rootDir = path.join(__dirname, '..');
|
||||||
|
const extDir = path.join(rootDir, 'ext');
|
||||||
|
const buildDir = path.join(rootDir, 'builds');
|
||||||
|
const manifestPath = path.join(extDir, 'manifest.json');
|
||||||
|
const sevenZipExes = ['7za', '7z'];
|
||||||
|
|
||||||
|
// Create build directory
|
||||||
|
if (!fs.existsSync(buildDir)) {
|
||||||
|
fs.mkdirSync(buildDir, {recursive: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const onUpdate = (metadata) => {
|
||||||
|
let message = `Progress: ${metadata.percent.toFixed(2)}%`;
|
||||||
|
if (metadata.currentFile) {
|
||||||
|
message += ` (${metadata.currentFile})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
readline.clearLine(process.stdout);
|
||||||
|
readline.cursorTo(process.stdout, 0);
|
||||||
|
process.stdout.write(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const variant of variants) {
|
||||||
|
const {name, fileName, fileCopies, modifications} = variant;
|
||||||
|
process.stdout.write(`Building ${name}...\n`);
|
||||||
|
|
||||||
|
const fileNameSafe = path.basename(fileName);
|
||||||
|
const modifiedManifest = createModifiedManifest(manifest, modifications);
|
||||||
|
const fullFileName = path.join(buildDir, fileNameSafe);
|
||||||
|
fs.writeFileSync(manifestPath, createManifestString(modifiedManifest));
|
||||||
|
await createZip(extDir, fullFileName, sevenZipExes, onUpdate);
|
||||||
|
|
||||||
|
if (Array.isArray(fileCopies)) {
|
||||||
|
for (const fileName2 of fileCopies) {
|
||||||
|
const fileName2Safe = path.basename(fileName2);
|
||||||
|
fs.copyFileSync(fullFileName, path.join(buildDir, fileName2Safe));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process.stdout.write('\n');
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// Restore manifest
|
||||||
|
process.stdout.write('Restoring manifest...\n');
|
||||||
|
fs.writeFileSync(manifestPath, createManifestString(manifest));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
loadDefaultManifest,
|
||||||
|
loadDefaultManifestAndVariants,
|
||||||
|
createManifestString
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (require.main === module) { main(); }
|
144
dev/data/manifest-variants.json
Normal file
144
dev/data/manifest-variants.json
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
{
|
||||||
|
"manifest": {
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "Yomichan",
|
||||||
|
"version": "20.8.3.0",
|
||||||
|
"description": "Japanese dictionary with Anki integration",
|
||||||
|
"author": "Alex Yatskov",
|
||||||
|
"icons": {
|
||||||
|
"16": "mixed/img/icon16.png",
|
||||||
|
"19": "mixed/img/icon19.png",
|
||||||
|
"32": "mixed/img/icon32.png",
|
||||||
|
"38": "mixed/img/icon38.png",
|
||||||
|
"48": "mixed/img/icon48.png",
|
||||||
|
"64": "mixed/img/icon64.png",
|
||||||
|
"128": "mixed/img/icon128.png"
|
||||||
|
},
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"16": "mixed/img/icon16.png",
|
||||||
|
"19": "mixed/img/icon19.png",
|
||||||
|
"32": "mixed/img/icon32.png",
|
||||||
|
"38": "mixed/img/icon38.png",
|
||||||
|
"48": "mixed/img/icon48.png",
|
||||||
|
"64": "mixed/img/icon64.png",
|
||||||
|
"128": "mixed/img/icon128.png"
|
||||||
|
},
|
||||||
|
"default_title": "Yomichan",
|
||||||
|
"default_popup": "bg/context.html"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"page": "bg/background.html",
|
||||||
|
"persistent": true
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": [
|
||||||
|
"http://*/*",
|
||||||
|
"https://*/*",
|
||||||
|
"file://*/*"
|
||||||
|
],
|
||||||
|
"js": [
|
||||||
|
"mixed/js/core.js",
|
||||||
|
"mixed/js/yomichan.js",
|
||||||
|
"mixed/js/comm.js",
|
||||||
|
"mixed/js/dom.js",
|
||||||
|
"mixed/js/api.js",
|
||||||
|
"mixed/js/dynamic-loader.js",
|
||||||
|
"mixed/js/frame-client.js",
|
||||||
|
"mixed/js/text-scanner.js",
|
||||||
|
"fg/js/document.js",
|
||||||
|
"fg/js/dom-text-scanner.js",
|
||||||
|
"fg/js/popup.js",
|
||||||
|
"fg/js/source.js",
|
||||||
|
"fg/js/popup-factory.js",
|
||||||
|
"fg/js/frame-offset-forwarder.js",
|
||||||
|
"fg/js/popup-proxy.js",
|
||||||
|
"fg/js/frontend.js",
|
||||||
|
"fg/js/content-script-main.js"
|
||||||
|
],
|
||||||
|
"match_about_blank": true,
|
||||||
|
"all_frames": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_chrome_version": "57.0.0.0",
|
||||||
|
"options_page": "bg/settings.html",
|
||||||
|
"options_ui": {
|
||||||
|
"page": "bg/settings.html",
|
||||||
|
"open_in_tab": true
|
||||||
|
},
|
||||||
|
"permissions": [
|
||||||
|
"<all_urls>",
|
||||||
|
"storage",
|
||||||
|
"clipboardWrite",
|
||||||
|
"unlimitedStorage",
|
||||||
|
"nativeMessaging",
|
||||||
|
"webRequest",
|
||||||
|
"webRequestBlocking"
|
||||||
|
],
|
||||||
|
"optional_permissions": [
|
||||||
|
"clipboardRead"
|
||||||
|
],
|
||||||
|
"commands": {
|
||||||
|
"toggle": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Alt+Delete"
|
||||||
|
},
|
||||||
|
"description": "Toggle text scanning"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Alt+Insert"
|
||||||
|
},
|
||||||
|
"description": "Open search window"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web_accessible_resources": [
|
||||||
|
"fg/float.html"
|
||||||
|
],
|
||||||
|
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||||
|
"applications": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "alex@foosoft.net",
|
||||||
|
"strict_min_version": "55.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"variants": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"fileName": "yomichan.zip",
|
||||||
|
"fileCopies": [
|
||||||
|
"yomichan.xpi"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev",
|
||||||
|
"fileName": "yomichan-dev.zip",
|
||||||
|
"fileCopies": [
|
||||||
|
"yomichan-dev.xpi"
|
||||||
|
],
|
||||||
|
"modifications": [
|
||||||
|
{
|
||||||
|
"action": "replace",
|
||||||
|
"path": ["name"],
|
||||||
|
"pattern": "^.*$",
|
||||||
|
"patternFlags": "",
|
||||||
|
"replacement": "$& (development build)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "replace",
|
||||||
|
"path": ["description"],
|
||||||
|
"pattern": "^(.*)(?:\\.\\s*)?$",
|
||||||
|
"patternFlags": "",
|
||||||
|
"replacement": "$1. This is a development build; get the stable version here: https://tinyurl.com/yaatdjmp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"path": ["applications", "gecko", "id"],
|
||||||
|
"value": "alex.testing@foosoft.net"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -2,15 +2,15 @@
|
|||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Yomichan",
|
"name": "Yomichan",
|
||||||
"version": "20.8.3.0",
|
"version": "20.8.3.0",
|
||||||
|
|
||||||
"description": "Japanese dictionary with Anki integration",
|
"description": "Japanese dictionary with Anki integration",
|
||||||
|
"author": "Alex Yatskov",
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "mixed/img/icon16.png",
|
"16": "mixed/img/icon16.png",
|
||||||
"19": "mixed/img/icon19.png",
|
"19": "mixed/img/icon19.png",
|
||||||
"32": "mixed/img/icon32.png",
|
"32": "mixed/img/icon32.png",
|
||||||
"38": "mixed/img/icon38.png",
|
"38": "mixed/img/icon38.png",
|
||||||
"48": "mixed/img/icon48.png",
|
"48": "mixed/img/icon48.png",
|
||||||
"64": "mixed/img/icon48.png",
|
"64": "mixed/img/icon64.png",
|
||||||
"128": "mixed/img/icon128.png"
|
"128": "mixed/img/icon128.png"
|
||||||
},
|
},
|
||||||
"browser_action": {
|
"browser_action": {
|
||||||
@ -20,42 +20,46 @@
|
|||||||
"32": "mixed/img/icon32.png",
|
"32": "mixed/img/icon32.png",
|
||||||
"38": "mixed/img/icon38.png",
|
"38": "mixed/img/icon38.png",
|
||||||
"48": "mixed/img/icon48.png",
|
"48": "mixed/img/icon48.png",
|
||||||
"64": "mixed/img/icon48.png",
|
"64": "mixed/img/icon64.png",
|
||||||
"128": "mixed/img/icon128.png"
|
"128": "mixed/img/icon128.png"
|
||||||
},
|
},
|
||||||
"default_title": "Yomichan",
|
"default_title": "Yomichan",
|
||||||
"default_popup": "bg/context.html"
|
"default_popup": "bg/context.html"
|
||||||
},
|
},
|
||||||
|
|
||||||
"author": "Alex Yatskov",
|
|
||||||
"background": {
|
"background": {
|
||||||
"page": "bg/background.html",
|
"page": "bg/background.html",
|
||||||
"persistent": true
|
"persistent": true
|
||||||
},
|
},
|
||||||
"content_scripts": [{
|
"content_scripts": [
|
||||||
"matches": ["http://*/*", "https://*/*", "file://*/*"],
|
{
|
||||||
"js": [
|
"matches": [
|
||||||
"mixed/js/core.js",
|
"http://*/*",
|
||||||
"mixed/js/yomichan.js",
|
"https://*/*",
|
||||||
"mixed/js/comm.js",
|
"file://*/*"
|
||||||
"mixed/js/dom.js",
|
],
|
||||||
"mixed/js/api.js",
|
"js": [
|
||||||
"mixed/js/dynamic-loader.js",
|
"mixed/js/core.js",
|
||||||
"mixed/js/frame-client.js",
|
"mixed/js/yomichan.js",
|
||||||
"mixed/js/text-scanner.js",
|
"mixed/js/comm.js",
|
||||||
"fg/js/document.js",
|
"mixed/js/dom.js",
|
||||||
"fg/js/dom-text-scanner.js",
|
"mixed/js/api.js",
|
||||||
"fg/js/popup.js",
|
"mixed/js/dynamic-loader.js",
|
||||||
"fg/js/source.js",
|
"mixed/js/frame-client.js",
|
||||||
"fg/js/popup-factory.js",
|
"mixed/js/text-scanner.js",
|
||||||
"fg/js/frame-offset-forwarder.js",
|
"fg/js/document.js",
|
||||||
"fg/js/popup-proxy.js",
|
"fg/js/dom-text-scanner.js",
|
||||||
"fg/js/frontend.js",
|
"fg/js/popup.js",
|
||||||
"fg/js/content-script-main.js"
|
"fg/js/source.js",
|
||||||
],
|
"fg/js/popup-factory.js",
|
||||||
"match_about_blank": true,
|
"fg/js/frame-offset-forwarder.js",
|
||||||
"all_frames": true
|
"fg/js/popup-proxy.js",
|
||||||
}],
|
"fg/js/frontend.js",
|
||||||
|
"fg/js/content-script-main.js"
|
||||||
|
],
|
||||||
|
"match_about_blank": true,
|
||||||
|
"all_frames": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"minimum_chrome_version": "57.0.0.0",
|
"minimum_chrome_version": "57.0.0.0",
|
||||||
"options_page": "bg/settings.html",
|
"options_page": "bg/settings.html",
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
@ -88,7 +92,9 @@
|
|||||||
"description": "Open search window"
|
"description": "Open search window"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web_accessible_resources": ["fg/float.html"],
|
"web_accessible_resources": [
|
||||||
|
"fg/float.html"
|
||||||
|
],
|
||||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||||
"applications": {
|
"applications": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
"test": "test"
|
"test": "test"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run test-lint && npm run test-code",
|
"build": "node ./dev/build.js",
|
||||||
|
"test": "npm run test-lint && npm run test-code && npm run test-manifest",
|
||||||
"test-lint": "eslint . && node ./test/lint/global-declarations.js",
|
"test-lint": "eslint . && node ./test/lint/global-declarations.js",
|
||||||
"test-code": "node ./test/test-schema.js && node ./test/test-dictionary.js && node ./test/test-database.js && node ./test/test-document.js && node ./test/test-object-property-accessor.js && node ./test/test-japanese.js && node ./test/test-text-source-map.js && node ./test/test-dom-text-scanner.js"
|
"test-code": "node ./test/test-schema.js && node ./test/test-dictionary.js && node ./test/test-database.js && node ./test/test-document.js && node ./test/test-object-property-accessor.js && node ./test/test-japanese.js && node ./test/test-text-source-map.js && node ./test/test-dom-text-scanner.js",
|
||||||
|
"test-manifest": "node ./test/test-manifest.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
41
test/test-manifest.js
Normal file
41
test/test-manifest.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Yomichan Authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const assert = require('assert');
|
||||||
|
const {loadDefaultManifest, createManifestString} = require('../dev/build');
|
||||||
|
|
||||||
|
|
||||||
|
function loadManifestString() {
|
||||||
|
const manifestPath = path.join(__dirname, '..', 'ext', 'manifest.json');
|
||||||
|
return fs.readFileSync(manifestPath, {encoding: 'utf8'});
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateManifest() {
|
||||||
|
const manifest1 = loadManifestString();
|
||||||
|
const manifest2 = createManifestString(loadDefaultManifest());
|
||||||
|
assert.strictEqual(manifest1, manifest2, 'Manifest data does not match.');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
validateManifest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (require.main === module) { main(); }
|
Loading…
Reference in New Issue
Block a user