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

Commit

Permalink
Windows support (#125)
Browse files Browse the repository at this point in the history
- `.cmd` formatting for Windows
- modify `findAvailablePort` to work on all platforms
- use `%HOME%/Documents/guppy-projects` for default Windows projects directory
- changed package manager from NPM to yarn
- add `cross-env` to allow package scripts to work on all platforms
- move app-wide settings into `src/config/app.js`
- change spawn process to use promises
- stub `electron.remote` for headless testing
- add `yarn` as local dependency to allow usage without global installation
- forward host environment to Electron process
- properly kill all spawned processes on app quit, cross-platform
- exit main process when Electron application quits during development
  • Loading branch information
AWolf81 authored and superhawk610 committed Aug 16, 2018
1 parent 566a392 commit efc6f57
Show file tree
Hide file tree
Showing 26 changed files with 394 additions and 230 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Steps to reproduce the behavior:

**Environment (please complete the following information):**
- OS: <!-- e.g. MacOS, Windows -->
- Version: <!-- e.g. 0.1.0 - to find the version, check the project's `package.json`, or go to Guppy -> About Guppy in the production bundle (not the development Electron app, but the packaged, distributable one) -->
- Version: <!-- e.g. 0.2.0 - to find the version, check the project's `package.json`, or go to Guppy -> About Guppy in the production bundle (not the development Electron app, but the packaged, distributable one) -->
- Node version: <!-- [eg. 8.11.1] - to find the version, run `node -v` in a terminal -->

**Additional context**
Expand Down
11 changes: 9 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,17 @@ This should open an Electron window with the application running.

In development, all projects are created at `~/guppy-projects-dev`

You can build a macOS executable by running:
You can build an executable by running:

```
yarn package
# MacOS
yarn package:mac
# Windows
yarn package:win
# Linux
yarn package:linux
```

The result will be in the `release-builds` folder.
Expand Down
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Guppy is a free-to-use desktop application designed to make it easier to get sta

Guppy is made for beginners - folks who are just starting out with web development. We hope that it's powerful enough for advanced users as well, but we'll always prioritize the new-developer experience. We'll never charge money for Guppy, it'll always be free-to-use.

> **NOTE**: This is _super early pre-release alpha_. Truthfully it's probably not ready for beginner usage yet (there may be frustrating bugs, plus it only runs on MacOS). The goal is to build a community of folks to work on this and create something truly useful and wonderful for beginners.
> **NOTE**: This is _super early pre-release alpha_. Truthfully it's probably not ready for beginner usage yet (there may be some frustrating bugs). The goal is to build a community of folks to work on this and create something truly useful and wonderful for beginners.
### Current Status

Expand All @@ -29,13 +29,11 @@ Also, important to note: this is a side-project worked on during spare time. We

### Installation

Right now, **Guppy only works for MacOS**. We hope to support Windows and Linux soon.

To use Guppy, you'll first need to have a modern version of Node (a Javascript runtime) installed. [Download Node](https://nodejs.org/en/download/current/). The "Current" version is recommended over LTS due to a bug in NPM 5.6.0 that can corrupt dependencies.

Once Node is installed, you can [download Guppy](https://github.com/joshwcomeau/guppy/releases/download/v0.0.1/Guppy-MacOS.zip)
Once Node is installed, you can [download Guppy](https://github.com/joshwcomeau/guppy/releases).

Double-click the downloaded executable to open Guppy. You may need to right-click and select "Open" if MacOS complains about the fact that this was downloaded from the internet.
Double-click the downloaded executable to open Guppy. Mac users may need to right-click and select "Open" if MacOS complains about the fact that this was downloaded from the internet.

> Note: In future stable releases, I hope to remove the need to download Node by using the Node runtime that comes with Guppy (see [#44](https://github.com/joshwcomeau/guppy/issues/44)). I also plan to create a proper installer so that it's easy to copy Guppy to the Applications folder (see [#26](https://github.com/joshwcomeau/guppy/issues/26)). Contributions welcome!
Expand Down
4 changes: 2 additions & 2 deletions config/webpack.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const getClientEnvironment = require('./env');
const paths = require('./paths');

// List of packages not to bundle and just fall back to `require()`
const externals = ['ps-tree', 'electron-store'];
const externals = ['electron-store'];

// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
Expand Down Expand Up @@ -356,7 +356,7 @@ module.exports = {
return callback(null, 'commonjs ' + request);
}
callback();
}
},
],
// Turn off performance hints during development because we don't do any
// splitting or minification in interest of speed. These warnings become
Expand Down
4 changes: 2 additions & 2 deletions config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const paths = require('./paths');
const getClientEnvironment = require('./env');

// List of packages not to bundle and just fall back to `require()`
const externals = ['ps-tree', 'electron-store'];
const externals = ['electron-store'];

// Webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
Expand Down Expand Up @@ -482,6 +482,6 @@ module.exports = {
return callback(null, 'commonjs ' + request);
}
callback();
}
},
],
};
21 changes: 13 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "guppy",
"productName": "Guppy",
"version": "0.1.0",
"version": "0.2.0",
"private": true,
"main": "src/main.js",
"homepage": "./",
Expand All @@ -11,16 +11,19 @@
},
"license": "ISC",
"scripts": {
"start": "NODE_ENV=development npm run start:react",
"start:react": "BROWSER=none node scripts/start.js",
"start": "cross-env NODE_ENV=development npm run start:react",
"start:react": "cross-env BROWSER=none node scripts/start.js",
"build": "node scripts/build.js",
"package:mac": "electron-packager . --platform=darwin --arch=x64 --icon=src/assets/icons/mac/logo.icns --prune=true --out=release-builds --overwrite",
"package:linux": "electron-packager . --platform=linux --prune=true --out=release-builds --overwrite",
"package": "GENERATE_SOURCEMAP=false npm run build && npm run package:mac && npm run package:linux",
"package:mac": "electron-packager . --platform=darwin --arch=x64 --icon=src/assets/icons/mac/logo.icns --prune=true --out=release-builds --overwrite",
"package:win": "electron-packager . --platform=win32 --arch=x64 --icon=src/assets/icons/win/logo.ico --prune=true --out=release-builds --overwrite",
"dist:linux": "cross-env GENERATE_SOURCEMAP=false npm run build && npm run package:linux",
"dist:mac": "cross-env GENERATE_SOURCEMAP=false npm run build && npm run package:mac",
"dist:win": "cross-env GENERATE_SOURCEMAP=false npm run build && npm run package:win",
"test": "node scripts/test.js --env=node",
"flow": "flow",
"prettier": "prettier --write",
"detect-port": "./node_modules/detect-port-alt/bin/detect-port 3000",
"detect-port": "cross-env ./node_modules/detect-port-alt/bin/detect-port 3000",
"precommit": "yarn run flow && lint-staged"
},
"lint-staged": {
Expand All @@ -36,12 +39,13 @@
"electron-store": "2.0.0",
"fix-path": "2.1.0",
"gatsby-cli": "1.1.58",
"ps-tree": "1.1.0"
"ps-tree": "1.1.0",
"yarn": "1.9.2"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.44",
"@babel/runtime": "7.0.0-beta.44",
"ansi-to-html": "^0.6.4",
"ansi-to-html": "0.6.4",
"async": "2.6.1",
"autoprefixer": "7.2.5",
"babel-core": "7.0.0-bridge.0",
Expand All @@ -53,6 +57,7 @@
"case-sensitive-paths-webpack-plugin": "2.1.1",
"chalk": "2.3.0",
"color": "3.0.0",
"cross-env": "5.2.0",
"css-loader": "0.28.9",
"dotenv": "5.0.0",
"dotenv-expand": "4.2.0",
Expand Down
51 changes: 30 additions & 21 deletions scripts/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ process.on('unhandledRejection', err => {
// Ensure environment variables are read.
require('../config/env');

const { exec } = require('child_process');
const { spawn } = require('child_process');
const chalk = require('chalk');
const path = require('path');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const clearConsole = require('react-dev-utils/clearConsole');
Expand All @@ -37,6 +38,8 @@ const isInteractive = process.stdout.isTTY;
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
const HOST = process.env.HOST || '0.0.0.0';

const IS_WIN = /^win/.test(process.platform);

/**
* Flag to check whether Electron is
* running already.
Expand All @@ -47,26 +50,31 @@ let isElectronRunning = false;
* Singleton-ish run of Electron
* Prevents multiple re-runs of Electron App
*/
function runElectronApp() {
if (isElectronRunning)
return;
function runElectronApp(port) {
if (isElectronRunning) return;

isElectronRunning = true;
process.env['ELECTRON_START_URL'] =
process.env['ELECTRON_START_URL'] || `http://localhost:${port}`;
const electronCommand = IS_WIN ? 'electron.cmd' : 'electron';

exec(`ELECTRON_START_URL=http://localhost:${DEFAULT_PORT} electron .`,
(err, stdout, stderr) => {
if (err) {
console.info(chalk.red('Electron app run failed: ') + stderr);
return;
}
const electronProcess = spawn(electronCommand, ['.']);

electronProcess.stdout.on('data', data => {
// dont log blank output or empty newlines
const output = data.toString().trim();
if (output.length) console.log(chalk.green('[ELECTRON]'), output);
});
electronProcess.stderr.on('data', data => {
const output = data.toString();
console.log(chalk.red(`[ELECTRON] ${output}`));
});

// Clear console for brevity
process.stdout.write('\x1bc');
// close webpack server when electron quits
electronProcess.on('exit', code => process.exit(code));

// Log output
console.info(stdout);
}
);
// clear console for brevity
process.stdout.write('\x1bc');
}

// Warn and crash if required files are missing
Expand Down Expand Up @@ -137,20 +145,21 @@ checkBrowsers(paths.appPath)
openBrowser(urls.localUrlForBrowser);
});

['SIGINT', 'SIGTERM'].forEach(function (sig) {
process.on(sig, function () {
['SIGINT', 'SIGTERM'].forEach(function(sig) {
process.on(sig, function() {
devServer.close();
process.exit();
});
});

/**
* Hook runElectronApp() to 'done' (compile) event
*
*
* Fails on error
*/
compiler.plugin('done',
stats => !stats.hasErrors() && runElectronApp()
compiler.plugin(
'done',
stats => !stats.hasErrors() && runElectronApp(port)
);
})
.catch(err => {
Expand Down
50 changes: 36 additions & 14 deletions src/components/ApplicationMenu/ApplicationMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,29 @@ class ApplicationMenu extends Component<Props> {
showImportExistingProjectPrompt,
} = this.props;

const __DARWIN__ = process.platform === 'darwin';
const template = [
{
label: 'File',
label: __DARWIN__ ? 'File' : '&File',
submenu: [
{
label: 'Create New Project',
label: __DARWIN__
? 'Create New Project...'
: 'Create &new project...',
click: createNewProjectStart,
accelerator: process.platform === 'darwin' ? 'Cmd+N' : 'Ctrl+N',
},
{
label: 'Import Existing Project',
label: __DARWIN__
? 'Import Existing Project...'
: '&Import existing project...',
click: showImportExistingProjectPrompt,
accelerator: process.platform === 'darwin' ? 'Cmd+I' : 'Ctrl+I',
},
],
},
{
label: 'Edit',
label: __DARWIN__ ? 'Edit' : '&Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
Expand All @@ -53,28 +58,45 @@ class ApplicationMenu extends Component<Props> {
{ role: 'copy' },
{ role: 'paste' },
{ role: 'delete' },
{ role: 'selectall' },
{
role: 'selectall',
label: __DARWIN__ ? 'Select All' : 'Select all',
},
],
},
{
label: 'View',
label: __DARWIN__ ? 'View' : '&View',
submenu: [
{ role: 'reload' },
{ role: 'forcereload' },
{ role: 'toggledevtools' },
{
role: 'forcereload',
label: __DARWIN__ ? 'Force Reload' : 'Force reload',
},
{
role: 'toggledevtools',
label: __DARWIN__
? 'Toggle Developer Tools'
: 'Toggle developer tools',
},
{ type: 'separator' },
{ role: 'resetzoom' },
{ role: 'zoomin' },
{ role: 'zoomout' },
{
role: 'resetzoom',
label: __DARWIN__ ? 'Actual Size' : 'Actual size',
},
{ role: 'zoomin', label: __DARWIN__ ? 'Zoom In' : 'Zoom in' },
{ role: 'zoomout', label: __DARWIN__ ? 'Zoom Out' : 'Zoom out' },
{ type: 'separator' },
{ role: 'togglefullscreen' },
{
role: 'togglefullscreen',
label: __DARWIN__ ? 'Toggle Full Screen' : 'Toggle full screen',
},
],
},
{
label: 'Help',
label: __DARWIN__ ? 'Help' : '&Help',
submenu: [
{
label: 'Getting Started',
label: __DARWIN__ ? 'Getting Started' : 'Getting started',
click: this.openGettingStartedDocs,
},
],
Expand Down
4 changes: 2 additions & 2 deletions src/components/CreateNewProjectWizard/BuildPane.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ const BUILD_STEPS = {
copy: 'Creating project directory',
},
installingDependencies: {
copy: 'Installing dependencies.',
copy: 'Installing dependencies',
additionalCopy: 'This step can take a while...',
},
guppification: {
copy: 'Persisting project info.',
copy: 'Persisting project info',
},
};

Expand Down
4 changes: 4 additions & 0 deletions src/config/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// app-wide settings (no user changable settings here)
module.exports = {
PACKAGE_MANAGER: 'yarn',
};
Loading

0 comments on commit efc6f57

Please sign in to comment.