Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Temporary workaround for CCI-Tools/cate#568
Browse files Browse the repository at this point in the history
  • Loading branch information
forman committed Apr 20, 2018
1 parent a5c0323 commit 2eb0de4
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 97 deletions.
141 changes: 93 additions & 48 deletions src/main/setup.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import * as electron from "electron";
import * as log from "electron-log";
import * as url from "url";
import * as fs from "fs";
import * as path from "path";
import {CATE_EXECUTABLES, CONDA_EXECUTABLES, getAppIconPath} from "./appenv";
import {ifInternet} from "./dnsutil";
import * as electron from 'electron';
import * as log from 'electron-log';
import * as url from 'url';
import * as fs from 'fs';
import * as path from 'path';
import { CATE_EXECUTABLES, CONDA_EXECUTABLES, getAppIconPath } from './appenv';
import { ifInternet } from './dnsutil';
import {
CATE_MODE_CONDA_DIR,
CATE_MODE_NEW_CATE_DIR, CATE_MODE_OLD_CATE_DIR, SETUP_MODE_AUTO, SETUP_REASON_INSTALL_CATE,
SETUP_REASON_UPDATE_CATE,
SetupInfo,
SetupOptions, SetupResult
} from "../common/setup";
import {DownloadMiniconda, InstallCondaEnv, InstallMiniconda, InstallOrUpdateCate} from "./update-backend";
import {TransactionError, TransactionProgress, TransactionSet} from "../common/transaction";
} from '../common/setup';
import { DownloadMiniconda, InstallCondaEnv, InstallMiniconda, InstallOrUpdateCate } from './update-backend';
import { TransactionError, TransactionProgress, TransactionSet } from '../common/transaction';
import BrowserWindow = Electron.BrowserWindow;


