diff --git a/.vim/coc-settings.json b/.vim/coc-settings.json new file mode 100644 index 0000000..ae5fe8f --- /dev/null +++ b/.vim/coc-settings.json @@ -0,0 +1,14 @@ +{ + "cSpell.words": [ + "HKEY", + "HKLM", + "Redistributable", + "Skylinks", + "Skynet", + "Unmount", + "msiexec", + "relver", + "siaprime", + "skylink" + ] +} \ No newline at end of file diff --git a/.vimrc b/.vimrc index 756e065..cbde2c6 100644 --- a/.vimrc +++ b/.vimrc @@ -1,2 +1,7 @@ set autoread set path+=.,public/**,src/**,test/** +if has('win32') + let &makeprg="create_dist.cmd" +else + let &makeprg="./create_dist.sh" +endif diff --git a/CHANGELOG.md b/CHANGELOG.md index 579c72b..3fd50b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ * \#48: Support pinning files to cache * Fixed Skynet export display * Properly detect existing remote +* Reduced number of Linux binaries to: + * CentOS 7 + * Solus +* S3 mount support [disabled] ## 1.3.1 * \#45: Skynet mount support @@ -17,8 +21,6 @@ * CentOS 7 * Debian 9 * Debian 10 - * Debian 9 ARM64 - * Debian 10 ARM64 * Solus * Added `FocusTrap` to modals diff --git a/README.md b/README.md index 02ce061..2de01f6 100644 --- a/README.md +++ b/README.md @@ -24,32 +24,16 @@ Repertory allows you to mount Sia, Skynet and/or ScPrime blockchain storage solu * Antergos * Arch Linux * Bodhi 5.0.0 - * CentOS 7 - * CentOS 8 - * Debian 9 - * Debian 10 - * Elementary OS 5.0 - * Elementary OS 5.1 - * Fedora 28 - * Fedora 29 - * Fedora 30 - * Fedora 31 - * Fedora 32 - * Fedora 33 - * Linux Mint 19 - * Linux Mint 19.1 - * Linux Mint 19.2 - * Linux Mint 19.3 + * CentOS 7, 8 + * Debian 9, 10 + * Elementary OS 5.0, 5.1 + * Fedora 28, 29, 30, 31, 32, 33 + * Linux Mint 19, 19.1, 19.2, 19.3, 20, 20.1 * Manjaro - * OpenSUSE Leap 15.0 - * OpenSUSE Leap 15.1 + * OpenSUSE Leap 15.0, 15.1 * OpenSUSE Tumbleweed * Solus - * Ubuntu 18.04 - * Ubuntu 18.10 - * Ubuntu 19.04 - * Ubuntu 19.10 - * Ubuntu 20.04 + * Ubuntu 18.04, 18.10, 19.04, 19.10, 20.04 ## Issues/Suggestions Please submit [here](https://bitbucket.org/blockstorage/repertory-ui/issues?status=new&status=open) diff --git a/public/detect_linux.sh b/public/detect_linux.sh old mode 100644 new mode 100755 index 12c0ebb..3ff1631 --- a/public/detect_linux.sh +++ b/public/detect_linux.sh @@ -8,104 +8,23 @@ resetDistVer() { DISTVER= } -if [ -f /etc/centos-release ]; then - . /etc/os-release - if [ "$VERSION_ID" = "7" ]; then - DISTNAME=centos - DISTVER=7 - elif [ "$VERSION_ID" = "8" ]; then - DISTNAME=debian - DISTVER=10 - else - resetDistVer - fi -elif [ -f /etc/fedora-release ]; then - . /etc/os-release - if [ "$VERSION_ID" != "33" ] && "$VERSION_ID" != "32" ] && [ "$VERSION_ID" != "31" ] && [ "$VERSION_ID" != "30" ] && [ "$VERSION_ID" != "29" ] && [ "$VERSION_ID" != "28" ]; then - resetDistVer - else - DISTNAME=debian - if [ "$VERSION_ID" = "28" ]; then - DISTVER=9 - else - DISTVER=10 - fi - fi -elif [ -f /etc/solus-release ]; then - DISTNAME=solus -elif [ -f /etc/lsb-release ]; then - . /etc/lsb-release - DISTNAME=$(echo ${DISTRIB_ID} | awk '{print tolower($0)}') - DISTVER=${DISTRIB_RELEASE} - if [ "$DISTNAME" != "ubuntu" ]; then - if [ "$DISTNAME" = "linuxmint" ]; then - if [ "$DISTVER" = "19" ] || [ "$DISTVER" = "19.1" ] || [ "$DISTVER" = "19.2" ] || [ "$DISTVER" = "19.3" ]; then - DISTNAME=debian - DISTVER=9 - else - resetDistVer - fi - elif [ "$DISTNAME" = "elementary" ]; then - if [ "$DISTVER" = "5.0" ] || [ "$DISTVER" = "5.1" ]; then - DISTNAME=debian - DISTVER=9 - else - resetDistVer - fi - else - resetDistVer - fi - elif [ "$DISTVER" != "18.04" ] && [ "$DISTVER" != "18.10" ] && [ "$DISTVER" != "19.04" ] && [ "$DISTVER" != "19.10" ] && [ "$DISTVER" != "20.04" ] && [ "$DISTVER" != "20.10" ]; then - resetDistVer - else - DISTNAME=debian - if [ "$DISTVER" = "18.04" ]; then - DISTVER=9 - else - DISTVER=10 - fi - fi -fi +IS_ARM=`(uname -a | grep aarch64) 1>/dev/null 2>&1 && echo 1` -if [ "$DISTNAME" = "unknown" ] && [ -f /etc/debian_version ]; then +if [ -f /etc/solus-release ]; then + DISTNAME=solus +elif [ "$IS_ARM" = "1" ] && [ -f /etc/debian_version ]; then DISTNAME=debian DISTVER=$(head -1 /etc/debian_version|awk -F. '{print $1}') if [ "$DISTVER" != "9" ] && [ "$DISTVER" != "10" ]; then - resetDistVer - fi -fi - -if [ "$DISTNAME" = "unknown" ]; then - if [ -f /etc/os-release ]; then - . /etc/os-release - if [ "$ID" = "arch" ]; then - DISTNAME=debian - DISTVER=10 - elif [ "$ID" = "antergos" ] || [ "$ID" = "manjaro" ]; then - DISTNAME=debian - DISTVER=9 - elif [ "$ID" = "opensuse-leap" ]; then - if [ "$VERSION_ID" = "15.0" ]; then - DISTNAME=debian - DISTVER=9 - elif [ "$VERSION_ID" = "15.1" ]; then - DISTNAME=debian - DISTVER=9 - elif [ "$VERSION_ID" = "15.2" ]; then - DISTNAME=debian - DISTVER=9 - else - resetDistVer - fi - elif [ "$ID" = "opensuse-tumbleweed" ]; then - DISTNAME=debian + if [ $(grep sid /etc/debian_version) ]; then DISTVER=10 else resetDistVer fi - else - resetDistVer fi +else + DISTNAME=centos7 + DISTVER= fi echo ${DISTNAME}${DISTVER} diff --git a/releases.json b/releases.json index c754ff6..a54f85a 100644 --- a/releases.json +++ b/releases.json @@ -18,24 +18,6 @@ ] } }, - "debian9": { - "1.3.2": { - "sha256": "", - "sig": "", - "urls": [ - "https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.3.2_linux_x86_64.AppImage" - ] - } - }, - "debian10": { - "1.3.2": { - "sha256": "", - "sig": "", - "urls": [ - "https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.3.2_linux_x86_64.AppImage" - ] - } - }, "solus": { "1.3.2": { "sha256": "", @@ -62,12 +44,6 @@ "darwin": [ "1.3.2" ], - "debian9": [ - "1.3.2" - ], - "debian10": [ - "1.3.2" - ], "linux": [ "unavailable" ], diff --git a/src/App.js b/src/App.js deleted file mode 100644 index a853042..0000000 --- a/src/App.js +++ /dev/null @@ -1,340 +0,0 @@ -import React from 'react'; -import './App.css'; -import Box from './components/UI/Box/Box'; -import Configuration from './containers/Configuration/Configuration'; -import {connect} from 'react-redux'; -import DependencyList from './components/DependencyList/DependencyList'; -import DownloadProgress from './components/DownloadProgress/DownloadProgress'; -import ErrorDetails from './components/ErrorDetails/ErrorDetails'; -import Grid from './components/UI/Grid/Grid'; -import InfoDetails from './components/InfoDetails/InfoDetails'; -import IPCContainer from './containers/IPCContainer/IPCContainer'; -import Loading from './components/UI/Loading/Loading'; -import MountItems from './containers/MountItems/MountItems'; -import NewReleases from './components/NewReleases/NewReleases'; -import {notifyError} from './redux/actions/error_actions'; -import Reboot from './components/Reboot/Reboot'; -import { - setDismissNewReleasesAvailable, - setNewReleasesAvailable -} from './redux/actions/release_version_actions'; -import ReleaseVersionDisplay from './components/ReleaseVersionDisplay/ReleaseVersionDisplay'; -import { - displaySelectAppPlatform, - saveState -} from './redux/actions/common_actions'; -import SelectAppPlatform from './containers/SelectAppPlatform/SelectAppPlatform'; -import Text from './components/UI/Text/Text'; -import UpgradeIcon from './components/UpgradeIcon/UpgradeIcon'; -import UpgradeUI from './components/UpgradeUI/UpgradeUI'; -import { - loadReleases, - setDismissUIUpgrade -} from './redux/actions/release_version_actions'; -import YesNo from './components/YesNo/YesNo'; -import {createModalConditionally} from './utils'; -import SkynetImport from './containers/SkynetImport/SkynetImport'; -import ApplicationBusy from './components/ApplicationBusy/ApplicationBusy'; -import SkynetExport from './containers/SkynetExport/SkynetExport'; -import PinnedManager from './containers/PinnedManager/PinnedManager'; - -const Constants = require('./constants'); -const Scheduler = require('node-schedule'); - -class App extends IPCContainer { - componentDidMount() { - const detectUpgrades = () => { - if (this.props.AppPlatform === 'unknown') { - if (this.props.Platform === 'linux') { - this.props.displaySelectAppPlatform(true); - } else { - this.props.notifyError('Operating system is not supported.', true); - } - } else { - this.props.loadReleases(); - } - }; - detectUpgrades(); - this.scheduledUpdateJob = Scheduler.scheduleJob('23 11 * * *', detectUpgrades); - } - - componentDidUpdate(prevProps) { - if ((prevProps.Release !== this.props.Release) || - (prevProps.ReleaseVersion !== this.props.ReleaseVersion) || - (prevProps.VersionLookup !== this.props.VersionLookup)) { - this.props.saveState(); - } else if (Object.keys(this.props.ProviderState).filter(k => { - return this.props.ProviderState[k] !== prevProps.ProviderState[k]; - }).length > 0) { - this.props.saveState(); - } - } - - componentWillUnmount() { - Scheduler.cancelJob(this.scheduledUpdateJob); - super.componentWillUnmount(); - } - - getSelectedVersion = () => { - return (this.props.ReleaseVersion === -1) ? - 'unavailable' : - this.props.VersionLookup[Constants.RELEASE_TYPES[this.props.Release]][this.props.ReleaseVersion]; - }; - - handleUpgradeIconClicked = () => { - if (this.props.UpgradeAvailable) { - this.props.setDismissUIUpgrade(false) - } else if (this.props.NewReleasesAvailable2.length > 0) { - this.props.setNewReleasesAvailable(this.props.NewReleasesAvailable2); - this.props.setDismissNewReleasesAvailable(false); - } - }; - - render() { - const selectedVersion = this.getSelectedVersion(); - - const downloadEnabled = this.props.AllowDownload && - !this.props.MountsBusy && - !this.props.DownloadActive && - (selectedVersion !== 'unavailable') && - (selectedVersion !== this.props.InstalledVersion); - - const missingDependencies = (this.props.MissingDependencies.length > 0) && - this.props.AllowMount; - - const allowMount = this.props.AllowMount && - this.props.InstalledVersion !== 'none' && - !missingDependencies && - !this.props.InstallActive; - - const remoteSupported = this.props.LocationsLookup[selectedVersion] && - this.props.LocationsLookup[selectedVersion].supports_remote; - - const s3Supported = this.props.LocationsLookup[selectedVersion] && - this.props.LocationsLookup[selectedVersion].s3_support; - - const skynetSupported = this.props.LocationsLookup[selectedVersion] && - this.props.LocationsLookup[selectedVersion].skynet_support; - - const scPrimeSupported = this.props.LocationsLookup[selectedVersion] && - this.props.LocationsLookup[selectedVersion].siaprime_support; - - const siaSupported = this.props.LocationsLookup[selectedVersion] && - this.props.LocationsLookup[selectedVersion].sia_support; - - const showConfig = !missingDependencies && - !this.props.DisplayPinnedManager && - this.props.DisplayConfiguration && - !this.props.RebootRequired; - - const showPinnedManager = !missingDependencies && - !this.props.RebootRequired && - this.props.DisplayPinnedManager; - - const showUpgrade = this.props.UpgradeAvailable && - !this.props.DisplayError && - !showConfig && - !this.props.DownloadActive && - !this.props.UpgradeDismissed && - !this.props.InstallActive && - !this.props.RebootRequired; - - const showDependencies = !showUpgrade && - missingDependencies && - !this.props.DownloadActive && - !this.props.RebootRequired && - !this.props.DismissDependencies && - this.props.AllowMount; - - const showNewReleases = !showConfig && - !this.props.DisplayConfirmYesNo && - !showDependencies && - !this.props.DownloadActive && - !this.props.DisplayError && - !this.props.DisplayInfo && - !this.props.InstallActive && - !this.props.RebootRequired && - !this.props.DisplaySelectAppPlatform && - !showUpgrade && - !this.props.DismissNewReleasesAvailable && - (this.props.NewReleasesAvailable.length > 0); - - const showSkynetImport = !showConfig && - !showDependencies && - !this.props.DownloadActive && - !showNewReleases && - !this.props.RebootRequired && - !this.props.DisplaySelectAppPlatform && - !showUpgrade && - this.props.DisplayImport; - - const showSkynetExport = !showConfig && - !showDependencies && - !this.props.DownloadActive && - !showNewReleases && - !this.props.RebootRequired && - !this.props.DisplaySelectAppPlatform && - !showUpgrade && - this.props.DisplayExport; - - const configDisplay = createModalConditionally(showConfig, ); - const pinnedManagerDisplay = createModalConditionally(showPinnedManager, ) - const confirmDisplay = createModalConditionally(this.props.DisplayConfirmYesNo, ); - const dependencyDisplay = createModalConditionally(showDependencies, - , false, this.props.InstallActive); - const downloadDisplay = createModalConditionally(this.props.DownloadActive, - , false, true); - const errorDisplay = createModalConditionally(this.props.DisplayError, , true); - const infoDisplay = createModalConditionally(this.props.DisplayInfo, , true); - const newReleasesDisplay = createModalConditionally(showNewReleases, ); - const rebootDisplay = createModalConditionally(this.props.RebootRequired, ); - const selectAppPlatformDisplay = createModalConditionally(this.props.DisplaySelectAppPlatform, - ); - const upgradeDisplay = createModalConditionally(showUpgrade, ); - const importDisplay = createModalConditionally(showSkynetImport, ); - const exportDisplay = createModalConditionally(showSkynetExport, ) - const appBusyDisplay = createModalConditionally(this.props.AppBusy, - , false, true, this.props.AppBusyTransparent); - - let mainContent = []; - if (this.props.DisplaySelectAppPlatform || !this.props.AppReady) { - mainContent = ( - - - ); - } else { - let key = 0; - mainContent.push(( - - - - )); - mainContent.push(
); - if (allowMount) { - mainContent.push(( - - - - )); - } else if (selectedVersion !== 'unavailable') { - mainContent.push(( - - - - )); - } - } - - return ( -
-
-
- - - - 0)} - newReleases={!this.props.UpgradeAvailable && (this.props.NewReleasesAvailable2.length > 0)} - clicked={this.handleUpgradeIconClicked} - col={dimensions => dimensions.columns - 6} - colSpan={5} - row={1} - rowSpan={remain => remain - 1}/> - - -
-
- {mainContent} -
-
- {importDisplay} - {exportDisplay} - {newReleasesDisplay} - {selectAppPlatformDisplay} - {dependencyDisplay} - {upgradeDisplay} - {pinnedManagerDisplay} - {configDisplay} - {infoDisplay} - {confirmDisplay} - {downloadDisplay} - {rebootDisplay} - {appBusyDisplay} - {errorDisplay} -
- ); - } -} - -const mapStateToProps = state => { - return { - AllowDownload: state.download.AllowDownload, - AllowMount: state.common.AllowMount, - AppPlatform: state.common.AppPlatform, - AppBusy: state.common.AppBusy, - AppBusyTransparent: state.common.AppBusyTransparent, - AppReady: state.common.AppReady, - DismissDependencies: state.install.DismissDependencies, - DisplayConfiguration: state.mounts.DisplayConfiguration, - DisplayConfirmYesNo: state.common.DisplayConfirmYesNo, - DisplayError: state.error.DisplayError, - DisplayExport: state.skynet.DisplayExport, - DisplayImport: state.skynet.DisplayImport, - DisplayInfo: state.error.DisplayInfo, - DisplayPinnedManager: state.pinned.DisplayPinnedManager, - DisplaySelectAppPlatform: state.common.DisplaySelectAppPlatform, - DismissNewReleasesAvailable: state.relver.DismissNewReleasesAvailable, - DownloadActive: state.download.DownloadActive, - InstallActive: state.install.InstallActive, - InstalledVersion: state.relver.InstalledVersion, - LocationsLookup: state.relver.LocationsLookup, - MissingDependencies: state.install.MissingDependencies, - MountsBusy: state.mounts.MountsBusy, - NewReleasesAvailable: state.relver.NewReleasesAvailable, - NewReleasesAvailable2: state.relver.NewReleasesAvailable2, - Platform: state.common.Platform, - ProviderState: state.mounts.ProviderState, - RebootRequired: state.common.RebootRequired, - Release: state.relver.Release, - ReleaseVersion: state.relver.Version, - UpgradeAvailable: state.relver.UpgradeAvailable, - UpgradeDismissed: state.relver.UpgradeDismissed, - Version: state.common.Version, - VersionLookup: state.relver.VersionLookup, - }; -}; - -const mapDispatchToProps = dispatch => { - return { - displaySelectAppPlatform: display => dispatch(displaySelectAppPlatform(display)), - loadReleases: () => dispatch(loadReleases()), - notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)), - saveState: () => dispatch(saveState()), - setDismissNewReleasesAvailable: dismiss => dispatch(setDismissNewReleasesAvailable(dismiss)), - setNewReleasesAvailable: items => dispatch(setNewReleasesAvailable(items)), - setDismissUIUpgrade: dismiss => dispatch(setDismissUIUpgrade(dismiss)), - }; -}; - -export default connect(mapStateToProps, mapDispatchToProps)(App); diff --git a/src/constants.js b/src/constants.js index 69d948d..47bd3b7 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,48 +1,46 @@ -Object.defineProperty(exports, '__esModule', {value: true}); +Object.defineProperty(exports, '__esModule', {value : true}); exports.DEV_PUBLIC_KEY = - '-----BEGIN PUBLIC KEY-----\n' + - 'MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEKfZmq5mMAtD4kSt2Gc/5J\n' + - 'H+HHTYtUZE6YYvsvz8TNG/bNL67ZtNRyaoMyhLTfIN4rPBNLUfD+owNS+u5Yk+lS\n' + - 'ZLYyOuhoCZIFefayYqKLr42G8EeuRbx0IMzXmJtN0a4rqxlWhkYufJubpdQ+V4DF\n' + - 'oeupcPdIATaadCKVeZC7A0G0uaSwoiAVMG5dZqjQW7F2LoQm3PhNkPvAybIJ6vBy\n' + - 'LqdBegS1JrDn43x/pvQHzLO+l+FIG23D1F7iF+yZm3DkzBdcmi/mOMYs/rXZpBym\n' + - '2/kTuSGh5buuJCeyOwR8N3WdvXw6+KHMU/wWU8qTCTT87mYbzH4YR8HgkjkLHxAO\n' + - '5waHK6vMu0TxugCdJmVV6BSbiarJsh66VRosn7+6hlq6AdgksxqCeNELZBS+LBki\n' + - 'tb5hKyL+jNZnaHiR0U7USWtmnqZG6FVVRzlCnxP7tZo5O5Ex9AAFGz5JzOzsFNbv\n' + - 'xwQ0zqaTQOze+MJbkda7JfRoC6TncD0+3hoXsiaF4mCn8PqUCn0DwhglcRucZlST\n' + - 'ZvDNDo1WAtxPJebb3aS6uymNhBIquQbVAWxVO4eTrOYEgutxwkHE3yO3is+ogp8d\n' + - 'xot7f/+vzlbsbIDyuZBDe0fFkbTIMTU48QuUUVZpRKmKZTHQloz4EHqminbfX1sh\n' + - 'M7wvDkpJEtqbc0VnG/BukUzP6e7Skvgc7eF1sI3+8jH8du2rivZeZAl7Q2f+L9JA\n' + - 'BY9pjaxttxsud7V5jeFi4tKuDHi21/XhSjlJK2c2C4AiUEK5/WhtGbQ5JjmcOjRq\n' + - 'yXFRqLlerzOcop2kbtU3Ar230wOx3Dj23Wg8++lV3LU4U9vMR/t0qnSbCSGJys7m\n' + - 'ax2JpFlTwj/0wYuTlVFoNQHZJ1cdfyRiRBY4Ou7XO0W5hcBBKiYsC+neEeMMHdCe\n' + - 'iTDIW/ojcVTdFovl+sq3n1u4SBknE90JC/3H+TPE1s2iB+fwORVg0KPosQSNDS0A\n' + - '7iK6AZCDC3YooFo+OzHkYMt9uLkXiXMSLx70az+qlIwOzVHKxCo7W/QpeKCXUCRZ\n' + - 'MMdlYEUs1PC8x2qIRUEVHuJ0XMTKNyOHmzVLuLK93wUWbToh+rdDxnbhX+emuESn\n' + - 'XH6aKiUwX4olEVKSylRUQw8nVckZGVWXzLDlgpzDrLHC8J8qHzFt7eCqOdiqsxhZ\n' + - 'x1U5LtugxwSWncTZ7vlKl0DuC/AWB7SuDi7bGRMSVp2n+MnD1VLKlsCclHXjIciE\n' + - 'W29n3G3lJ/sOta2sxqLd0j1XBQddrFXl5b609sIY81ocHqu8P2hRu5CpqJ/sGZC5\n' + - 'mMH3segHBkRj0xJcfOxceRLj1a+ULIIR3xL/3f8s5Id25TDo/nqBoCvu5PeCpo6L\n' + - '9wIDAQAB\n' + - '-----END PUBLIC KEY-----'; + '-----BEGIN PUBLIC KEY-----\n' + + 'MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEKfZmq5mMAtD4kSt2Gc/5J\n' + + 'H+HHTYtUZE6YYvsvz8TNG/bNL67ZtNRyaoMyhLTfIN4rPBNLUfD+owNS+u5Yk+lS\n' + + 'ZLYyOuhoCZIFefayYqKLr42G8EeuRbx0IMzXmJtN0a4rqxlWhkYufJubpdQ+V4DF\n' + + 'oeupcPdIATaadCKVeZC7A0G0uaSwoiAVMG5dZqjQW7F2LoQm3PhNkPvAybIJ6vBy\n' + + 'LqdBegS1JrDn43x/pvQHzLO+l+FIG23D1F7iF+yZm3DkzBdcmi/mOMYs/rXZpBym\n' + + '2/kTuSGh5buuJCeyOwR8N3WdvXw6+KHMU/wWU8qTCTT87mYbzH4YR8HgkjkLHxAO\n' + + '5waHK6vMu0TxugCdJmVV6BSbiarJsh66VRosn7+6hlq6AdgksxqCeNELZBS+LBki\n' + + 'tb5hKyL+jNZnaHiR0U7USWtmnqZG6FVVRzlCnxP7tZo5O5Ex9AAFGz5JzOzsFNbv\n' + + 'xwQ0zqaTQOze+MJbkda7JfRoC6TncD0+3hoXsiaF4mCn8PqUCn0DwhglcRucZlST\n' + + 'ZvDNDo1WAtxPJebb3aS6uymNhBIquQbVAWxVO4eTrOYEgutxwkHE3yO3is+ogp8d\n' + + 'xot7f/+vzlbsbIDyuZBDe0fFkbTIMTU48QuUUVZpRKmKZTHQloz4EHqminbfX1sh\n' + + 'M7wvDkpJEtqbc0VnG/BukUzP6e7Skvgc7eF1sI3+8jH8du2rivZeZAl7Q2f+L9JA\n' + + 'BY9pjaxttxsud7V5jeFi4tKuDHi21/XhSjlJK2c2C4AiUEK5/WhtGbQ5JjmcOjRq\n' + + 'yXFRqLlerzOcop2kbtU3Ar230wOx3Dj23Wg8++lV3LU4U9vMR/t0qnSbCSGJys7m\n' + + 'ax2JpFlTwj/0wYuTlVFoNQHZJ1cdfyRiRBY4Ou7XO0W5hcBBKiYsC+neEeMMHdCe\n' + + 'iTDIW/ojcVTdFovl+sq3n1u4SBknE90JC/3H+TPE1s2iB+fwORVg0KPosQSNDS0A\n' + + '7iK6AZCDC3YooFo+OzHkYMt9uLkXiXMSLx70az+qlIwOzVHKxCo7W/QpeKCXUCRZ\n' + + 'MMdlYEUs1PC8x2qIRUEVHuJ0XMTKNyOHmzVLuLK93wUWbToh+rdDxnbhX+emuESn\n' + + 'XH6aKiUwX4olEVKSylRUQw8nVckZGVWXzLDlgpzDrLHC8J8qHzFt7eCqOdiqsxhZ\n' + + 'x1U5LtugxwSWncTZ7vlKl0DuC/AWB7SuDi7bGRMSVp2n+MnD1VLKlsCclHXjIciE\n' + + 'W29n3G3lJ/sOta2sxqLd0j1XBQddrFXl5b609sIY81ocHqu8P2hRu5CpqJ/sGZC5\n' + + 'mMH3segHBkRj0xJcfOxceRLj1a+ULIIR3xL/3f8s5Id25TDo/nqBoCvu5PeCpo6L\n' + + '9wIDAQAB\n' + + '-----END PUBLIC KEY-----'; const REPERTORY_BRANCH = '1.3.x_branch'; const REPERTORY_UI_BRANCH = '1.3.x_branch'; exports.RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory/raw/' + - REPERTORY_BRANCH + '/releases_1.3.json'; + REPERTORY_BRANCH + '/releases_1.3.json'; exports.UI_RELEASES_URL = - 'https://bitbucket.org/blockstorage/repertory-ui/raw/' + - REPERTORY_UI_BRANCH + '/releases.json'; + 'https://bitbucket.org/blockstorage/repertory-ui/raw/' + + REPERTORY_UI_BRANCH + '/releases.json'; exports.LINUX_DETECT_SCRIPT_URL = - 'https://bitbucket.org/blockstorage/repertory/raw/' + REPERTORY_BRANCH + - '/detect_linux2.sh'; + 'https://bitbucket.org/blockstorage/repertory/raw/' + REPERTORY_BRANCH + + '/detect_linux2.sh'; exports.LINUX_SELECTABLE_PLATFORMS = [ 'centos7', - 'debian9', - 'debian10', ]; exports.WINFSP_VERSION_NAMES = [ @@ -63,15 +61,15 @@ exports.WINFSP_VERSION_NAMES = [ ]; exports.DATA_LOCATIONS = { - linux: '~/.local/repertory/ui', - darwin: '~/Library/Application Support/repertory/ui', - win32: '%LOCALAPPDATA%\\repertory\\ui' + linux : '~/.local/repertory/ui', + darwin : '~/Library/Application Support/repertory/ui', + win32 : '%LOCALAPPDATA%\\repertory\\ui' }; exports.REPERTORY_LOCATIONS = { - linux: '~/.local/repertory', - darwin: '~/Library/Application Support/repertory', - win32: '%LOCALAPPDATA%\\repertory' + linux : '~/.local/repertory', + darwin : '~/Library/Application Support/repertory', + win32 : '%LOCALAPPDATA%\\repertory' }; exports.S3_PROVIDER_LIST = [ @@ -83,7 +81,7 @@ exports.S3_REGION_PROVIDER_REGION = [ ]; exports.S3_PROVIDER_URL = { - 'Filebase': 'https://s3.filebase.com', + 'Filebase' : 'https://s3.filebase.com', }; exports.PROVIDER_LIST = [ @@ -93,10 +91,10 @@ exports.PROVIDER_LIST = [ ]; exports.PROVIDER_ARG = { - sia: '', - skynet: '-sk', - scprime: '-sp', - s3: '-s3', + sia : '', + skynet : '-sk', + scprime : '-sp', + s3 : '-s3', }; exports.DEFAULT_RELEASE = 0; @@ -108,10 +106,10 @@ exports.RELEASE_TYPES = [ ]; exports.INSTALL_TYPES = { - Dependency: 'dependency', - Release: 'release', - TestRelease: 'test_release', - Upgrade: 'upgrade', + Dependency : 'dependency', + Release : 'release', + TestRelease : 'test_release', + Upgrade : 'upgrade', }; exports.IPC_Browse_Directory = 'browse_directory'; diff --git a/src/helpers.js b/src/helpers.js index 1152e93..8457149 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -18,44 +18,49 @@ const _vcRuntimeExists = () => { resolve(true); } else { 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, null, args) - .then(lines => { - const parseLine = index => { - if (index < lines.length) { - const line = lines[index]; - if (line.startsWith('HKEY_LOCAL_MACHINE\\')) { - let args2 = JSON.parse(JSON.stringify(args)); - args2[1] = 'HKLM\\' + line.substr(19); - args2.push('/v'); - args2.push('DisplayName'); - args2.push('/t'); - args2.push('REG_SZ'); - _execProcessGetOutput(cmd, null, args2) - .then(lines => { - const value = lines[2].trim().substr(args2[3].length).trim().substr(6).trim(); - if (value.includes('Microsoft Visual C++ 2015-2019 Redistributable (x64)')) { - vcRuntimeExists = true; - resolve(true); + .then(lines => { + const parseLine = index => { + if (index < lines.length) { + const line = lines[index]; + if (line.startsWith('HKEY_LOCAL_MACHINE\\')) { + let args2 = JSON.parse(JSON.stringify(args)); + args2[1] = 'HKLM\\' + line.substr(19); + args2.push('/v'); + args2.push('DisplayName'); + args2.push('/t'); + args2.push('REG_SZ'); + _execProcessGetOutput(cmd, null, args2) + .then(lines => { + const value = lines[2] + .trim() + .substr(args2[3].length) + .trim() + .substr(6) + .trim(); + if (value.includes( + 'Microsoft Visual C++ 2015-2019 Redistributable (x64)')) { + vcRuntimeExists = true; + resolve(true); + } else { + parseLine(++index); + } + }) + .catch(() => { parseLine(++index); }); } else { parseLine(++index); } - }) - .catch(() => { - parseLine(++index); - }); - } else { - parseLine(++index); - } - } else { - resolve(false); - } - }; - parseLine(0); - }) - .catch(err => { - reject(err); - }); + } else { + resolve(false); + } + }; + parseLine(0); + }) + .catch(err => { reject(err); }); } } }); @@ -66,48 +71,52 @@ const _createTreeNodes = fileList => { let tree = {} const directorySort = (a, b) => { - return !!a.directory === !!b.directory ? a.name.localeCompare(b.name) : a.directory ? -1 : 1; + return !!a.directory === !!b.directory ? a.name.localeCompare(b.name) + : a.directory ? -1 : 1; }; - const addNode = obj => { - let fullPath; - const idx = obj.skylink.indexOf('/'); - if (idx > -1) { - fullPath = path.join(obj.directory, obj.skylink.substr(idx + 1)).replace(/\\/g, '/'); - } else { - fullPath = path.join(obj.directory, obj.filename).replace(/\\/g, '/'); - } - const pathParts = fullPath.replace(/^\/|\/$/g, '').split('/'); - let ptr = tree; - for (let i = 0; i < pathParts.length; i++) { - const node = { - directory: true, - name: pathParts[i], - }; - if (i === pathParts.length - 1) { - node.directory = false; - node.path = fullPath; + const addNode = + obj => { + let fullPath; + const idx = obj.skylink.indexOf('/'); + if (idx > -1) { + fullPath = path.join(obj.directory, obj.skylink.substr(idx + 1)) + .replace(/\\/g, '/'); + } else { + fullPath = path.join(obj.directory, obj.filename).replace(/\\/g, '/'); + } + const pathParts = fullPath.replace(/^\/|\/$/g, '').split('/'); + let ptr = tree; + for (let i = 0; i < pathParts.length; i++) { + const node = { + directory : true, + name : pathParts[i], + }; + if (i === pathParts.length - 1) { + node.directory = false; + node.path = fullPath; + } + ptr[pathParts[i]] = ptr[pathParts[i]] || node; + ptr[pathParts[i]].children = ptr[pathParts[i]].children || {}; + ptr = ptr[pathParts[i]].children; + } } - ptr[pathParts[i]] = ptr[pathParts[i]] || node; - ptr[pathParts[i]].children = ptr[pathParts[i]].children || {}; - ptr = ptr[pathParts[i]].children; - } - } - const objectToArray = node => { - Object.keys(node || {}).map((k) => { - if (node[k].children) { - objectToArray(node[k]) + const objectToArray = + node => { + Object.keys(node || {}).map((k) => { + if (node[k].children) { + objectToArray(node[k]) + } + }) + if (node.children) { + node.children = Object.values(node.children); + node.children.forEach(objectToArray) + node.children = node.children.sort(directorySort); + } } - }) - if (node.children) { - node.children = Object.values(node.children); - node.children.forEach(objectToArray) - node.children = node.children.sort(directorySort); - } - } - fileList.map(addNode); + fileList.map(addNode); objectToArray(tree); return Object.values(tree).sort(directorySort); }; @@ -116,10 +125,10 @@ const _exportAllSkylinks = version => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; const args = _getDefaultRepertoryArgs('Skynet'); @@ -128,17 +137,11 @@ const _exportAllSkylinks = version => { let result = ''; const process = new spawn(repertoryExec.cmd, args, processOptions); - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); - process.stderr.on('data', (d) => { - result += d; - }); + process.stderr.on('data', (d) => { result += d; }); process.on('exit', code => { if (code === 0) { @@ -156,8 +159,8 @@ const _exportAllSkylinks = version => { const _executeProcess = (command, working, args = []) => { return new Promise((resolve, reject) => { let processOptions = { - detached: true, - shell: false, + detached : true, + shell : false, }; if (working) { processOptions.cwd = working; @@ -166,13 +169,9 @@ const _executeProcess = (command, working, args = []) => { const process = new spawn(command, args, processOptions); const pid = process.pid; - process.on('error', (err) => { - reject(err, pid); - }); + process.on('error', (err) => { reject(err, pid); }); - process.on('exit', (code) => { - resolve(code); - }); + process.on('exit', (code) => { resolve(code); }); process.unref(); }); @@ -181,8 +180,8 @@ const _executeProcess = (command, working, args = []) => { const _execProcessGetOutput = (cmd, working, args) => { return new Promise((resolve, reject) => { let processOptions = { - env: process.env, - stdio: ['ignore', 'pipe', 'pipe'] + env : process.env, + stdio : [ 'ignore', 'pipe', 'pipe' ] }; if (working) { processOptions.cwd = working; @@ -190,18 +189,12 @@ const _execProcessGetOutput = (cmd, working, args) => { const proc = spawn(cmd, args, processOptions); let output; - proc.stdout.on('data', data => { - output += data.toString(); - }); + proc.stdout.on('data', data => { output += data.toString(); }); - proc.on('error', (err) => { - reject(err); - }); + proc.on('error', (err) => { reject(err); }); proc.on('exit', () => { - const lines = output - .replace(/\r\n/g, '\n') - .split('\n'); + const lines = output.replace(/\r\n/g, '\n').split('\n'); resolve(lines); }); @@ -209,9 +202,8 @@ const _execProcessGetOutput = (cmd, working, args) => { }); }; -const _getDataDirectory = () => { - return _resolvePath(Constants.DATA_LOCATIONS[os.platform()]); -}; +const _getDataDirectory = + () => { return _resolvePath(Constants.DATA_LOCATIONS[os.platform()]); }; const _getRepertoryDirectory = () => { return _resolvePath(Constants.REPERTORY_LOCATIONS[os.platform()]); @@ -227,7 +219,8 @@ const _getDefaultRepertoryArgs = (provider, remote, s3) => { } else if (remote) { args.push('-rm'); args.push(provider.substr(6)); - } else if (Constants.PROVIDER_ARG[providerLower] && (Constants.PROVIDER_ARG[providerLower].length > 0)) { + } else if (Constants.PROVIDER_ARG[providerLower] && + (Constants.PROVIDER_ARG[providerLower].length > 0)) { args.push(Constants.PROVIDER_ARG[providerLower]); } return args; @@ -235,16 +228,14 @@ const _getDefaultRepertoryArgs = (provider, remote, s3) => { const _getRepertoryExec = version => { return { - cmd: (os.platform() === 'win32') ? 'repertory.exe' : './repertory', - working: path.join(_getDataDirectory(), version), + cmd : (os.platform() === 'win32') ? 'repertory.exe' : './repertory', + working : path.join(_getDataDirectory(), version), }; }; const _removeDirectoryRecursively = dir => { if (fs.existsSync(dir)) { - fs - .readdirSync(dir) - .forEach(file => { + fs.readdirSync(dir).forEach(file => { const curPath = path.join(dir, file); if (fs.lstatSync(curPath).isDirectory()) { module.exports.removeDirectoryRecursively(curPath); @@ -258,9 +249,7 @@ const _removeDirectoryRecursively = dir => { const _resolvePath = str => { if (os.platform() === 'win32') { - return str.replace(/%([^%]+)%/g, (_, n) => { - return process.env[n]; - }); + return str.replace(/%([^%]+)%/g, (_, n) => { return process.env[n]; }); } else { return str.replace('~', os.homedir()); } @@ -278,23 +267,19 @@ module.exports.checkDaemonVersion = (version, provider) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; const args = _getDefaultRepertoryArgs(provider); args.push('-cv'); const process = new spawn(repertoryExec.cmd, args, processOptions); - process.on('error', err => { - reject(err); - }); + process.on('error', err => { reject(err); }); - process.on('exit', code => { - resolve(code); - }); + process.on('exit', code => { resolve(code); }); process.unref(); }); }; @@ -304,14 +289,13 @@ module.exports.cleanupOldReleases = versionList => { try { if (versionList && versionList.length > 0) { const dataDir = _getDataDirectory(); - const directoryList = fs - .readdirSync(dataDir, {withFileTypes: true}) - .filter(dirent => dirent.isDirectory()) - .map(dirent => dirent); + const directoryList = fs.readdirSync(dataDir, {withFileTypes : true}) + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent); - const removeList = directoryList - .filter(dirent => !versionList.includes(dirent.name)) - .map(dirent => dirent.name); + const removeList = + directoryList.filter(dirent => !versionList.includes(dirent.name)) + .map(dirent => dirent.name); for (const dir of removeList) { try { @@ -330,14 +314,10 @@ module.exports.cleanupOldReleases = versionList => { }; module.exports.createSignatureFiles = (signature, publicKey) => { - const fileName1 = RandomString.generate({ - length: 12, - charset: 'alphabetic' - }); - const fileName2 = RandomString.generate({ - length: 12, - charset: 'alphabetic' - }); + const fileName1 = + RandomString.generate({length : 12, charset : 'alphabetic'}); + const fileName2 = + RandomString.generate({length : 12, charset : 'alphabetic'}); const signatureFile = path.join(os.tmpdir(), fileName1 + '.sig'); const publicKeyFile = path.join(os.tmpdir(), fileName2 + '.pub'); @@ -347,8 +327,8 @@ module.exports.createSignatureFiles = (signature, publicKey) => { fs.writeFileSync(publicKeyFile, publicKey); return { - PublicKeyFile: publicKeyFile, - SignatureFile: signatureFile, + PublicKeyFile : publicKeyFile, + SignatureFile : signatureFile, }; }; @@ -358,9 +338,9 @@ module.exports.detectRepertoryMounts = (version, providerList) => { const defaultData = {}; for (const provider of providerList) { defaultData[provider] = { - Active: false, - Location: '', - PID: -1, + Active : false, + Location : '', + PID : -1, }; } const grabStatus = index => { @@ -370,35 +350,34 @@ module.exports.detectRepertoryMounts = (version, providerList) => { const provider = providerList[index]; const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; - const args = _getDefaultRepertoryArgs(provider, - !Constants.PROVIDER_LIST.includes(provider) && provider.toLowerCase().startsWith('remote'), - !Constants.PROVIDER_LIST.includes(provider) && provider.toLowerCase().startsWith('s3')); + const args = _getDefaultRepertoryArgs( + provider, + !Constants.PROVIDER_LIST.includes(provider) && + provider.toLowerCase().startsWith('remote'), + !Constants.PROVIDER_LIST.includes(provider) && + provider.toLowerCase().startsWith('s3')); args.push('-status'); const process = new spawn(repertoryExec.cmd, args, processOptions); let result = ''; - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); process.on('exit', () => { - mountState[provider] = _tryParse(result, defaultData)[provider] || defaultData; + mountState[provider] = + _tryParse(result, defaultData)[provider] || defaultData; if (mountState[provider].Active && - ((mountState[provider].Location === 'elevating') || (mountState[provider].Location === ''))) { - setTimeout(() => { - grabStatus(index); - }, 2000); + ((mountState[provider].Location === 'elevating') || + (mountState[provider].Location === ''))) { + setTimeout(() => { grabStatus(index); }, 2000); } else { grabStatus(++index); } @@ -410,7 +389,8 @@ module.exports.detectRepertoryMounts = (version, providerList) => { }); }; -module.exports.downloadFile = (url, destination, progressCallback, completeCallback) => { +module.exports.downloadFile = (url, destination, progressCallback, + completeCallback) => { try { if (fs.existsSync(destination)) { fs.unlinkSync(destination); @@ -421,51 +401,48 @@ module.exports.downloadFile = (url, destination, progressCallback, completeCallb } axios - .get(url, { - responseType: 'stream', - }) - .then(response => { - try { - const total = parseInt(response.headers['content-length'], 10); - if (total === 0) { - completeCallback(new Error('No data available for download')); - } else { - const stream = fs.createWriteStream(destination); + .get(url, { + responseType : 'stream', + }) + .then(response => { + try { + const total = parseInt(response.headers['content-length'], 10); + if (total === 0) { + completeCallback(new Error('No data available for download')); + } else { + const stream = fs.createWriteStream(destination); - let downloaded = 0; - response.data.on('data', (chunk) => { - stream.write(Buffer.from(chunk)); - downloaded += chunk.length; - if (progressCallback) { - progressCallback((downloaded / total * 100.0).toFixed(2)); + let downloaded = 0; + response.data.on('data', (chunk) => { + stream.write(Buffer.from(chunk)); + downloaded += chunk.length; + if (progressCallback) { + progressCallback((downloaded / total * 100.0).toFixed(2)); + } + }); + + response.data.on('end', () => { + stream.end(() => { + if (downloaded === 0) { + completeCallback(new Error('Received 0 bytes')); + } else if (downloaded !== total) { + completeCallback( + new Error('Received incorrect number of bytes')); + } else { + completeCallback(); + } + }); + }); + + response.data.on( + 'error', + error => { stream.end(() => { completeCallback(error); }); }); } - }); - - response.data.on('end', () => { - stream.end(() => { - if (downloaded === 0) { - completeCallback(new Error('Received 0 bytes')); - } else if (downloaded !== total) { - completeCallback(new Error('Received incorrect number of bytes')); - } else { - completeCallback(); - } - }); - }); - - response.data.on('error', error => { - stream.end(() => { - completeCallback(error); - }); - }); - } - } catch (error) { - completeCallback(error); - } - }) - .catch(error => { - completeCallback(error); - }); + } catch (error) { + completeCallback(error); + } + }) + .catch(error => { completeCallback(error); }); }; module.exports.executeAndWait = (command, ignoreResult) => { @@ -475,9 +452,7 @@ module.exports.executeAndWait = (command, ignoreResult) => { exec(command, error => { if (error) { if (!ignoreResult && (error.code === 1)) { - setTimeout(() => { - retryExecute(count, error); - }, 1000); + setTimeout(() => { retryExecute(count, error); }, 1000); } else { reject(error); } @@ -497,10 +472,12 @@ module.exports.executeAsync = (command, args = []) => { return new Promise((resolve, reject) => { const launchProcess = (count, timeout) => { let cmd = path.basename(command); - const working = cmd.length === command.length ? null : command.substr(0, command.length - cmd.length); + const working = cmd.length === command.length + ? null + : command.substr(0, command.length - cmd.length); let processOptions = { - detached: true, - shell: false, + detached : true, + shell : false, }; if (working) { processOptions.cwd = working; @@ -517,7 +494,9 @@ module.exports.executeAsync = (command, args = []) => { reject(err, pid); } else { clearTimeout(timeout); - setTimeout(() => launchProcess(count, setTimeout(() => resolve(), 3000)), 1000); + setTimeout( + () => launchProcess(count, setTimeout(() => resolve(), 3000)), + 1000); } }); @@ -527,7 +506,9 @@ module.exports.executeAsync = (command, args = []) => { reject(code, pid); } else { clearTimeout(timeout); - setTimeout(() => launchProcess(count, setTimeout(() => resolve(), 3000)), 1000); + setTimeout( + () => launchProcess(count, setTimeout(() => resolve(), 3000)), + 1000); } } }); @@ -542,85 +523,76 @@ module.exports.executeAsync = (command, args = []) => { module.exports.executeScript = script => { return new Promise((resolve, reject) => { const processOptions = { - detached: false, - shell: true, - windowsHide: true, + detached : false, + shell : true, + windowsHide : true, }; const command = '/bin/sh'; - const args = [ - script - ]; + const args = [ script ]; const process = new spawn(command, args, processOptions); let result = ''; - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); - process.on('exit', () => { - resolve(result); - }); + process.on('exit', () => { resolve(result); }); process.unref(); }); }; -module.exports.executeMount = (version, provider, remote, s3, location, exitCallback) => { - return new Promise((resolve) => { - const repertoryExec = _getRepertoryExec(version); - const processOptions = { - cwd: repertoryExec.working, - detached: false, - shell: os.platform() !== 'darwin', - stdio: 'ignore', +module.exports.executeMount = + (version, provider, remote, s3, location, exitCallback) => { + return new Promise((resolve) => { + const repertoryExec = _getRepertoryExec(version); + const processOptions = { + cwd : repertoryExec.working, + detached : false, + shell : os.platform() !== 'darwin', + stdio : 'ignore', + }; + + const args = _getDefaultRepertoryArgs(provider, remote, s3); + + if ((os.platform() === 'linux') || (os.platform() === 'darwin')) { + args.push('-o'); + args.push('big_writes'); + args.push('-f'); + args.push('-nc'); + } else if (os.platform() === 'win32') { + args.push('-hidden'); + } + args.push(location); + + let process = new spawn(repertoryExec.cmd, args, processOptions); + const pid = process.pid; + + const timeout = setTimeout(() => { resolve(pid); }, 3000); + + process.on('error', (err) => { + clearTimeout(timeout); + exitCallback(err, pid); + }); + + process.on('exit', (code) => { + clearTimeout(timeout); + exitCallback(code, pid); + }); + }); }; - const args = _getDefaultRepertoryArgs(provider, remote, s3); - - if ((os.platform() === 'linux') || (os.platform() === 'darwin')) { - args.push('-o'); - args.push('big_writes'); - args.push('-f'); - args.push('-nc'); - } else if (os.platform() === 'win32') { - args.push('-hidden'); - } - args.push(location); - - let process = new spawn(repertoryExec.cmd, args, processOptions); - const pid = process.pid; - - const timeout = setTimeout(() => { - resolve(pid); - }, 3000); - - process.on('error', (err) => { - clearTimeout(timeout); - exitCallback(err, pid); - }); - - process.on('exit', (code) => { - clearTimeout(timeout); - exitCallback(code, pid); - }); - }); -}; - module.exports.exportAllSkylinks = _exportAllSkylinks; module.exports.exportSkylinks = (version, paths) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; const args = _getDefaultRepertoryArgs('Skynet'); @@ -630,17 +602,11 @@ module.exports.exportSkylinks = (version, paths) => { let result = ''; const process = new spawn(repertoryExec.cmd, args, processOptions); - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); - process.stderr.on('data', (d) => { - result += d; - }); + process.stderr.on('data', (d) => { result += d; }); process.on('exit', code => { if (code === 0) { @@ -659,10 +625,10 @@ module.exports.getConfig = (version, provider, remote, s3) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; const args = _getDefaultRepertoryArgs(provider, remote, s3); @@ -671,25 +637,19 @@ module.exports.getConfig = (version, provider, remote, s3) => { const process = new spawn(repertoryExec.cmd, args, processOptions); let result = ''; - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); process.on('exit', () => { - const lines = result - .replace(/\r\n/g, '\n') - .split('\n'); + const lines = result.replace(/\r\n/g, '\n').split('\n'); const code = parseInt(lines[0], 10); if (code === 0) { lines.shift(); resolve({ - Code: code, - Data: JSON.parse(lines.join('\n')), + Code : code, + Data : JSON.parse(lines.join('\n')), }); } else { resolve(code); @@ -703,10 +663,10 @@ module.exports.getConfigTemplate = (version, provider, remote, s3) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; const args = _getDefaultRepertoryArgs(provider, remote, s3); @@ -715,17 +675,11 @@ module.exports.getConfigTemplate = (version, provider, remote, s3) => { const process = new spawn(repertoryExec.cmd, args, processOptions); let result = ''; - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); - process.on('exit', () => { - resolve(JSON.parse(result)); - }); + process.on('exit', () => { resolve(JSON.parse(result)); }); process.unref(); }); }; @@ -754,16 +708,16 @@ module.exports.getMissingDependencies = dependencies => { if (index >= dep.registry.length) { if (dep.display === 'VC Runtime 2015-2019') { _vcRuntimeExists() - .then(exists => { - if (!exists) { - missing.push(dep); - } - resolveIfComplete(); - }) - .catch(() => { - missing.push(dep); - resolveIfComplete(); - }) + .then(exists => { + if (!exists) { + missing.push(dep); + } + resolveIfComplete(); + }) + .catch(() => { + missing.push(dep); + resolveIfComplete(); + }) } else { missing.push(dep); resolveIfComplete(); @@ -772,30 +726,27 @@ module.exports.getMissingDependencies = dependencies => { let hive = null; const hiveName = dep.registry[index].split('\\')[0]; switch (hiveName) { - case 'HKEY_CLASSES_ROOT': - hive = Registry.HKCR; - break; - case 'HKEY_CURRENT_CONFIG': - hive = Registry.HKCC; - break; - case 'HKEY_CURRENT_USER': - hive = Registry.HKCU; - break; - case 'HKEY_LOCAL_MACHINE': - hive = Registry.HKLM; - break; - case 'HKEY_USERS': - hive = Registry.HKU; - break; - default: - throw new Error('Invalid registry hive: ' + hiveName); + case 'HKEY_CLASSES_ROOT': + hive = Registry.HKCR; + break; + case 'HKEY_CURRENT_CONFIG': + hive = Registry.HKCC; + break; + case 'HKEY_CURRENT_USER': + hive = Registry.HKCU; + break; + case 'HKEY_LOCAL_MACHINE': + hive = Registry.HKLM; + break; + case 'HKEY_USERS': + hive = Registry.HKU; + break; + default: + throw new Error('Invalid registry hive: ' + hiveName); } const key = dep.registry[index].substr(hiveName.length); - const regKey = new Registry({ - hive: hive, - key: key - }); + const regKey = new Registry({hive : hive, key : key}); regKey.valueExists('DisplayName', (err, exists) => { if (err || !exists) { regKey.valueExists('ProductName', (err, exists) => { @@ -818,7 +769,8 @@ module.exports.getMissingDependencies = dependencies => { } else { for (const dep of dependencies) { try { - if (!(fs.lstatSync(dep.file).isFile() || fs.lstatSync(dep.file).isSymbolicLink())) { + if (!(fs.lstatSync(dep.file).isFile() || + fs.lstatSync(dep.file).isSymbolicLink())) { missing.push(dep); } } catch (e) { @@ -833,16 +785,14 @@ module.exports.getMissingDependencies = dependencies => { module.exports.grabSkynetFileTree = version => { return new Promise((resolve, reject) => { _exportAllSkylinks(version) - .then(results => { - resolve([{ - name: '/', - directory: true, - children: _createTreeNodes(results.success), - }]); - }) - .catch(e => { - reject(e); - }); + .then(results => { + resolve([ { + name : '/', + directory : true, + children : _createTreeNodes(results.success), + } ]); + }) + .catch(e => { reject(e); }); }); }; @@ -850,10 +800,10 @@ module.exports.grabDirectoryItems = (path, version, provider, remote, s3) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; const args = _getDefaultRepertoryArgs(provider, remote, s3); @@ -863,17 +813,11 @@ module.exports.grabDirectoryItems = (path, version, provider, remote, s3) => { let result = ''; const process = new spawn(repertoryExec.cmd, args, processOptions); - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); - process.stderr.on('data', (d) => { - result += d; - }); + process.stderr.on('data', (d) => { result += d; }); process.on('exit', code => { if (code === 0) { @@ -892,10 +836,10 @@ module.exports.setPinned = (path, pinned, version, provider, remote, s3) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; const args = _getDefaultRepertoryArgs(provider, remote, s3); @@ -905,17 +849,11 @@ module.exports.setPinned = (path, pinned, version, provider, remote, s3) => { let result = ''; const process = new spawn(repertoryExec.cmd, args, processOptions); - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); - process.stderr.on('data', (d) => { - result += d; - }); + process.stderr.on('data', (d) => { result += d; }); process.on('exit', code => { if (code === 0) { @@ -933,10 +871,10 @@ module.exports.importSkylinks = (version, jsonArray) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, }; const args = _getDefaultRepertoryArgs('Skynet'); @@ -946,17 +884,11 @@ module.exports.importSkylinks = (version, jsonArray) => { let result = ''; const process = new spawn(repertoryExec.cmd, args, processOptions); - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); - process.stdout.on('data', (d) => { - result += d; - }); + process.stdout.on('data', (d) => { result += d; }); - process.stderr.on('data', (d) => { - result += d; - }); + process.stderr.on('data', (d) => { result += d; }); process.on('exit', code => { if (code === 0) { @@ -971,8 +903,9 @@ module.exports.importSkylinks = (version, jsonArray) => { }); }; -//https://stackoverflow.com/questions/31645738/how-to-create-full-path-with-nodes-fs-mkdirsync -module.exports.mkDirByPathSync = (targetDir, {isRelativeToScript = false} = {}) => { +// https://stackoverflow.com/questions/31645738/how-to-create-full-path-with-nodes-fs-mkdirsync +module.exports.mkDirByPathSync = (targetDir, + {isRelativeToScript = false} = {}) => { const sep = path.sep; const initDir = path.isAbsolute(targetDir) ? sep : ''; const baseDir = isRelativeToScript ? __dirname : '.'; @@ -986,12 +919,14 @@ module.exports.mkDirByPathSync = (targetDir, {isRelativeToScript = false} = {}) return curDir; } - // To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on Windows. - if (err.code === 'ENOENT') { // Throw the original parentDir error on curDir `ENOENT` failure. + // To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on + // Windows. + if (err.code === 'ENOENT') { // Throw the original parentDir error on + // curDir `ENOENT` failure. throw new Error(`EACCES: permission denied, mkdir '${parentDir}'`); } - const caughtErr = ['EACCES', 'EPERM', 'EISDIR'].indexOf(err.code) > -1; + const caughtErr = [ 'EACCES', 'EPERM', 'EISDIR' ].indexOf(err.code) > -1; if (!caughtErr || (caughtErr && (targetDir === curDir))) { throw err; // Throw if it's just the last created dir. } @@ -1007,55 +942,60 @@ module.exports.performWindowsUninstall = names => { reject('Windows OS is not being used'); } else { 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, null, args) - .then(lines => { - const parseLine = index => { - if (index < lines.length) { - const line = lines[index]; - if (line.startsWith('HKEY_LOCAL_MACHINE\\')) { - let args2 = JSON.parse(JSON.stringify(args)); - args2[1] = 'HKLM\\' + line.substr(19); - args2.push('/v'); - args2.push('DisplayName'); - args2.push('/t'); - args2.push('REG_SZ'); - _execProcessGetOutput(cmd, null, args2) - .then(lines => { - const value = lines[2].trim().substr(args2[3].length).trim().substr(6).trim(); - if (names.includes(value)) { - const items = line.split('\\'); - const productCode = items[items.length - 1]; - _executeProcess('msiexec.exe', null, ['/x', productCode, '/norestart']) - .then(code => { - if ((code === 0) || (code === 3010) || (code === 1641)) { - resolve(true); - } else { - reject('[' + value + '] uninstall failed: ' + code); - } - }) - .catch(err => { - reject(err); - }); + .then(lines => { + const parseLine = index => { + if (index < lines.length) { + const line = lines[index]; + if (line.startsWith('HKEY_LOCAL_MACHINE\\')) { + let args2 = JSON.parse(JSON.stringify(args)); + args2[1] = 'HKLM\\' + line.substr(19); + args2.push('/v'); + args2.push('DisplayName'); + args2.push('/t'); + args2.push('REG_SZ'); + _execProcessGetOutput(cmd, null, args2) + .then(lines => { + const value = lines[2] + .trim() + .substr(args2[3].length) + .trim() + .substr(6) + .trim(); + if (names.includes(value)) { + const items = line.split('\\'); + const productCode = items[items.length - 1]; + _executeProcess('msiexec.exe', null, + [ '/x', productCode, '/norestart' ]) + .then(code => { + if ((code === 0) || (code === 3010) || + (code === 1641)) { + resolve(true); + } else { + reject('[' + value + + '] uninstall failed: ' + code); + } + }) + .catch(err => { reject(err); }); + } else { + parseLine(++index); + } + }) + .catch(() => { parseLine(++index); }); } else { parseLine(++index); } - }) - .catch(() => { - parseLine(++index); - }); - } else { - parseLine(++index); - } - } else { - resolve(false); - } - }; - parseLine(0); - }) - .catch(err => { - reject(err); - }); + } else { + resolve(false); + } + }; + parseLine(0); + }) + .catch(err => { reject(err); }); } }); }; @@ -1064,47 +1004,46 @@ module.exports.removeDirectoryRecursively = _removeDirectoryRecursively; module.exports.resolvePath = _resolvePath; -module.exports.setConfigValue = (name, value, provider, remote, s3, version) => { - return new Promise((resolve, reject) => { - const repertoryExec = _getRepertoryExec(version); - const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: false, - windowsHide: true, +module.exports.setConfigValue = + (name, value, provider, remote, s3, version) => { + return new Promise((resolve, reject) => { + const repertoryExec = _getRepertoryExec(version); + const processOptions = { + cwd : repertoryExec.working, + detached : true, + shell : false, + windowsHide : true, + }; + + const args = _getDefaultRepertoryArgs(provider, remote, s3); + args.push('-set'); + args.push(name); + args.push(value); + + const process = new spawn(repertoryExec.cmd, args, processOptions); + + process.on('error', (err) => { reject(err); }); + + process.on('exit', code => { + if (code !== 0) { + reject(new Error('Failed to set configuration value: ' + code)); + } else { + resolve(); + } + }); + + process.unref(); + }); }; - const args = _getDefaultRepertoryArgs(provider, remote, s3); - args.push('-set'); - args.push(name); - args.push(value); - - const process = new spawn(repertoryExec.cmd, args, processOptions); - - process.on('error', (err) => { - reject(err); - }); - - process.on('exit', code => { - if (code !== 0) { - reject(new Error('Failed to set configuration value: ' + code)); - } else { - resolve(); - } - }); - - process.unref(); - }); -}; - module.exports.stopMountProcess = (version, provider, remote, s3) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: os.platform() === 'darwin', - shell: os.platform() !== 'darwin', - windowsHide: true, + cwd : repertoryExec.working, + detached : os.platform() === 'darwin', + shell : os.platform() !== 'darwin', + windowsHide : true, }; const args = _getDefaultRepertoryArgs(provider, remote, s3); @@ -1112,13 +1051,11 @@ module.exports.stopMountProcess = (version, provider, remote, s3) => { const process = new spawn(repertoryExec.cmd, args, processOptions); const pid = process.pid; - process.on('error', (err) => { - reject(err); - }); + process.on('error', (err) => { reject(err); }); process.on('exit', (code) => { resolve({ - PID: pid, - Code: code, + PID : pid, + Code : code, }); }); @@ -1131,10 +1068,10 @@ module.exports.stopMountProcess = (version, provider, remote, s3) => { module.exports.stopMountProcessSync = (version, provider, remote, s3) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd: repertoryExec.working, - detached: true, - shell: os.platform() !== 'darwin', - windowsHide: true, + cwd : repertoryExec.working, + detached : true, + shell : os.platform() !== 'darwin', + windowsHide : true, }; const args = _getDefaultRepertoryArgs(provider, remote, s3); @@ -1147,17 +1084,15 @@ module.exports.stopMountProcessSync = (version, provider, remote, s3) => { module.exports.testRepertoryBinary = version => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); - _executeProcess(repertoryExec.cmd, repertoryExec.working, ['-dc']) - .then(code => { - if (code === 0) { - resolve(); - } else { - reject(new Error('Invalid exit code: ' + code)); - } - }) - .catch(error => { - reject(error); - }); + _executeProcess(repertoryExec.cmd, repertoryExec.working, [ '-dc' ]) + .then(code => { + if (code === 0) { + resolve(); + } else { + reject(new Error('Invalid exit code: ' + code)); + } + }) + .catch(error => { reject(error); }); }); }; @@ -1168,10 +1103,10 @@ module.exports.verifyHash = (file, hash) => { let args; if (platform === 'darwin') { command = 'shasum'; - args = ['-b', '-a', '256', file]; + args = [ '-b', '-a', '256', file ]; } else if (platform === 'linux') { command = 'sha256sum'; - args = ['-b', file, '-z']; + args = [ '-b', file, '-z' ]; } else { reject(new Error('Platform not supported: ' + os.platform())) } @@ -1195,20 +1130,26 @@ module.exports.verifyHash = (file, hash) => { module.exports.verifySignature = (file, signatureFile, publicKeyFile) => { return new Promise((resolve, reject) => { const executeVerify = openssl => { - execFile(openssl, ['dgst', '-sha256', '-verify', publicKeyFile, '-signature', signatureFile, file], (err, stdout) => { - if (err) { - reject(err); - } else { - resolve(stdout); - } - }); + execFile(openssl, + [ + 'dgst', '-sha256', '-verify', publicKeyFile, '-signature', + signatureFile, file + ], + (err, stdout) => { + if (err) { + reject(err); + } else { + resolve(stdout); + } + }); }; if (os.platform() === 'win32') { const Registry = require('winreg'); const regKey = new Registry({ - hive: Registry.HKLM, - key: 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1' + hive : Registry.HKLM, + key : + 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1' }); regKey.valueExists('InstallLocation', (err, exists) => { if (err) { diff --git a/src/index.js b/src/index.js index 008c70c..b817d0a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,15 +1,18 @@ +import './index.css'; +import 'react-checkbox-tree/lib/react-checkbox-tree.css'; + import React from 'react'; import ReactDOM from 'react-dom'; -import './index.css'; -import App from './App'; -import createAppStore from './redux/store/createAppStore'; -import {getIPCRenderer} from './utils'; -import packageJson from '../package.json'; import {Provider} from 'react-redux'; -import {setActiveRelease} from './redux/actions/release_version_actions'; + +import packageJson from '../package.json'; + +import App from './App'; import {setProviderState} from './redux/actions/mount_actions'; +import {setActiveRelease} from './redux/actions/release_version_actions'; +import createAppStore from './redux/store/createAppStore'; import * as serviceWorker from './serviceWorker'; -import 'react-checkbox-tree/lib/react-checkbox-tree.css'; +import {getIPCRenderer} from './utils'; const Constants = require('./constants'); @@ -17,13 +20,13 @@ const ipcRenderer = getIPCRenderer(); let store; if (ipcRenderer) { - ipcRenderer.once(Constants.IPC_Get_Platform_Reply, (event, platformInfo) => { + ipcRenderer.once(Constants.IPC_Get_Platform_Reply, (_, platformInfo) => { if (platformInfo.Platform === 'linux') { const root = document.documentElement; root.style.setProperty('--default_font_size', '15.3px'); } - ipcRenderer.once(Constants.IPC_Get_State_Reply, (event, result) => { + ipcRenderer.once(Constants.IPC_Get_State_Reply, (_, result) => { if (result.data) { store = createAppStore(platformInfo, packageJson.version, result.data); const providerList = [ @@ -41,7 +44,8 @@ if (ipcRenderer) { } store.dispatch(setProviderState(provider, state)); } - store.dispatch(setActiveRelease(result.data.Release, result.data.Version)); + store.dispatch( + setActiveRelease(result.data.Release, result.data.Version)); } else { store = createAppStore(platformInfo, packageJson.version, {}); } @@ -57,4 +61,3 @@ if (ipcRenderer) { }); ipcRenderer.send(Constants.IPC_Get_Platform); } -