1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00

Plugin Repo: Allow overridding manifest properties and added recommended plugins

This commit is contained in:
Laurent Cozic 2021-08-31 22:37:56 +01:00
parent dc008ecf64
commit 9c44133bd0
7 changed files with 221 additions and 43 deletions

View File

@ -1644,6 +1644,12 @@ packages/plugin-repo-cli/lib/gitCompareUrl.js.map
packages/plugin-repo-cli/lib/gitCompareUrl.test.d.ts
packages/plugin-repo-cli/lib/gitCompareUrl.test.js
packages/plugin-repo-cli/lib/gitCompareUrl.test.js.map
packages/plugin-repo-cli/lib/overrideUtils.d.ts
packages/plugin-repo-cli/lib/overrideUtils.js
packages/plugin-repo-cli/lib/overrideUtils.js.map
packages/plugin-repo-cli/lib/overrideUtils.test.d.ts
packages/plugin-repo-cli/lib/overrideUtils.test.js
packages/plugin-repo-cli/lib/overrideUtils.test.js.map
packages/plugin-repo-cli/lib/types.d.ts
packages/plugin-repo-cli/lib/types.js
packages/plugin-repo-cli/lib/types.js.map
@ -1653,6 +1659,9 @@ packages/plugin-repo-cli/lib/updateReadme.js.map
packages/plugin-repo-cli/lib/updateReadme.test.d.ts
packages/plugin-repo-cli/lib/updateReadme.test.js
packages/plugin-repo-cli/lib/updateReadme.test.js.map
packages/plugin-repo-cli/lib/utils.d.ts
packages/plugin-repo-cli/lib/utils.js
packages/plugin-repo-cli/lib/utils.js.map
packages/plugins/ToggleSidebars/api/index.d.ts
packages/plugins/ToggleSidebars/api/index.js
packages/plugins/ToggleSidebars/api/index.js.map

9
.gitignore vendored
View File

@ -1629,6 +1629,12 @@ packages/plugin-repo-cli/lib/gitCompareUrl.js.map
packages/plugin-repo-cli/lib/gitCompareUrl.test.d.ts
packages/plugin-repo-cli/lib/gitCompareUrl.test.js
packages/plugin-repo-cli/lib/gitCompareUrl.test.js.map
packages/plugin-repo-cli/lib/overrideUtils.d.ts
packages/plugin-repo-cli/lib/overrideUtils.js
packages/plugin-repo-cli/lib/overrideUtils.js.map
packages/plugin-repo-cli/lib/overrideUtils.test.d.ts
packages/plugin-repo-cli/lib/overrideUtils.test.js
packages/plugin-repo-cli/lib/overrideUtils.test.js.map
packages/plugin-repo-cli/lib/types.d.ts
packages/plugin-repo-cli/lib/types.js
packages/plugin-repo-cli/lib/types.js.map
@ -1638,6 +1644,9 @@ packages/plugin-repo-cli/lib/updateReadme.js.map
packages/plugin-repo-cli/lib/updateReadme.test.d.ts
packages/plugin-repo-cli/lib/updateReadme.test.js
packages/plugin-repo-cli/lib/updateReadme.test.js.map
packages/plugin-repo-cli/lib/utils.d.ts
packages/plugin-repo-cli/lib/utils.js
packages/plugin-repo-cli/lib/utils.js.map
packages/plugins/ToggleSidebars/api/index.d.ts
packages/plugins/ToggleSidebars/api/index.js
packages/plugins/ToggleSidebars/api/index.js.map

View File