Expand Down Expand Up @@ -41,28 +41,28 @@ export function doSetup(setupInfo: SetupInfo, callback: (result?: SetupResult) =
slashes: true
}));
setupWindow.webContents.on('did-finish-load', () => {
setupWindow.webContents.send("setSetupInfo", setupInfo);
setupWindow.webContents.send('setSetupInfo', setupInfo);
});
if (process.env.NODE_ENV === 'development') {
setupWindow.webContents.openDevTools();
}
setupWindow.on('close', () => callback());
electron.ipcMain.on("cancelSetup", cancelSetup(setupWindow, callback));
electron.ipcMain.on("endSetup", endSetup(setupWindow, callback));
electron.ipcMain.on("browseNewCateDir", browseNewCateDir);
electron.ipcMain.on("browseOldCateDir", browseOldCateDir);
electron.ipcMain.on("browseCondaDir", browseCondaDir);
electron.ipcMain.on("validateNewCateDir", validateNewCateDir);
electron.ipcMain.on("validateOldCateDir", validateOldCateDir);
electron.ipcMain.on("validateCondaDir", validateCondaDir);
electron.ipcMain.on("performSetupTasks", performSetupTasks);
electron.ipcMain.on('cancelSetup', cancelSetup(setupWindow, callback));
electron.ipcMain.on('endSetup', endSetup(setupWindow, callback));
electron.ipcMain.on('browseNewCateDir', browseNewCateDir);
electron.ipcMain.on('browseOldCateDir', browseOldCateDir);
electron.ipcMain.on('browseCondaDir', browseCondaDir);
electron.ipcMain.on('validateNewCateDir', validateNewCateDir);
electron.ipcMain.on('validateOldCateDir', validateOldCateDir);
electron.ipcMain.on('validateCondaDir', validateCondaDir);
electron.ipcMain.on('performSetupTasks', performSetupTasks);
}).catch(() => {
const messageBoxOptions = {
type: "error",
type: 'error',
title: dialogTitle,
icon: getAppIconPath() as any,
message: "Internet connection required.",
detail: "Cate Desktop requires performing some setup tasks for which additional online resources are needed.",
message: 'Internet connection required.',
detail: 'Cate Desktop requires performing some setup tasks for which additional online resources are needed.',
};
electron.dialog.showMessageBox(messageBoxOptions, quitApp);
});
Expand All @@ -87,13 +87,13 @@ function cancelSetup(setupWindow: BrowserWindow, callback: (setupResult: SetupRe

return (event, inProgress: boolean) => {
if (inProgress) {
let title = "Cate Desktop Setup";
let title = 'Cate Desktop Setup';
electron.dialog.showMessageBox(setupWindow, {
title,
detail: `${title} is currently in progress. If you cancel now, won't be able to use Cate.`,
detail: `${title} is currently in progress. If you cancel now, you won't be able to use Cate.`,
message: `Really cancel ${title}?`,
type: "question",
buttons: ["Yes", "No"],
type: 'question',
buttons: ['Yes', 'No'],
}, (response => {
if (response === 0) {
endSetupImpl(setupWindow, callback, null);
Expand All @@ -107,31 +107,31 @@ function cancelSetup(setupWindow: BrowserWindow, callback: (setupResult: SetupRe

function browseNewCateDir(event, newCateDir: string) {
browseDir(event,
"browseNewCateDir-response",
"Select Cate Installation Directory",
'browseNewCateDir-response',
'Select Cate Installation Directory',
newCateDir);
}

function browseOldCateDir(event, oldCateDir: string) {
browseDir(event,
"browseOldCateDir-response",
"Select Cate Installation Directory",
'browseOldCateDir-response',
'Select Cate Installation Directory',
oldCateDir);
}

function browseCondaDir(event, condaDir: string) {
browseDir(event,
"browseCondaDir-response",
"Select Anaconda/Miniconda Installation Directory",
'browseCondaDir-response',
'Select Anaconda/Miniconda Installation Directory',
condaDir);
}

function browseDir(event, channel: string, title: string, defaultPath: string) {
const options: electron.OpenDialogOptions = {
title,
defaultPath,
properties: ["createDirectory", "openDirectory", "showHiddenFiles"],
buttonLabel: "Select",
properties: ['createDirectory', 'openDirectory', 'showHiddenFiles'],
buttonLabel: 'Select',
};
electron.dialog.showOpenDialog(options, (filePaths: string[]) => {
const dirPath = (filePaths && filePaths.length) ? filePaths[0] : null;
Expand All @@ -142,11 +142,11 @@ function browseDir(event, channel: string, title: string, defaultPath: string) {
}

function validateNewCateDir(event, newCateDir: string) {
const channel = "validateNewCateDir-response";
if (validateAbsoluteDir(event, channel, newCateDir)) {
const channel = 'validateNewCateDir-response';
if (validateAbsoluteDir(event, channel, CATE_MODE_NEW_CATE_DIR, newCateDir, true)) {
fs.access(newCateDir, fs.constants.O_DIRECTORY | fs.constants.R_OK | fs.constants.W_OK, (err) => {
if (err) {
if (err.code === "ENOENT") {
if (err.code === 'ENOENT') {
event.sender.send(channel, null);
} else {
event.sender.send(channel, `${newCateDir} has access restrictions`);
Expand All @@ -167,26 +167,71 @@ function validateNewCateDir(event, newCateDir: string) {
}

function validateOldCateDir(event, oldCateDir: string) {
const channel = "validateOldCateDir-response";
if (validateAbsoluteDir(event, channel, oldCateDir)) {
const channel = 'validateOldCateDir-response';
if (validateAbsoluteDir(event, channel, CATE_MODE_OLD_CATE_DIR, oldCateDir, true)) {
validateExecutables(event, channel, oldCateDir, CATE_EXECUTABLES);
}
}

function validateCondaDir(event, condaDir: string) {
const channel = "validateCondaDir-response";
if (validateAbsoluteDir(event, channel, condaDir)) {
const channel = 'validateCondaDir-response';
if (validateAbsoluteDir(event, channel, CATE_MODE_CONDA_DIR, condaDir, true)) {
validateExecutables(event, channel, condaDir, CONDA_EXECUTABLES);
}
}

function validateAbsoluteDir(event, channel: string, dirPath: string): boolean {
if (!dirPath || dirPath === "") {
event.sender.send(channel, `Directory must be given`);
function validateAbsoluteDir(event, channel: string, mode: string, dirPath: string, noSpaces?: boolean): boolean {
let dirTitle;
if (mode === CATE_MODE_NEW_CATE_DIR) {
dirTitle = 'Cate installation directory';
} else if (mode === CATE_MODE_OLD_CATE_DIR) {
dirTitle = 'Existing Cate installation directory';
} else if (mode === CATE_MODE_CONDA_DIR) {
dirTitle = 'Anaconda/Miniconda installation directory';
} else {
dirTitle = 'Directory';
}

if (!dirPath || dirPath === '') {
event.sender.send(channel, `${dirTitle} must be given.`);
return false;
}
if (!path.isAbsolute(dirPath)) {
event.sender.send(channel, `Directory path must be absolute`);
event.sender.send(channel, `${dirTitle} path must be absolute.`);
return false;
}

// TODO (forman): the following code is a sad workaround for "Cate package installer fails with spaces in user name"
// See https://github.com/CCI-Tools/cate/issues/568
//
//let spaceChar = 'Norman';
let spaceChar = ' ';
if (noSpaces && dirPath.includes(spaceChar)) {
let parts = dirPath.split(path.sep);
let index = -1;
parts.forEach((part: string, i: number) => {
if (part.includes(spaceChar)) {
index = i;
}
});
if (index >= 0) {
let spaceInUserName = false;
if (index === 2) {
spaceInUserName = (process.platform === 'win32' || process.platform === 'darwin')
&& parts[1] === 'Users'
|| parts[1] === 'home';

}
let errorMessage;
if (spaceInUserName) {
errorMessage = 'Your user name appears to contain a space character.';
} else {
errorMessage = `${dirTitle} path must not contain spaces.`;
}
errorMessage += ' Cate is known not work properly in this case. ' +
'We are working on a solution. Sorry!';
event.sender.send(channel, errorMessage);
}
return false;
}
return true;
Expand All @@ -208,7 +253,7 @@ function validateExecutables(event, channel: string, dirPath: string, executable
}

export function performSetupTasks(event, setupInfo: SetupInfo, setupOptions: SetupOptions) {
const channel = "performSetupTasks-response";
const channel = 'performSetupTasks-response';

const {newCateVersion} = setupInfo;
const {newCateDir, oldCateDir, condaDir} = setupOptions;
Expand Down Expand Up @@ -236,7 +281,7 @@ export function performSetupTasks(event, setupInfo: SetupInfo, setupOptions: Set
const installOrUpdateCate = new InstallOrUpdateCate(newCateVersion, installCondaEnv.getCondaEnvDir(), [installCondaEnv.id]);
transactions = [installCondaEnv, installOrUpdateCate];
} else {
event.sender.send(channel, {message: "Internal error: illegal cate setup mode: " + cateMode});
event.sender.send(channel, {message: 'Internal error: illegal cate setup mode: ' + cateMode});
return;
}

Expand Down
Loading

0 comments on commit 2eb0de4

Please sign in to comment.