Skip to content

Commit

Permalink
0.4.1 beta - new workflow for manifest-beta.json
Browse files Browse the repository at this point in the history
  • Loading branch information
TfTHacker committed Oct 16, 2021
1 parent 7ad8078 commit 274cba8
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 35 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"rules": {
"@typescript-eslint/ban-ts-comment": "off",
"no-prototype-builtins": "off",
"@typescript-eslint/no-explicit-any": "off"
}
}
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,20 @@ This allows you to control what release version beta testers are using, while le

If you choose to use manifest-beta.json, it needs to be formatted with the same structure of a manifest.json file. Again, manifest-beta.json file is completly optional.

Pseudo code for how the manifest files are processed:
```
if repositoryRoot/manifest-beta.json exists
use repositoryRoot/manifest-beta.json for release information, ignore repositoryRoot/manifest.json
copy repositoryRoot/manifest-beta.json to plugin folder, renaming it to manifest.json
else
use repositoryRoot/manifest.json for release information
copy Release/manifest.json to the plugin folder if it exists. If it doesn't exist, use the repositoryRoot/manifest.json
main.js and styles.css copied from the correspondencing release version depending upon the above logic
````
Few additional notes:
* manifest-beta.json does not need to be in the GitHub release, it just needs to be on the root of the repository itself.
* manifest-beta.json should have the exact same details as your manifest.json file, except the version number in this file should point to the release you want tested.
* A GitHub release must contain a main.js and a manifest.json file. The styles.css file is optional.
* For additional instructions on plugin requirements, see the plugins documentation provided by obsidian: [Obsidian Sample Plugin](https://github.com/obsidianmd/obsidian-sample-plugin)
10 changes: 10 additions & 0 deletions manifest-beta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "obsidian42-brat",
"name": "Obsidian42 - BRAT",
"version": "0.4.1",
"minAppVersion": "0.9.12",
"description": "Easily install a beta version of a plugin for testing.",
"author": "TfTHacker",
"authorUrl": "https://github.com/TfTHacker/obsidian42-brat",
"isDesktopOnly": false
}
73 changes: 41 additions & 32 deletions src/BetaPlugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,14 @@ export default class BetaPlugins {
*
* @param {string} repositoryPath path to the GitHub repository
* @param {PluginManifest<ReleaseFiles>} manifest manifest file
* @param {boolean} getManifest grab the remote manifest file
*
* @return {Promise<ReleaseFiles>} all relase files as strings based on the ReleaseFiles interaface
*/
async getAllReleaseFiles(repositoryPath: string, manifest: PluginManifest): Promise<ReleaseFiles> {
async getAllReleaseFiles(repositoryPath: string, manifest: PluginManifest, getManifest: boolean): Promise<ReleaseFiles> {
return {
mainJs: await grabReleaseFileFromRepository(repositoryPath, manifest.version, "main.js"),
manifest: await grabReleaseFileFromRepository(repositoryPath, manifest.version, "manifest.json"),
manifest: getManifest ? await grabReleaseFileFromRepository(repositoryPath, manifest.version, "manifest.json") : null,
styles: await grabReleaseFileFromRepository(repositoryPath, manifest.version, "styles.css")
}
}
Expand Down Expand Up @@ -110,61 +111,69 @@ export default class BetaPlugins {
* @return {Promise<boolean>} true if succeeds
*/
async addPlugin(repositoryPath: string, updatePluginFiles = false, seeIfUpdatedOnly = false, reportIfNotUpdted = false): Promise<boolean> {
const manifestJson = await this.validateRepository(repositoryPath, false, true);
const noticeTimeout = 10000;
if (manifestJson === null) return false;
const betaManifestJson = await this.validateRepository(repositoryPath, true, false);
const primaryManifest: PluginManifest = betaManifestJson ? betaManifestJson : manifestJson; // if there is a beta manifest, use that
let primaryManifest = await this.validateRepository(repositoryPath, true, false); // attempt to get manifest-beta.json
const usingBetaManifest: boolean = primaryManifest ? true : false;
if(usingBetaManifest===false)
primaryManifest = await this.validateRepository(repositoryPath, false, true); // attempt to get manifest.json

if(!primaryManifest.hasOwnProperty('version')) {
new Notice(`BRAT\n${repositoryPath}\nThe manifest file in the root directory of the repository does not have a version number in the file. This plugin cannot be installed.`, noticeTimeout);
return false;
}

const releaseFiles = await this.getAllReleaseFiles(repositoryPath, primaryManifest)

if (releaseFiles.mainJs === null) {
new Notice(`BRAT\n${repositoryPath}\nThe release is not complete and cannot be download. main.js is missing from the Release`, noticeTimeout);
if(primaryManifest===null) {
new Notice(`BRAT\n${repositoryPath}\nA manifest.json or manifest-beta.json file does not exist in the root directory of the repository. This plugin cannot be installed.`, noticeTimeout);
return false;
}

if (releaseFiles.manifest === null) {
new Notice(`BRAT\n${repositoryPath}\nThe release is not complete and cannot be download. manifest.json is missing from the Release`, noticeTimeout);
if(!primaryManifest.hasOwnProperty('version')) {
new Notice(`BRAT\n${repositoryPath}\nThe manifest${usingBetaManifest ? "-beta" : ""}.json file in the root directory of the repository does not have a version number in the file. This plugin cannot be installed.`, noticeTimeout);
return false;
}
const remoteManifestJSON = JSON.parse(releaseFiles.manifest);

if(!remoteManifestJSON.hasOwnProperty('version')) {
new Notice(`BRAT\n${repositoryPath}\nThe manifest file in the Release does not have a version number in the file. This plugin cannot be installed`, noticeTimeout);
return false;
const getRelease = async ()=>{
const rFiles = await this.getAllReleaseFiles(repositoryPath, primaryManifest, usingBetaManifest);
if(usingBetaManifest || rFiles.manifest === null) //if beta, use that manifest, or if there is no manifest in release, use the primaryManifest
rFiles.manifest = JSON.stringify(primaryManifest);

if (rFiles.mainJs === null) {
new Notice(`BRAT\n${repositoryPath}\nThe release is not complete and cannot be download. main.js is missing from the Release`, noticeTimeout);
return null;
}
return rFiles;
}

if (updatePluginFiles === false) {
await this.writeReleaseFilesToPluginFolder(remoteManifestJSON.id, releaseFiles);
const releaseFiles = await getRelease();
if (releaseFiles===null) return;
await this.writeReleaseFilesToPluginFolder(primaryManifest.id, releaseFiles);
await addBetaPluginToList(this.plugin, repositoryPath);
new Notice(`BRAT\n${repositoryPath}\nThe plugin has been installed and now needs to be enabled in Community Plugins in Settings. First refresh community plugins and then enable this plugin`, noticeTimeout);
//@ts-ignore
const appPlugins = this.plugin.app.plugins;
await appPlugins.loadManifests();
await appPlugins.enablePlugin(primaryManifest.id);
new Notice(`BRAT\n${repositoryPath}\nThe plugin has been installed.`, noticeTimeout);
} else {
// test if the plugin needs to be updated
const pluginTargetFolderPath = this.plugin.app.vault.configDir + "/plugins/" + remoteManifestJSON.id + "/";
const pluginTargetFolderPath = this.plugin.app.vault.configDir + "/plugins/" + primaryManifest.id + "/";
let localManifestContents = null;
try {
localManifestContents = await this.plugin.app.vault.adapter.read(pluginTargetFolderPath + "manifest.json")
} catch (e) {
if (e.errno === -4058) { // file does not exist, try installing the plugin
await this.addPlugin(repositoryPath, false);
await this.addPlugin(repositoryPath, false, usingBetaManifest);
return true; // even though failed, return true since install will be attempted
}
else
console.log("BRAT - Local Manifest Load", remoteManifestJSON.id, JSON.stringify(e, null, 2));
console.log("BRAT - Local Manifest Load", primaryManifest.id, JSON.stringify(e, null, 2));
}
const localManifestJSON = await JSON.parse(localManifestContents);
if (localManifestJSON.version !== remoteManifestJSON.version) { //manifest files are not the same, do an update
if (localManifestJSON.version !== primaryManifest.version) { //manifest files are not the same, do an update
const releaseFiles = await getRelease();
if (releaseFiles===null) return;

if (seeIfUpdatedOnly) { // dont update, just report it
new Notice(`BRAT\nThere is an update available for ${remoteManifestJSON.id}`);
new Notice(`BRAT\nThere is an update available for ${primaryManifest.id}`);
} else {
await this.writeReleaseFilesToPluginFolder(remoteManifestJSON.id, releaseFiles);
await this.reloadPlugin(remoteManifestJSON.id)
new Notice(`BRAT\n${remoteManifestJSON.id}\nplugin has been updated and reloaded`, noticeTimeout);
await this.writeReleaseFilesToPluginFolder(primaryManifest.id, releaseFiles);
await this.reloadPlugin(primaryManifest.id)
new Notice(`BRAT\n${primaryManifest.id}\nplugin has been updated and reloaded`, noticeTimeout);
}
} else
if (reportIfNotUpdted) new Notice(`BRAT\nNo update available for ${repositoryPath}`, 3000);
Expand Down
3 changes: 2 additions & 1 deletion src/githubUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ const GITHUB_RAW_USERCONTENT_PATH = "https://raw.githubusercontent.com/";
* @return {Promise<string>} contents of file as string from the repository's release
*/
export const grabReleaseFileFromRepository = async (repository: string, version: string, fileName: string): Promise<string> => {
const URL = `https://github.com/${repository}/releases/download/${version}/${fileName}`;
try {
const download = await request({ url: `https://github.com/${repository}/releases/download/${version}/${fileName}` });
const download = await request({ url: URL });
return ( ( download === "Not Found" || download === `{"error":"Not Found"}`) ? null : download);
} catch (error) {
console.log("error in grabReleaseFileFromRepository", error)
Expand Down
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class ThePlugin extends Plugin {
betaPlugins: BetaPlugins;

async onload(): Promise<void> {
console.log("loading " + this.appName);
console.log("loading Obsidian42 - BRAT");
await this.loadSettings();
this.addSettingTab(new SettingsTab(this.app, this));

Expand Down

0 comments on commit 274cba8

Please sign in to comment.