@ -10,18 +10,8 @@ import updateReadme from './lib/updateReadme';
import { NpmPackage } from './lib/types';
import gitCompareUrl from './lib/gitCompareUrl';
import commandUpdateRelease from './commands/updateRelease';
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;
}
import { isJoplinPluginPackage, readJsonFile } from './lib/utils';
import { applyManifestOverrides, getObsoleteManifests, readManifestOverrides } from './lib/overrideUtils';
function pluginInfoFromSearchResults(results: any[]): NpmPackage[] {
const output: NpmPackage[] = [];
@ -44,19 +34,11 @@ async function checkPluginRepository(dirPath: string, dryRun: boolean) {
if (!(await fs.pathExists(`${dirPath}/.git`))) throw new Error(`Directory is not a Git repository: ${dirPath}`);
const previousDir = chdir(dirPath);
await gitRepoCleanTry();
if (!dryRun) await gitPullTry();
chdir(previousDir);
}
async function readJsonFile(manifestPath: string, defaultValue: any = null): Promise<any> {
if (!(await fs.pathExists(manifestPath))) {
if (defaultValue === null) throw new Error(`No such file: ${manifestPath}`);
return defaultValue;
if (!dryRun) {
await gitRepoCleanTry();
await gitPullTry();
}
const content = await fs.readFile(manifestPath, 'utf8');
return JSON.parse(content);
chdir(previousDir);
}
async function extractPluginFilesFromPackage(existingManifests: any, workDir: string, packageName: string, destDir: string): Promise<any> {
@ -147,14 +129,14 @@ function chdir(path: string): string {
return previous;
}
async function processNpmPackage(npmPackage: NpmPackage, repoDir: string) {
async function processNpmPackage(npmPackage: NpmPackage, repoDir: string, dryRun: boolean) {
const tempDir = `${repoDir}/temp`;
const obsoleteManifestsPath = path.resolve(repoDir, 'obsoletes.json');
await fs.mkdirp(tempDir);
const originalPluginManifests = await readManifests(repoDir);
const obsoleteManifests = await readJsonFile(obsoleteManifestsPath, {});
const manifestOverrides = await readManifestOverrides(repoDir);
const obsoleteManifests = getObsoleteManifests(manifestOverrides);
const existingManifests = {
...originalPluginManifests,
...obsoleteManifests,
@ -199,6 +181,8 @@ async function processNpmPackage(npmPackage: NpmPackage, repoDir: string) {
...manifests,
};
manifests = applyManifestOverrides(manifests, manifestOverrides);
await writeManifests(repoDir, manifests);
await updateReadme(`${repoDir}/README.md`, manifests);
}
@ -206,11 +190,13 @@ async function processNpmPackage(npmPackage: NpmPackage, repoDir: string) {
chdir(repoDir);
await fs.remove(tempDir);
if (!(await gitRepoClean())) {
await execCommand2('git add -A', { showOutput: false });
await execCommand2(['git', 'commit', '-m', commitMessage(actionType, manifest, previousManifest, npmPackage, error)], { showOutput: false });
} else {
console.info('Nothing to commit');
if (!dryRun) {
if (!(await gitRepoClean())) {
await execCommand2('git add -A', { showOutput: false });
await execCommand2(['git', 'commit', '-m', commitMessage(actionType, manifest, previousManifest, npmPackage, error)], { showOutput: false });
} else {
console.info('Nothing to commit');
}
}
}
@ -223,36 +209,40 @@ async function commandBuild(args: CommandBuildArgs) {
await checkPluginRepository(repoDir, dryRun);
// When starting, always update and commit README, in case something has
// been updated via a pull request (for example obsoletes.json being
// modified). We do that separately so that the README update doesn't get
// mixed up with plugin updates, as in this example:
// been updated via a pull request. We do that separately so that the README
// update doesn't get mixed up with plugin updates, as in this example:
// https://github.com/joplin/plugins/commit/8a65bbbf64bf267674f854a172466ffd4f07c672
const manifests = await readManifests(repoDir);
await updateReadme(`${repoDir}/README.md`, manifests);
const previousDir = chdir(repoDir);
if (!(await gitRepoClean())) {
console.info('Updating README...');
await execCommand2('git add -A', { showOutput: true });
await execCommand2('git commit -m "Update README"', { showOutput: true });
if (!dryRun) {
if (!(await gitRepoClean())) {
console.info('Updating README...');
await execCommand2('git add -A', { showOutput: true });
await execCommand2('git commit -m "Update README"', { showOutput: true });
}
}
chdir(previousDir);
const searchResults = (await execCommand2('npm search joplin-plugin --searchlimit 5000 --json', { showOutput: false })).trim();
const npmPackages = pluginInfoFromSearchResults(JSON.parse(searchResults));
for (const npmPackage of npmPackages) {
await processNpmPackage(npmPackage, repoDir);
await processNpmPackage(npmPackage, repoDir, dryRun);
}
if (!dryRun) {
await commandUpdateRelease(args);
if (!(await gitRepoClean())) {
await execCommand2('git add -A', { showOutput: true });
await execCommand2('git commit -m "Update stats"', { showOutput: true });
}
}
if (!dryRun) await execCommand2('git push');
await execCommand2('git push');
}
}
async function commandVersion() {

View File

@ -0,0 +1,95 @@
import { applyManifestOverrides, getObsoleteManifests, ManifestOverrides } from './overrideUtils';
describe('overrideUtils', () => {
test('should get the obsolete manifests', () => {
const manifestOverrides: any = {
'ambrt.backlinksToNote': {
'manifest_version': 1,
'id': 'ambrt.backlinksToNote',
'app_min_version': '1.5',
'version': '1.0.2',
'name': 'Backlinks to note',
'description': 'Creates backlinks to opened note',
'author': 'a',
'homepage_url': 'https://discourse.joplinapp.org/t/insert-referencing-notes-backlinks-plugin/13632',
'_publish_hash': 'sha256:5676da6b9ad71fc5a9779d3bde13f17de5352344711e135f0db8c62c6dbb5696',
'_publish_commit': 'master:19e515bd67e51cc37bd270a32d2898ca009a0de2',
'_npm_package_name': 'joplin-plugin-backlinks',
'_obsolete': true,
},
'MyPlugin': {
'manifest_version': 1,
'id': 'MyPlugin',
'app_min_version': '1.6',
'version': '1.0.0',
'name': 'Testing New Plugin',
'description': 'bla',
'author': 'bla',
'homepage_url': 'bla',
'repository_url': 'bla',
'_publish_hash': 'sha256:065285d06ea3c084e7f8f8c23583de8d70c4d586274a242c4c750f6faad8c7cb',
'_publish_commit': '',
'_npm_package_name': 'joplin-plugin-testing-new-plugin',
'_obsolete': true,
},
'io.github.jackgruber.copytags': {
'_recommended': true,
},
};
const obsoletes = getObsoleteManifests(manifestOverrides);
expect(Object.keys(obsoletes).sort()).toEqual(['MyPlugin', 'ambrt.backlinksToNote']);
expect(obsoletes['ambrt.backlinksToNote'].description).toBe('Creates backlinks to opened note');
});
test('should apply the overrides', () => {
const manifests: any = {
'io.github.jackgruber.copytags': {
'manifest_version': 1,
'id': 'io.github.jackgruber.copytags',
'app_min_version': '1.6.2',
'version': '1.0.1',
'name': 'Tagging',
'description': 'Plugin to extend the Joplin tagging menu with a coppy all tags and a tagging dialog with more control. (Formerly Copy Tags).',
'author': 'JackGruber',
'homepage_url': 'https://github.com/JackGruber/joplin-plugin-tagging/blob/master/README.md',
'repository_url': 'https://github.com/JackGruber/joplin-plugin-tagging',
'keywords': [
'duplicate',
'copy',
'tags',
'tagging',
'tag',
],
'_publish_hash': 'sha256:88daaf234a9b47e5644a8de6f830a801d12edbe41ea5364d994773e89eeafeef',
'_publish_commit': 'master:64c0510e3236df7788a8d10ec28dcfbb4c2bdbb7',
'_npm_package_name': 'joplin-plugin-copytags',
},
'joplin.plugin.ambrt.backlinksToNote': {
'manifest_version': 1,
'id': 'joplin.plugin.ambrt.backlinksToNote',
'app_min_version': '1.7',
'version': '2.0.11',
'name': 'Automatic Backlinks to note',
'description': 'Creates backlinks to opened note, also in automatic way',
'author': 'ambrt,cyingfan',
'homepage_url': 'https://discourse.joplinapp.org/t/insert-referencing-notes-backlinks-plugin/13632',
'_publish_hash': 'sha256:df57930d1ab62d4297dad0bb1764888935fcbf6ca8c04e3a843e86a260735c51',
'_publish_commit': 'master:98102718a9c0fa9416d654451b18602798c4d3bb',
'_npm_package_name': 'joplin-plugin-backlinks',
},
};
const overrides: ManifestOverrides = {
'io.github.jackgruber.copytags': {
_recommended: true,
},
};
const updatedManifests = applyManifestOverrides(manifests, overrides);
expect(updatedManifests['io.github.jackgruber.copytags']._recommended).toBe(true);
expect(updatedManifests['joplin.plugin.ambrt.backlinksToNote']._recommended).toBe(undefined);
});
});

View File

@ -0,0 +1,51 @@
import * as path from 'path';
import { readJsonFile } from './utils';
export interface ManifestOverride {
_obsolete?: boolean;
_recommended?: boolean;
}
export type ManifestOverrides = Record<string, ManifestOverride>;
export function applyManifestOverrides(manifests: any, overrides: ManifestOverrides) {
for (const [pluginId, override] of Object.entries(overrides)) {
const manifest: any = manifests[pluginId];
if (!manifest) {
// If the manifest does not exist in the destination, it means the
// plugin has been taken out, so the obsolete property should be set
// to `true`. If not, it's an error.
if (!override._obsolete) {
console.error(`Could not find manifest for plugin ${pluginId} when applying override`);
}
continue;
}
for (const [propName, propValue] of Object.entries(override)) {
manifest[propName] = propValue;
}
}
return manifests;
}
export function getObsoleteManifests(overrides: ManifestOverrides) {
const output: any = {};
for (const [pluginId, override] of Object.entries(overrides)) {
if (override._obsolete) {
output[pluginId] = override;
}
}
return output;
}
function pluginManifestOverridesPath(repoDir: string): string {
return path.resolve(repoDir, 'manifestOverrides.json');
}
export async function readManifestOverrides(repoDir: string): Promise<ManifestOverrides> {
return readJsonFile(pluginManifestOverridesPath(repoDir), {});
}

View File

@ -0,0 +1,23 @@
import * as fs from 'fs-extra';
export async function readJsonFile(manifestPath: string, defaultValue: any = null): Promise<any> {
if (!(await fs.pathExists(manifestPath))) {
if (defaultValue === null) throw new Error(`No such file: ${manifestPath}`);
return defaultValue;
}
const content = await fs.readFile(manifestPath, 'utf8');
return JSON.parse(content);
}
function stripOffPackageOrg(name: string): string {
const n = name.split('/');
if (n[0][0] === '@') n.splice(0, 1);
return n.join('/');
}
export 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;
}

View File

@ -13,7 +13,8 @@
"tsc": "tsc --project tsconfig.json",
"watch": "tsc --watch --project tsconfig.json",
"test": "jest",
"test-ci": "npm run test"
"test-ci": "npm run test",
"start": "node index.js"
},
"author": "",
"license": "MIT",