Merged 1.1.x_branch into master

This commit is contained in:
2020-02-11 17:45:03 -06:00
21 changed files with 130 additions and 85 deletions

View File

@@ -1,4 +1,10 @@
# Changelog # Changelog
## 1.1.3
* CentOS 8 support
* Support remote send and receive timeouts
* Support WinFSP mount manager
* Fix `spawn()` failure on Windows when paths contain spaces
## 1.1.2 ## 1.1.2
* Style changes * Style changes

View File

@@ -12,7 +12,7 @@ Repertory allows you to mount Sia and/or ScPrime blockchain storage solutions vi
* **Repertory UI v1.1.2 Linux 64-bit** [<Primary\>](https://pixeldrain.com/u/5i1mA1gb) [<Alternate\>](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.1.2_linux_x86_64.AppImage) * **Repertory UI v1.1.2 Linux 64-bit** [<Primary\>](https://pixeldrain.com/u/5i1mA1gb) [<Alternate\>](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.1.2_linux_x86_64.AppImage)
* NOTE: Linux distributions require `fuse` and `libfuse` to be installed. * NOTE: Linux distributions require `fuse` and `libfuse` to be installed.
* **Repertory UI v1.1.2 OS X 64-bit** [<Primary\>](https://pixeldrain.com/u/jEWmNDRX) [<Alternate\>](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.1.2_mac.dmg) * **Repertory UI v1.1.2 OS X 64-bit** [<Primary\>](https://pixeldrain.com/u/jEWmNDRX) [<Alternate\>](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.1.2_mac.dmg)
* **Repertory UI v1.1.2 Windows 64-bit** [<Primary\>](https://pixeldrain.com/u/TkQn25Bm) [<Alternate\>](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.1.2_win.exe) * **Repertory UI v1.1.3 Windows 64-bit** [<Primary\>](https://pixeldrain.com/u/xyfCGfcM) [<Alternate\>](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.1.3_win.exe)
## Supported Platforms ## Supported Platforms
* OS X 64-bit * OS X 64-bit
@@ -23,6 +23,7 @@ Repertory allows you to mount Sia and/or ScPrime blockchain storage solutions vi
* Arch Linux * Arch Linux
* Bodhi 5.0.0 * Bodhi 5.0.0
* CentOS 7 * CentOS 7
* CentOS 8
* Debian 9 * Debian 9
* Debian 10 * Debian 10
* Elementary OS 5.0 * Elementary OS 5.0

View File

@@ -19,7 +19,7 @@ if beginsWith darwin "$OSTYPE"; then
JQ_EXEC=jq-osx-amd64 JQ_EXEC=jq-osx-amd64
SHA256_EXEC="shasum -a 256 -b" SHA256_EXEC="shasum -a 256 -b"
else else
DISTRO_LIST="arch centos7 debian9 debian10 fedora28 fedora29 fedora30 fedora31 opensuse15 opensuse15.1 solus tumbleweed ubuntu18.04 ubuntu18.10 ubuntu19.04 ubuntu19.10" DISTRO_LIST="arch centos7 centos8 debian9 debian10 fedora28 fedora29 fedora30 fedora31 opensuse15 opensuse15.1 solus tumbleweed ubuntu18.04 ubuntu18.10 ubuntu19.04 ubuntu19.10"
OUT_FILE=repertory-ui_${APP_VER}_linux_x86_64.AppImage OUT_FILE=repertory-ui_${APP_VER}_linux_x86_64.AppImage
BASE64_EXEC="base64 -w0" BASE64_EXEC="base64 -w0"
JQ_EXEC=jq-linux64 JQ_EXEC=jq-linux64

View File

@@ -1,38 +1,42 @@
{ {
"name": "repertory-ui", "name": "repertory-ui",
"version": "1.1.2", "version": "1.1.3",
"private": true, "private": true,
"author": "scott.e.graves@protonmail.com", "author": "scott.e.graves@protonmail.com",
"description": "GUI for Repertory - Repertory allows you to mount Sia and/or ScPrime blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows.", "description": "GUI for Repertory - Repertory allows you to mount Sia and/or ScPrime blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows.",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.25", "@fortawesome/fontawesome-svg-core": "^1.2.27",
"@fortawesome/free-solid-svg-icons": "^5.11.2", "@fortawesome/free-solid-svg-icons": "^5.12.1",
"@fortawesome/react-fontawesome": "^0.1.7", "@fortawesome/react-fontawesome": "^0.1.8",
"@reduxjs/toolkit": "^1.2.4",
"auto-launch": "^5.0.5", "auto-launch": "^5.0.5",
"axios": "^0.19.0", "axios": "^0.19.2",
"devtron": "^1.4.0", "devtron": "^1.4.0",
"electron-debug": "^3.0.1", "electron-debug": "^3.0.1",
"electron-log": "^4.0.6",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"node-schedule": "^1.3.2", "node-schedule": "^1.3.2",
"randomstring": "^1.1.5", "randomstring": "^1.1.5",
"react": "^16.11.0", "react": "^16.12.0",
"react-dom": "^16.11.0", "react-dom": "^16.12.0",
"react-loader-spinner": "^3.1.4", "react-loader-spinner": "^3.1.5",
"react-redux": "^7.1.3", "react-redux": "^7.1.3",
"react-scripts": "3.2.0", "react-scripts": "3.3.1",
"react-tooltip": "^3.11.1", "react-tooltip": "^4.0.3",
"redux": "^4.0.4", "redux": "^4.0.5",
"redux-starter-kit": "^1.0.1",
"redux-thunk": "^2.3.0", "redux-thunk": "^2.3.0",
"unzipper": "^0.10.5", "unzipper": "^0.10.8",
"winreg": "^1.2.4" "winreg": "^1.2.4"
}, },
"devDependencies": { "devDependencies": {
"cross-env": "^6.0.3", "cross-env": "^7.0.0",
"electron": "^5.0.12", "electron": "^5.0.13",
"electron-builder": "^20.44.4", "electron-builder": "^20.44.4",
"extract-text-webpack-plugin": "^3.0.2", "extract-text-webpack-plugin": "^3.0.2",
"typescript": "^3.7.2", "fibers": "^4.0.2",
"node-sass": "^4.13.1",
"sass": "^1.25.0",
"typescript": "^3.7.5",
"webpack-browser-plugin": "^1.0.20" "webpack-browser-plugin": "^1.0.20"
}, },
"scripts": { "scripts": {

View File

@@ -13,6 +13,9 @@ if [ -f /etc/centos-release ]; then
if [ "$VERSION_ID" = "7" ]; then if [ "$VERSION_ID" = "7" ]; then
DISTNAME=centos DISTNAME=centos
DISTVER=7 DISTVER=7
elif [ "$VERSION_ID" = "8" ]; then
DISTNAME=centos
DISTVER=8
else else
resetDistVer resetDistVer
fi fi

View File

@@ -20,6 +20,13 @@
] ]
} }
}, },
"centos8": {
"1.1.3": {
"sha256": "",
"sig": "",
"urls": []
}
},
"darwin": { "darwin": {
"1.1.2": { "1.1.2": {
"sha256": "0c9c4de2006ecc4ecc6166af979cc5e0b66212472d21c542d4198013e354e275", "sha256": "0c9c4de2006ecc4ecc6166af979cc5e0b66212472d21c542d4198013e354e275",
@@ -171,14 +178,12 @@
} }
}, },
"win32": { "win32": {
"1.1.2": { "sha256": "7fd80d416da1b8ba1fdf29dd317d2939a08ff94b6555f34c0bbbccc0c0bf5c69",
"sha256": "2534a2aa350d4ed1786c4b1cd298ccc987fae226850a1a8bd6d54a8fac39295c", "sig": "A82EF0Ejt98Dwwpp5S32LNIRE6rycHgpwrdqPQae/LtpO7fyuD0RR0YZQkUDGbSbrCgrO/CleI4STjBx48aIv0UKGSyZtO0bfAuMc2gj0zWTBPHRI2mtZGo+tZSrg9lmIJQ8X0xeSH/18cuwOGHmd031+eOKAJ920kz4gN0TYpr77nnJNVRW4+X2T5BNtDETntuIwH5bt8cZfSRB9pHHpOOMdIuJOAMIttwIY6G8Bz1YteyD1U7KU0GdGcMZHldO1v3b55vw2HAWElOJ1d9XK3gVK8jAQerFsuBx6hfzYxqtKpO1uIDxJnWvt7k95vuUJkPFIHcZKACBX8sM55DCoD2XARXkmrn7bIibEBwqKfg0RsNOt8E0lSbLSuHancGJcAvIMuS6Y32tyCY+ofU/OrU2rLzKc2kWYZagg1drshlAsJDIybUhOtH7bkbf8HSpkeXFYJe8bHDbzDFVM9W2u9tkTbYOM+AW96iyEmabt9zPy0xsYt2Za+lRcur0+z/B1sKegUJjquXVjbnGt1OXETwVEJt4NbGuV0gvGUseAUaToK3VaVDwq0/mIlFgfAMXn6jqCQNCOsIQfTwmfXDxObx/ijXF0h6u1+aRVzbS6Y8cPVqOfZMT3T2j/IEtL71C+vPc13QFiP0iQbFabjHQ5PLHC5HdXw3cAQNWOTWVnSn0IUf2SlVunReS+opVw4s5asIgm5KbUbbfJjnPdU1OSU1uMd0l19bU2Tx3s3i99/DWgR5t1ZvRXHeCLonunI/gb93p2QQ0sLISaR5qq3QEiTeXnqFXvRgjqFm3RBvkWE3+njOUWuWcK7T3S0Pf/U9gBkKwhvScLjZRP3bNHuwJOrFtP+/NBWOXbAF+BqBUYZ6BtuUjTJIjEGCwlRzsM9VH0p+2kh5HxdNmWxPR6LRskZ6jnZWzyLp99/xmbYJk4bfPgFTEnK54V6WTCNzaYVeSXVJrBxW2cZMSQSvaU8Q6mUzdWbIDSeeU/XU1mW9RxkhG99H8oGRWRlir8lp1Xm1RyJekEhRSvbgtn398OyyzkGZikrzMInhsCNYAV/XwoCcm1+tf0RAawUOR6zMR5UvnRhgmnrMQcua7xElLTV+GwnbY3rCxkevjMTjenxtz3Xokw5FWytoD8nCJbTRN026ZlVVYxT5ROGDc/R0Z56b18xoHgMxIZWKzhUbsRKzyjyrqU7Wkc4V0XmYcm55xNZExxmMDLiLyMPUTgNK2xYnsya46PpgAzPbIhgF0Fpa0xhB1Ekwb/v3/d6OhhoroJ2l21CjhPVPtDoHZEUBn7C980VDA/hNrFT2ijGV3zHyw8snzCKX1Cb6VZ/IW3GJG3SaPuITtVtzTSnXUKIAtXYAem5o=",
"sig": "Azsov3SYmN/+I3ojIAtYubfEctxD+0QgtgmeubXnjMacb1us8Lu9hFb2wVVd7RGWtsHRmxkpWAi+hUd+gSjM9ahPbm164uq2licspNWeaGJFsQ6LDT6htKz0mQAyfZB9UrKCZrfFKDMXji85GqyUlGu92NlcnXK2tVxMFuB8DHKO+uG97+YisrwvoxLgVSM/9XrjfVEJMcik4URFF1tL5IRksnqA7ccuo++BmoDOcTFvRSky5tNl/KKabEJQLS72FIJI42djBKEn/tE9wxPhBUAa/ya5crOlkD+FgAywoUScbhwcGzg1EMjtDCIDEZrsmfW91jlZmJKDxTv8DaV2MFn97NZVWGWEjU9iOYzd0j4GbNtG58M6YM6ViCJ9fCjSCGrxLS76B9Ra2YShSaJJ6RbD7JiZI86btohiQBbguhvPq16BgRUi35SQCIerASYJTjCys958fSYGd66yfyQNOcFLaTzuvG5nSpbdsakLxAqRzYx+ATYY1lETWk5OMst0pkjIxFid+xw8+/btwlfrtrGx7R7WKAfQJAL/OxvXkhiOZ3aylcdnf8tspOsjUKDGHuznt6HQvdTreUDAVZL6iVL9h+QNEeTw1AISaVqy4+dtGwFGdIxacyt5az9rpnoI9w52cARQiiUyk3I5IGyBF20ia75QXoAOZcaPiBM4yF9gicG8VKW+XFO5FBQCZiktcrNZ0lB8USILjHfRSnITqEZCOKiMRBLQVdJuwa/QxkH3tQfmVFr1FN18ZiImnLITTr2ffiFhXoQTF9NQNGtLHKLe6xvPjPjQm0ZdBKKHw7y5jkkA2mQysvD10ebackP+SLPR7hq3uBhhQsBic4pVDV1GS3UsP/etExzWCwos11MpChRSG5fAmROMiLR1DkvPUJslM4A7Rm+weo91F8+48krxNYRKeJszCWBcRUJnEd5sYI83bJ0RM6+ftl+29YW8QJpVf1tJ0D22yaTI/XgGHusdQircD4vLRKPfkXn8XEApFnLV9knujzXs5vrlQNTFFarXG+f+7E6IeXE+jneaSBXru0XgYyFCy8HRqq5rgMu1SHU5UjdWQyBM1bNGXp8WOOwuDpVbTUHg16TJ99GMbvYNjL9sJNjFcsNcId7b2gNWxo60w9O8C4+GUJrexisjQCZFzL7d/PbKCvHZp1MpliNEEIV43rniY7KUcXUmvLnMrKywj1aYVTRpLDJrtjGEGZ7OeVrxKPR/wPIpV9DD05xyOpYNyamIs5uJyBoBESXUGM+6kWhc5ZO+EJvueVU7OvuqQG8l5YQAbZvLI03jgJLTCyWxvu0zdpsSUtH560zXumuVlbCqJj2XWizP+aCQbqSnvtv1hFxJYv7a9yIgvLc=", "urls": [
"urls": [ "https://pixeldrain.com/api/file/xyfCGfcM",
"https://pixeldrain.com/api/file/TkQn25Bm", "https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.1.3_win.exe"
"https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.1.2_win.exe" ]
]
}
} }
}, },
"Versions": { "Versions": {
@@ -240,7 +245,7 @@
"unavailable" "unavailable"
], ],
"win32": [ "win32": [
"1.1.2" "1.1.3"
] ]
} }
} }

View File

@@ -12,6 +12,8 @@
"RemoteHostNameOrIp": "Host name or IP of host to connect to for remote mounting.", "RemoteHostNameOrIp": "Host name or IP of host to connect to for remote mounting.",
"RemoteMaxConnections": "Maximum number of TCP connections to use when communicating with remote instances.", "RemoteMaxConnections": "Maximum number of TCP connections to use when communicating with remote instances.",
"RemotePort": "TCP port used for remote mounting.", "RemotePort": "TCP port used for remote mounting.",
"RemoteReceiveTimeoutSeconds": "Number of seconds to wait for a response before failing.",
"RemoteSendTimeoutSeconds": "Number of seconds to wait for a request to be written before failing.",
"RemoteToken": "Encryption token used for remote mounts. This value must be the same on local and remote systems." "RemoteToken": "Encryption token used for remote mounts. This value must be the same on local and remote systems."
}, },
"Settings": { "Settings": {
@@ -21,8 +23,10 @@
"ChunkDownloaderTimeoutSeconds": "Files that are not cached locally will download data in ChunkSize chunks when a read or write operation occurs. This timeout value specifies the amount of time chunks should continue downloading after the last file handle has been closed.", "ChunkDownloaderTimeoutSeconds": "Files that are not cached locally will download data in ChunkSize chunks when a read or write operation occurs. This timeout value specifies the amount of time chunks should continue downloading after the last file handle has been closed.",
"ChunkSize": "This is the minimum data size (converted to KiB - value of 8 means 8KiB) used for downloads. This value cannot be less than 8 and should also be a multiple of 8.", "ChunkSize": "This is the minimum data size (converted to KiB - value of 8 means 8KiB) used for downloads. This value cannot be less than 8 and should also be a multiple of 8.",
"EnableChunkDownloaderTimeout": "This setting applies to full allocation downloads. When set to true, downloads will timeout after ChunkDownloaderTimeoutSeconds if the file has no more open handles. If set to false, the entire file will always download.", "EnableChunkDownloaderTimeout": "This setting applies to full allocation downloads. When set to true, downloads will timeout after ChunkDownloaderTimeoutSeconds if the file has no more open handles. If set to false, the entire file will always download.",
"EnableCommDurationEvents": "Debug setting. Enable this to log API call durations.",
"EnableDriveEvents": "When set to true, additional logging for FUSE on UNIX or WinFSP on Windows will occur. It's best to leave this value set to 'false' unless troubleshooting an issue as enabling it may have an adverse affect on performance.", "EnableDriveEvents": "When set to true, additional logging for FUSE on UNIX or WinFSP on Windows will occur. It's best to leave this value set to 'false' unless troubleshooting an issue as enabling it may have an adverse affect on performance.",
"EnableMaxCacheSize": "If set to true, files will begin to be removed from the local cache as soon as MaxCacheSizeBytes and MinimumRedundancy have been met. This does not mean further attempts to write will fail when MaxCacheSizeBytes is reached. Writes will continue as long as there is enough local drive space to accommodate the operation.\n\nIf set to false, files will begin to be removed from the local cache as soon as MinimumRedundancy has been met.\n\nIn both cases, files that do not have any open handles will be chosen by oldest modification date for removal.", "EnableMaxCacheSize": "If set to true, files will begin to be removed from the local cache as soon as MaxCacheSizeBytes and MinimumRedundancy have been met. This does not mean further attempts to write will fail when MaxCacheSizeBytes is reached. Writes will continue as long as there is enough local drive space to accommodate the operation.\n\nIf set to false, files will begin to be removed from the local cache as soon as MinimumRedundancy has been met.\n\nIn both cases, files that do not have any open handles will be chosen by oldest modification date for removal.",
"EnableMountManager": "[EXPERIMENTAL]\n\nEnabling this setting will allow all users and background services to have access to the mounted location. By default, only the user executing the mount has access to the drive.\n\nNOTE:Requires UAC Administrator elevation.",
"EventLevel": "Internally, events are fired during certain operations. This setting determines which events should be logged to repertory.log. Valid values are Error, Warn, Normal, Debug, and Verbose.", "EventLevel": "Internally, events are fired during certain operations. This setting determines which events should be logged to repertory.log. Valid values are Error, Warn, Normal, Debug, and Verbose.",
"EvictionDelaySeconds": "Number of seconds to wait after all file handles are closed before allowing file to be evicted from cache.", "EvictionDelaySeconds": "Number of seconds to wait after all file handles are closed before allowing file to be evicted from cache.",
"EvictionDelayMinutes": "Number of minutes to wait after all file handles are closed before allowing file to be evicted from cache.", "EvictionDelayMinutes": "Number of minutes to wait after all file handles are closed before allowing file to be evicted from cache.",

View File

@@ -235,7 +235,7 @@ class Configuration extends IPCContainer {
JSON.parse(itemList.find(s => s.label === 'EnableRemoteMount').value); JSON.parse(itemList.find(s => s.label === 'EnableRemoteMount').value);
return (item.label === 'RemoteHostNameOrIp') || (item.label === 'RemoteMaxConnections') ? return (item.label === 'RemoteHostNameOrIp') || (item.label === 'RemoteMaxConnections') ?
isRemoteMount : isRemoteMount :
(item.label === 'RemotePort') || (item.label === 'RemoteToken') ? (item.label === 'RemoteReceiveTimeoutSeconds') || (item.label === 'RemoteSendTimeoutSeconds') || (item.label === 'RemotePort') || (item.label === 'RemoteToken') ?
isRemoteMount || enableRemoteMount : isRemoteMount || enableRemoteMount :
(item.label === 'EnableRemoteMount') ? (item.label === 'EnableRemoteMount') ?
!isRemoteMount : !isRemoteMount :

View File

@@ -8,12 +8,15 @@ const spawn = require('child_process').spawn;
const Constants = require('./constants'); const Constants = require('./constants');
const RandomString = require('randomstring'); const RandomString = require('randomstring');
const _executeProcess = (command, args=[]) => { const _executeProcess = (command, working, args=[]) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const processOptions = { let processOptions = {
detached: true, detached: true,
shell: false, shell: false,
}; };
if (working) {
processOptions.cwd = working;
}
const process = new spawn(command, args, processOptions); const process = new spawn(command, args, processOptions);
const pid = process.pid; const pid = process.pid;
@@ -30,12 +33,16 @@ const _executeProcess = (command, args=[]) => {
}); });
}; };
const _execProcessGetOutput = (cmd, args) => { const _execProcessGetOutput = (cmd, working, args) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const proc = spawn(cmd, args, { let processOptions = {
env: process.env, env: process.env,
stdio: ['ignore', 'pipe', 'pipe'] stdio: ['ignore', 'pipe', 'pipe']
}); };
if (working) {
processOptions.cwd = working;
}
const proc = spawn(cmd, args, processOptions);
let output; let output;
proc.stdout.on('data', data => { proc.stdout.on('data', data => {
@@ -74,7 +81,10 @@ const _getDefaultRepertoryArgs = (provider, remote) => {
}; };
const _getRepertoryExec = version => { const _getRepertoryExec = version => {
return path.join(_getDataDirectory(), version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory'); return {
cmd: (os.platform() === 'win32') ? 'repertory.exe' : 'repertory',
working: path.join(_getDataDirectory(), version),
};
}; };
const _resolvePath = str => { const _resolvePath = str => {
@@ -97,17 +107,17 @@ const _tryParse = (j, def) => {
module.exports.checkDaemonVersion = (version, provider) => { module.exports.checkDaemonVersion = (version, provider) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const repertoryExec = _getRepertoryExec(version);
const processOptions = { const processOptions = {
cwd: repertoryExec.working,
detached: true, detached: true,
shell: false, shell: false,
windowsHide: true, windowsHide: true,
}; };
const command = _getRepertoryExec(version);
const args = _getDefaultRepertoryArgs(provider, false); const args = _getDefaultRepertoryArgs(provider, false);
args.push('-cv'); args.push('-cv');
const process = new spawn(repertoryExec.cmd, args, processOptions);
const process = new spawn(command, args, processOptions);
process.on('error', err => { process.on('error', err => {
reject(err); reject(err);
@@ -159,17 +169,18 @@ module.exports.detectRepertoryMounts = (version, providerList) => {
resolve(mountState); resolve(mountState);
} else { } else {
const provider = providerList[index]; const provider = providerList[index];
const repertoryExec = _getRepertoryExec(version);
const processOptions = { const processOptions = {
cwd: repertoryExec.working,
detached: true, detached: true,
shell: false, shell: false,
windowsHide: true, windowsHide: true,
}; };
const command = _getRepertoryExec(version);
const args = _getDefaultRepertoryArgs(provider, !Constants.PROVIDER_LIST.includes(provider)); const args = _getDefaultRepertoryArgs(provider, !Constants.PROVIDER_LIST.includes(provider));
args.push('-status'); args.push('-status');
const process = new spawn(command, args, processOptions); const process = new spawn(repertoryExec.cmd, args, processOptions);
let result = ''; let result = '';
process.on('error', (err) => { process.on('error', (err) => {
@@ -277,15 +288,20 @@ module.exports.executeAndWait = (command, ignoreResult) => {
module.exports.executeAsync = (command, args=[]) => { module.exports.executeAsync = (command, args=[]) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const launchProcess = (count, timeout) => { const launchProcess = (count, timeout) => {
const processOptions = { const cmd = path.basename(command);
const working = cmd.length === command.length ? null : command.substr(0, command.length - cmd.length);
let processOptions = {
detached: true, detached: true,
shell: false, shell: false,
}; };
if (working) {
processOptions.cwd = working;
}
const process = new spawn(command, args, processOptions); const process = new spawn(cmd, args, processOptions);
const pid = process.pid; const pid = process.pid;
process.on('error', (err) => { process.on('error', err => {
if (++count === 5) { if (++count === 5) {
reject(err, pid); reject(err, pid);
} else { } else {
@@ -345,13 +361,14 @@ module.exports.executeScript = script => {
module.exports.executeMount = (version, provider, remote, location, noConsoleSupported, exitCallback) => { module.exports.executeMount = (version, provider, remote, location, noConsoleSupported, exitCallback) => {
return new Promise((resolve) => { return new Promise((resolve) => {
const repertoryExec = _getRepertoryExec(version);
const processOptions = { const processOptions = {
cwd: repertoryExec.working,
detached: false, detached: false,
shell: os.platform() !== 'darwin', shell: os.platform() !== 'darwin',
stdio: 'ignore', stdio: 'ignore',
}; };
const command = _getRepertoryExec(version);
const args = _getDefaultRepertoryArgs(provider, remote); const args = _getDefaultRepertoryArgs(provider, remote);
if ((os.platform() === 'linux') || (os.platform() === 'darwin')) { if ((os.platform() === 'linux') || (os.platform() === 'darwin')) {
@@ -366,7 +383,7 @@ module.exports.executeMount = (version, provider, remote, location, noConsoleSup
} }
args.push(location); args.push(location);
let process = new spawn(command, args, processOptions); let process = new spawn(repertoryExec.cmd, args, processOptions);
const pid = process.pid; const pid = process.pid;
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
@@ -387,17 +404,18 @@ module.exports.executeMount = (version, provider, remote, location, noConsoleSup
module.exports.getConfig = (version, provider, remote) => { module.exports.getConfig = (version, provider, remote) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const repertoryExec = _getRepertoryExec(version);
const processOptions = { const processOptions = {
cwd: repertoryExec.working,
detached: true, detached: true,
shell: false, shell: false,
windowsHide: true, windowsHide: true,
}; };
const command = _getRepertoryExec(version);
const args = _getDefaultRepertoryArgs(provider, remote); const args = _getDefaultRepertoryArgs(provider, remote);
args.push('-dc'); args.push('-dc');
const process = new spawn(command, args, processOptions); const process = new spawn(repertoryExec.cmd, args, processOptions);
let result = ''; let result = '';
process.on('error', (err) => { process.on('error', (err) => {
@@ -430,17 +448,18 @@ module.exports.getConfig = (version, provider, remote) => {
module.exports.getConfigTemplate = (version, provider, remote) => { module.exports.getConfigTemplate = (version, provider, remote) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const repertoryExec = _getRepertoryExec(version);
const processOptions = { const processOptions = {
cwd: repertoryExec.working,
detached: true, detached: true,
shell: false, shell: false,
windowsHide: true, windowsHide: true,
}; };
const command = _getRepertoryExec(version);
const args = _getDefaultRepertoryArgs(provider, remote); const args = _getDefaultRepertoryArgs(provider, remote);
args.push('-gt'); args.push('-gt');
const process = new spawn(command, args, processOptions); const process = new spawn(repertoryExec.cmd, args, processOptions);
let result = ''; let result = '';
process.on('error', (err) => { process.on('error', (err) => {
@@ -579,7 +598,7 @@ module.exports.performWindowsUninstall = names => {
} else { } else {
const cmd = path.join(process.env.windir, 'system32', 'reg.exe'); const cmd = path.join(process.env.windir, 'system32', 'reg.exe');
const args = ["QUERY", "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"]; const args = ["QUERY", "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"];
_execProcessGetOutput(cmd, args) _execProcessGetOutput(cmd, null, args)
.then(lines => { .then(lines => {
const parseLine = index => { const parseLine = index => {
if (index < lines.length) { if (index < lines.length) {
@@ -591,13 +610,13 @@ module.exports.performWindowsUninstall = names => {
args2.push('DisplayName'); args2.push('DisplayName');
args2.push('/t'); args2.push('/t');
args2.push('REG_SZ'); args2.push('REG_SZ');
_execProcessGetOutput(cmd, args2) _execProcessGetOutput(cmd, null, args2)
.then(lines => { .then(lines => {
const value = lines[2].trim().substr(args2[3].length).trim().substr(6).trim(); const value = lines[2].trim().substr(args2[3].length).trim().substr(6).trim();
if (names.includes(value)) { if (names.includes(value)) {
const items = line.split('\\'); const items = line.split('\\');
const productCode = items[items.length - 1]; const productCode = items[items.length - 1];
_executeProcess('msiexec.exe', ['/x', productCode, '/norestart']) _executeProcess('msiexec.exe', null,['/x', productCode, '/norestart'])
.then(code => { .then(code => {
if ((code === 0) || (code === 3010) || (code === 1641)) { if ((code === 0) || (code === 3010) || (code === 1641)) {
resolve(true); resolve(true);
@@ -651,19 +670,20 @@ module.exports.resolvePath = _resolvePath;
module.exports.setConfigValue = (name, value, provider, remote, version) => { module.exports.setConfigValue = (name, value, provider, remote, version) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const repertoryExec = _getRepertoryExec(version);
const processOptions = { const processOptions = {
cwd: repertoryExec.working,
detached: true, detached: true,
shell: false, shell: false,
windowsHide: true, windowsHide: true,
}; };
const command = _getRepertoryExec(version);
const args = _getDefaultRepertoryArgs(provider, remote); const args = _getDefaultRepertoryArgs(provider, remote);
args.push('-set'); args.push('-set');
args.push(name); args.push(name);
args.push(value); args.push(value);
const process = new spawn(command, args, processOptions); const process = new spawn(repertoryExec.cmd, args, processOptions);
process.on('error', (err) => { process.on('error', (err) => {
reject(err); reject(err);
@@ -679,17 +699,18 @@ module.exports.setConfigValue = (name, value, provider, remote, version) => {
module.exports.stopMountProcess = (version, provider, remote) => { module.exports.stopMountProcess = (version, provider, remote) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const repertoryExec = _getRepertoryExec(version);
const processOptions = { const processOptions = {
cwd: repertoryExec.working,
detached: os.platform() === 'darwin', detached: os.platform() === 'darwin',
shell: os.platform() !== 'darwin', shell: os.platform() !== 'darwin',
windowsHide: true, windowsHide: true,
}; };
const command = _getRepertoryExec(version);
const args = _getDefaultRepertoryArgs(provider, remote); const args = _getDefaultRepertoryArgs(provider, remote);
args.push('-unmount'); args.push('-unmount');
const process = new spawn(command, args, processOptions); const process = new spawn(repertoryExec.cmd, args, processOptions);
const pid = process.pid; const pid = process.pid;
process.on('error', (err) => { process.on('error', (err) => {
reject(err); reject(err);
@@ -708,24 +729,25 @@ module.exports.stopMountProcess = (version, provider, remote) => {
}; };
module.exports.stopMountProcessSync = (version, provider, remote) => { module.exports.stopMountProcessSync = (version, provider, remote) => {
const repertoryExec = _getRepertoryExec(version);
const processOptions = { const processOptions = {
cwd: repertoryExec.working,
detached: true, detached: true,
shell: os.platform() !== 'darwin', shell: os.platform() !== 'darwin',
windowsHide: true, windowsHide: true,
}; };
const command = _getRepertoryExec(version);
const args = _getDefaultRepertoryArgs(provider, remote); const args = _getDefaultRepertoryArgs(provider, remote);
args.push('-unmount'); args.push('-unmount');
const process = new spawn(command, args, processOptions); const process = new spawn(repertoryExec.cmd, args, processOptions);
process.unref(); process.unref();
}; };
module.exports.testRepertoryBinary = version => { module.exports.testRepertoryBinary = version => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const command = _getRepertoryExec(version); const repertoryExec = _getRepertoryExec(version);
_executeProcess(command, ['-dc']) _executeProcess(repertoryExec.cmd, repertoryExec.working, ['-dc'])
.then(code => { .then(code => {
if (code === 0) { if (code === 0) {
resolve(); resolve();

View File

@@ -1,5 +1,5 @@
import * as Constants from '../../constants'; import * as Constants from '../../constants';
import {createAction} from 'redux-starter-kit'; import {createAction} from '@reduxjs/toolkit';
import {getIPCRenderer} from '../../utils'; import {getIPCRenderer} from '../../utils';
const ipcRenderer = getIPCRenderer(); const ipcRenderer = getIPCRenderer();

View File

@@ -1,5 +1,5 @@
import * as Constants from '../../constants'; import * as Constants from '../../constants';
import {createAction} from 'redux-starter-kit'; import {createAction} from '@reduxjs/toolkit';
import {getIPCRenderer} from '../../utils'; import {getIPCRenderer} from '../../utils';
import {notifyError} from './error_actions'; import {notifyError} from './error_actions';
import { import {

View File

@@ -1,5 +1,5 @@
import * as Constants from '../../constants'; import * as Constants from '../../constants';
import {createAction} from 'redux-starter-kit'; import {createAction} from '@reduxjs/toolkit';
import { import {
getIPCRenderer, getIPCRenderer,
getSelectedVersionFromState getSelectedVersionFromState

View File

@@ -1,5 +1,5 @@
import * as Constants from '../../constants'; import * as Constants from '../../constants';
import {createAction} from 'redux-starter-kit'; import {createAction} from '@reduxjs/toolkit';
import {getIPCRenderer} from '../../utils'; import {getIPCRenderer} from '../../utils';
import { import {
confirmYesNo, confirmYesNo,

View File

@@ -1,6 +1,6 @@
import axios from 'axios'; import axios from 'axios';
import * as Constants from '../../constants'; import * as Constants from '../../constants';
import {createAction} from 'redux-starter-kit'; import {createAction} from '@reduxjs/toolkit';
import {notifyError} from './error_actions'; import {notifyError} from './error_actions';
import { import {
saveState, saveState,

View File

@@ -1,4 +1,4 @@
import {createReducer} from 'redux-starter-kit'; import {createReducer} from '@reduxjs/toolkit';
import { import {
DISPLAY_CONFIRM_YES_NO, DISPLAY_CONFIRM_YES_NO,
notifyRebootRequired, notifyRebootRequired,

View File

@@ -1,4 +1,4 @@
import {createReducer} from 'redux-starter-kit'; import {createReducer} from '@reduxjs/toolkit';
import { import {
setAllowDownload, setAllowDownload,
SET_DOWNLOAD_BEGIN, SET_DOWNLOAD_BEGIN,

View File

@@ -1,4 +1,4 @@
import {createReducer} from 'redux-starter-kit'; import {createReducer} from '@reduxjs/toolkit';
import { import {
CLEAR_ERROR, CLEAR_ERROR,
CLEAR_INFO, CLEAR_INFO,

View File

@@ -1,4 +1,4 @@
import {createReducer} from 'redux-starter-kit'; import {createReducer} from '@reduxjs/toolkit';
import { import {
setDismissDependencies, setDismissDependencies,
setInstallActive, setInstallActive,

View File

@@ -1,5 +1,5 @@
import * as Constants from '../../constants'; import * as Constants from '../../constants';
import {createReducer} from 'redux-starter-kit'; import {createReducer} from '@reduxjs/toolkit';
import { import {
addRemoteMount2, addRemoteMount2,
DISPLAY_CONFIGURATION, DISPLAY_CONFIGURATION,

View File

@@ -1,4 +1,4 @@
import {createReducer} from 'redux-starter-kit'; import {createReducer} from '@reduxjs/toolkit';
import * as Actions from '../actions/release_version_actions'; import * as Actions from '../actions/release_version_actions';
import * as Constants from '../../constants'; import * as Constants from '../../constants';

View File

@@ -1,4 +1,4 @@
import {configureStore, getDefaultMiddleware} from 'redux-starter-kit'; import {configureStore, getDefaultMiddleware} from '@reduxjs/toolkit';
import {createCommonReducer} from '../reducers/common_reducer'; import {createCommonReducer} from '../reducers/common_reducer';
import {downloadReducer} from '../reducers/download_reducer'; import {downloadReducer} from '../reducers/download_reducer';
import {errorReducer} from '../reducers/error_reducer'; import {errorReducer} from '../reducers/error_reducer';