Skip to content

Instantly share code, notes, and snippets.

@Descent098
Created July 16, 2022 23:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Descent098/60d227ed96ad8e28cf1b098e2ca1b71e to your computer and use it in GitHub Desktop.
Save Descent098/60d227ed96ad8e28cf1b098e2ca1b71e to your computer and use it in GitHub Desktop.
A Script to setup electron apps using the quick start guide https://www.electronjs.org/docs/latest/tutorial/quick-start
"""A script that automates the process found on https://www.electronjs.org/docs/latest/tutorial/quick-start
Interactive Usage:
python setup-electron.py
To pre-specify an app name use:
python setup-electron.py <app_name>
To run fully headlessly (without forge use):
python setup-electron.py <app_name> --headless
To run fully headlessly (with forge use):
python setup-electron.py <app_name> --headless --useforge
Written July 26th 2022
"""
import os
import sys
import json
import string
from subprocess import Popen, PIPE
# Argument parsing from terminal
if "--headless" in sys.argv:
headless=True
else:
headless=False
if "--useforge" in sys.argv:
forge = True
else:
forge= False
legal_path_characters = string.ascii_letters + string.digits+ " ()[]" # Allowed characters in file path
if len(sys.argv) > 1 and not (sys.argv[1] == "--headless" or sys.argv[1] == "--useforge"): # If project name is provided
app_name = "".join([safe_char for safe_char in sys.argv[1] if safe_char in legal_path_characters]).strip().replace(" ", "-")
else:
if headless:
app_name = "my-app"
else:
app_name = input("Please provide an app name: ")
app_name = "".join([safe_char for safe_char in app_name if safe_char in legal_path_characters]).strip().replace(" ", "-")
print(f"Creating app with name: {app_name}")
## Step 2: Get NPM Install
if os.name == "nt": #windows
npm_path = [path for path in os.environ["PATH"].split(";") if "nodejs" in path][0] + "npm.cmd"
else:
npm_path = "npm" # TODO: test this works
if not npm_path:
raise ValueError("Unable to find valid NPM install, please install NPM and add it to your path")
## Step 3. Create Required directories
if not os.path.exists(app_name):
os.mkdir(app_name)
os.chdir(app_name)
print(f"Initialized directory {app_name}, beginning install of electron (this may take a while)")
process = Popen([npm_path, "install", "-save-dev","electron"], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
## Step 4. Setting up file defaults to write necessary files
package = { # Package.json defaults
"name": app_name,
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"keywords": [],
"author": "",
"license": "MIT"
}
### Step 5. Configure file defaults
file_defaults = { # The default files to use
"package.json": json.dumps(package),
"index.html": r"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</body>
</html>""",
"preload.js": r"""// All of the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
""",
"main.js": r"""
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const path = require('path')
const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
"""
}
## Step 6. Write required files
print("Beginning to write files:")
for index,current_file in enumerate(file_defaults):
print(f"Writing {index+1}/{len(file_defaults)}: {current_file}")
with open(current_file, "w+") as cur_file:
cur_file.write(file_defaults[current_file])
## Step 7. Ask if they want to setup forge
if forge:
Popen([npm_path.replace("npm", "npx"), f"create-electron-app@latest {app_name}"], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
elif not headless and "y" in input("Would you like to install electron forge [this is used to make building distributables easier https://www.electronforge.io/](y/n)?: "):
Popen([npm_path.replace("npm", "npx"), f"create-electron-app@latest {app_name}"], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
## Step 8. Ask user if they want to start the app to test it
if not headless and "y" in input("Would you like to start the app using:\n\t$ npm start\nTo confirm it is working (y/n)?").lower():
Popen([npm_path, "start"], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
print(f"\n\nYou're ready to go!\n\nTo start your app in future run this command in the source folder:\n\t npm start\n\nSource folder is available at:\n\t {os.path.abspath('.')}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment