Skip to content
This repository has been archived by the owner on Jun 20, 2022. It is now read-only.

Commit

Permalink
fix: autoupdate packages
Browse files Browse the repository at this point in the history
  • Loading branch information
moughxyz committed Jan 16, 2022
1 parent cb22fac commit 9453fb7
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
with:
snapcraft_token: ${{ secrets.SNAPCRAFT_TOKEN }}
- run: yarn setup
- run: yarn build appimage-x64
- run: node scripts/build.mjs appimage-x64
- uses: actions/upload-artifact@v2
with:
name: 'AppImage'
Expand Down
90 changes: 65 additions & 25 deletions app/javascripts/main/packageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,28 @@ import {
FileDoesNotExist,
readJSONFile,
} from './fileUtils';
import { downloadFile } from './networking';
import { downloadFile, getJSON } from './networking';
import { Paths } from './paths';
import { AppName } from './strings';
import { timeout } from './utils';
import log from 'electron-log';

function log(...message: any) {
console.log('PackageManager:', ...message);
function logMessage(...message: any) {
log.info('PackageManager:', ...message);
}

function logError(...message: any) {
console.error('PackageManager:', ...message);
}

type PackageInfo = {
identifier: string;
version: string;
download_url: string;
latest_url: string;
url: string;
};

/* eslint-disable camelcase */
interface Component {
uuid: string;
Expand All @@ -33,11 +42,7 @@ interface Component {
name?: string;
autoupdateDisabled: boolean;
local_url?: string;
package_info: {
identifier: string;
version: string;
download_url: string;
};
package_info: PackageInfo;
};
}
/* eslint-enable camelcase */
Expand Down Expand Up @@ -138,7 +143,7 @@ export async function initializePackageManager(
async (_event, data: { componentsData: Component[] }) => {
const components = data.componentsData;

log(
logMessage(
'received sync event for:',
components
.map(
Expand Down Expand Up @@ -254,14 +259,14 @@ async function syncComponents(
components.map(async (component) => {
if (component.deleted) {
/** Uninstall */
log(`Uninstalling ${component.content?.name}`);
logMessage(`Uninstalling ${component.content?.name}`);
await uninstallComponent(mapping, component.uuid);
return;
}

// eslint-disable-next-line camelcase
if (!component.content?.package_info) {
log('Package info is null, skipping');
logMessage('Package info is null, skipping');
return;
}

Expand All @@ -271,7 +276,13 @@ async function syncComponents(
/**
* We have a component but it is not mapped to anything on the file system
*/
await installComponent(webContents, mapping, component, version);
await installComponent(
webContents,
mapping,
component,
component.content.package_info,
version
);
} else {
try {
/** Will trigger an error if the directory does not exist. */
Expand All @@ -282,7 +293,13 @@ async function syncComponents(
} catch (error: any) {
if (error.code === FileDoesNotExist) {
/** We have a component but no content. Install the component */
await installComponent(webContents, mapping, component, version);
await installComponent(
webContents,
mapping,
component,
component.content.package_info,
version
);
} else {
throw error;
}
Expand All @@ -300,37 +317,53 @@ async function checkForUpdate(
const installedVersion = await mapping.getInstalledVersionForComponent(
component
);
const latestVersion = component.content!.package_info.version;
log(

const latestUrl = component.content?.package_info?.latest_url;
if (!latestUrl) {
return;
}

const latestJson = (await getJSON(latestUrl)) as PackageInfo;
if (!latestJson) {
return;
}

const latestVersion = latestJson.version;
logMessage(
`Checking for update for ${component.content?.name}\n` +
`Latest: ${latestVersion} | Installed: ${installedVersion}`
);

if (compareVersions(latestVersion, installedVersion) === 1) {
/** Latest version is greater than installed version */
log(
'Downloading new version',
component.content!.package_info.download_url
logMessage('Downloading new version', latestVersion);
await installComponent(
webContents,
mapping,
component,
latestJson,
latestVersion
);
await installComponent(webContents, mapping, component, latestVersion);
}
}

async function installComponent(
webContents: Electron.WebContents,
mapping: MappingFileHandler,
component: Component,
packageInfo: PackageInfo,
version: string
) {
if (!component.content) {
return;
}
const downloadUrl = component.content.package_info.download_url;
const downloadUrl = packageInfo.download_url;
if (!downloadUrl) {
return;
}
const name = component.content.name;

log('Installing ', name, downloadUrl);
logMessage('Installing ', name, downloadUrl);

const sendInstalledMessage = (
component: Component,
Expand All @@ -339,7 +372,7 @@ async function installComponent(
if (error) {
logError(`Error when installing component ${name}: ` + error.message);
} else {
log(`Installed component ${name} (${version})`);
logMessage(`Installed component ${name} (${version})`);
}
webContents.send(IpcMessages.InstallComponentComplete, {
component,
Expand All @@ -349,7 +382,7 @@ async function installComponent(

const paths = pathsForComponent(component);
try {
log(`Downloading from ${downloadUrl}`);
logMessage(`Downloading from ${downloadUrl}`);
/** Download the zip and clear the component's directory in parallel */
await Promise.all([
downloadFile(downloadUrl, paths.downloadPath),
Expand All @@ -360,7 +393,7 @@ async function installComponent(
})(),
]);

log('Extracting', paths.downloadPath, 'to', paths.absolutePath);
logMessage('Extracting', paths.downloadPath, 'to', paths.absolutePath);
await extractNestedZip(paths.downloadPath, paths.absolutePath);

let main = 'index.html';
Expand All @@ -380,11 +413,18 @@ async function installComponent(
}

component.content.local_url = 'sn://' + paths.relativePath + '/' + main;
component.content.package_info.download_url = packageInfo.download_url;
component.content.package_info.latest_url = packageInfo.latest_url;
component.content.package_info.url = packageInfo.url;
component.content.package_info.version = packageInfo.version;
mapping.set(component.uuid, paths.relativePath, version);

sendInstalledMessage(component);
} catch (error: any) {
log(`Error while installing ${component.content.name}`, error.message);
logMessage(
`Error while installing ${component.content.name}`,
error.message
);

/**
* Waiting five seconds prevents clients from spamming install requests
Expand Down
2 changes: 2 additions & 0 deletions test/packageManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ function fakeComponent({ deleted = false, modifier = '' } = {}) {
version,
identifier: identifier + modifier,
download_url: 'https://standardnotes.com',
url: 'https://standardnotes.com',
latest_url: 'https://standardnotes.com',
},
},
};
Expand Down

0 comments on commit 9453fb7

Please sign in to comment.