mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Tools: Handle obsolete packages on plugin repo
This commit is contained in:
parent
309a97fb5b
commit
4413e6a1ee
@ -13,6 +13,7 @@
|
|||||||
"buildApiDoc": "npm start --prefix=packages/app-cli -- apidoc ../../readme/api/references/rest_api.md",
|
"buildApiDoc": "npm start --prefix=packages/app-cli -- apidoc ../../readme/api/references/rest_api.md",
|
||||||
"buildDoc": "./packages/tools/build-all.sh",
|
"buildDoc": "./packages/tools/build-all.sh",
|
||||||
"buildPluginDoc": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme './Assets/PluginDocTheme/' --readme './Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out docs/api/references/plugin_api packages/lib/services/plugins/api/",
|
"buildPluginDoc": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme './Assets/PluginDocTheme/' --readme './Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out docs/api/references/plugin_api packages/lib/services/plugins/api/",
|
||||||
|
"buildPluginRepo": "node packages/tools/build-plugin-repository.js",
|
||||||
"buildTranslations": "npm run tsc && node packages/tools/build-translation.js",
|
"buildTranslations": "npm run tsc && node packages/tools/build-translation.js",
|
||||||
"buildTranslationsNoTsc": "node packages/tools/build-translation.js",
|
"buildTranslationsNoTsc": "node packages/tools/build-translation.js",
|
||||||
"buildWebsite": "npm run buildApiDoc && node ./packages/tools/build-website.js && npm run buildPluginDoc",
|
"buildWebsite": "npm run buildApiDoc && node ./packages/tools/build-website.js && npm run buildPluginDoc",
|
||||||
|
@ -30,6 +30,17 @@ const markdownUtils = {
|
|||||||
return url;
|
return url;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
escapeTableCell(text: string) {
|
||||||
|
// Disable HTML code
|
||||||
|
text = text.replace(/</g, '<');
|
||||||
|
text = text.replace(/>/g, '>');
|
||||||
|
// Table cells can't contain new lines so replace with <br/>
|
||||||
|
text = text.replace(/\n/g, '<br/>');
|
||||||
|
// "|" is a reserved characters that should be escaped
|
||||||
|
text = text.replace(/\|/g, '\\|');
|
||||||
|
return text;
|
||||||
|
},
|
||||||
|
|
||||||
unescapeLinkUrl(url: string) {
|
unescapeLinkUrl(url: string) {
|
||||||
url = url.replace(/%28/g, '(');
|
url = url.replace(/%28/g, '(');
|
||||||
url = url.replace(/%29/g, ')');
|
url = url.replace(/%29/g, ')');
|
||||||
@ -117,8 +128,8 @@ const markdownUtils = {
|
|||||||
const rowMd = [];
|
const rowMd = [];
|
||||||
for (let j = 0; j < headers.length; j++) {
|
for (let j = 0; j < headers.length; j++) {
|
||||||
const h = headers[j];
|
const h = headers[j];
|
||||||
const value = h.filter ? h.filter(row[h.name]) : row[h.name];
|
const valueMd = markdownUtils.escapeTableCell(h.filter ? h.filter(row[h.name]) : row[h.name]);
|
||||||
rowMd.push(stringPadding(value, 3, ' ', stringPadding.RIGHT));
|
rowMd.push(stringPadding(valueMd, 3, ' ', stringPadding.RIGHT));
|
||||||
}
|
}
|
||||||
output.push(rowMd.join(' | '));
|
output.push(rowMd.join(' | '));
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,23 @@ interface NpmPackage {
|
|||||||
date: Date;
|
date: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stripOffPackageOrg(name: string): string {
|
||||||
|
const n = name.split('/');
|
||||||
|
if (n[0][0] === '@') n.splice(0, 1);
|
||||||
|
return n.join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
function isJoplinPluginPackage(pack: any): boolean {
|
||||||
|
if (!pack.keywords || !pack.keywords.includes('joplin-plugin')) return false;
|
||||||
|
if (stripOffPackageOrg(pack.name).indexOf('joplin-plugin') !== 0) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function pluginInfoFromSearchResults(results: any[]): NpmPackage[] {
|
function pluginInfoFromSearchResults(results: any[]): NpmPackage[] {
|
||||||
const output: NpmPackage[] = [];
|
const output: NpmPackage[] = [];
|
||||||
|
|
||||||
for (const r of results) {
|
for (const r of results) {
|
||||||
if (r.name.indexOf('joplin-plugin') !== 0) continue;
|
if (!isJoplinPluginPackage(r)) continue;
|
||||||
if (!r.keywords || !r.keywords.includes('joplin-plugin')) continue;
|
|
||||||
|
|
||||||
output.push({
|
output.push({
|
||||||
name: r.name,
|
name: r.name,
|
||||||
@ -48,7 +59,14 @@ async function readJsonFile(manifestPath: string, defaultValue: any = null): Pro
|
|||||||
return JSON.parse(content);
|
return JSON.parse(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function extractPluginFilesFromPackage(originalPluginManifests: any, workDir: string, packageName: string, destDir: string): Promise<any> {
|
function caseInsensitiveFindManifest(manifests: any, manifestId: string): any {
|
||||||
|
for (const id of Object.keys(manifests)) {
|
||||||
|
if (id.toLowerCase() === manifestId.toLowerCase()) return manifests[id];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function extractPluginFilesFromPackage(existingManifests: any, workDir: string, packageName: string, destDir: string): Promise<any> {
|
||||||
const previousDir = process.cwd();
|
const previousDir = process.cwd();
|
||||||
process.chdir(workDir);
|
process.chdir(workDir);
|
||||||
|
|
||||||
@ -76,7 +94,11 @@ async function extractPluginFilesFromPackage(originalPluginManifests: any, workD
|
|||||||
// package name, we skip it. Otherwise it would allow anyone to overwrite
|
// package name, we skip it. Otherwise it would allow anyone to overwrite
|
||||||
// someone else plugin just by using the same ID. So the first plugin with
|
// someone else plugin just by using the same ID. So the first plugin with
|
||||||
// this ID that was originally added is kept.
|
// this ID that was originally added is kept.
|
||||||
const originalManifest = originalPluginManifests[manifest.id];
|
//
|
||||||
|
// We need case insensitive match because the filesystem might be case
|
||||||
|
// insensitive too.
|
||||||
|
const originalManifest = caseInsensitiveFindManifest(existingManifests, manifest.id);
|
||||||
|
|
||||||
if (originalManifest && originalManifest._npm_package_name !== packageName) {
|
if (originalManifest && originalManifest._npm_package_name !== packageName) {
|
||||||
throw new Error(`Plugin "${manifest.id}" from npm package "${packageName}" has already been published under npm package "${originalManifest._npm_package_name}". Plugin from package "${packageName}" will not be imported.`);
|
throw new Error(`Plugin "${manifest.id}" from npm package "${packageName}" has already been published under npm package "${originalManifest._npm_package_name}". Plugin from package "${packageName}" will not be imported.`);
|
||||||
}
|
}
|
||||||
@ -145,6 +167,7 @@ async function main() {
|
|||||||
const repoDir = path.resolve(path.dirname(rootDir), 'joplin-plugins');
|
const repoDir = path.resolve(path.dirname(rootDir), 'joplin-plugins');
|
||||||
const tempDir = `${repoDir}/temp`;
|
const tempDir = `${repoDir}/temp`;
|
||||||
const pluginManifestsPath = path.resolve(repoDir, 'manifests.json');
|
const pluginManifestsPath = path.resolve(repoDir, 'manifests.json');
|
||||||
|
const obsoleteManifestsPath = path.resolve(repoDir, 'obsoletes.json');
|
||||||
const errorsPath = path.resolve(repoDir, 'errors.json');
|
const errorsPath = path.resolve(repoDir, 'errors.json');
|
||||||
|
|
||||||
await checkPluginRepository(repoDir);
|
await checkPluginRepository(repoDir);
|
||||||
@ -152,6 +175,11 @@ async function main() {
|
|||||||
await fs.mkdirp(tempDir);
|
await fs.mkdirp(tempDir);
|
||||||
|
|
||||||
const originalPluginManifests = await readJsonFile(pluginManifestsPath, {});
|
const originalPluginManifests = await readJsonFile(pluginManifestsPath, {});
|
||||||
|
const obsoleteManifests = await readJsonFile(obsoleteManifestsPath, {});
|
||||||
|
const existingManifests = {
|
||||||
|
...originalPluginManifests,
|
||||||
|
...obsoleteManifests,
|
||||||
|
};
|
||||||
|
|
||||||
const searchResults = (await execCommand('npm search joplin-plugin --searchlimit 5000 --json')).trim();
|
const searchResults = (await execCommand('npm search joplin-plugin --searchlimit 5000 --json')).trim();
|
||||||
const npmPackages = pluginInfoFromSearchResults(JSON.parse(searchResults));
|
const npmPackages = pluginInfoFromSearchResults(JSON.parse(searchResults));
|
||||||
@ -172,8 +200,8 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
const packageName = npmPackage.name;
|
const packageName = npmPackage.name;
|
||||||
const destDir = `${repoDir}/plugins/`;
|
const destDir = `${repoDir}/plugins/`;
|
||||||
const manifest = await extractPluginFilesFromPackage(originalPluginManifests, packageTempDir, packageName, destDir);
|
const manifest = await extractPluginFilesFromPackage(existingManifests, packageTempDir, packageName, destDir);
|
||||||
manifests[manifest.id] = manifest;
|
if (!obsoleteManifests[manifest.id]) manifests[manifest.id] = manifest;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
errors.push(error);
|
errors.push(error);
|
||||||
|
Loading…
Reference in New Issue
Block a user