summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--gui/src/main/command-line-options.ts71
-rw-r--r--gui/src/main/index.ts36
-rw-r--r--gui/src/main/user-interface.ts6
-rw-r--r--gui/src/main/version.ts2
5 files changed, 91 insertions, 25 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83184591d9..1d8ff3ecf0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,7 @@ Line wrap the file at 100 chars. Th
## [Unreleased]
### Added
- Log select settings on each connection attempt.
+- Add `--help` and `--version` options to the desktop GUI application.
#### Android
- Add DNS content blockers.
diff --git a/gui/src/main/command-line-options.ts b/gui/src/main/command-line-options.ts
index 543a384029..0cddf6b14a 100644
--- a/gui/src/main/command-line-options.ts
+++ b/gui/src/main/command-line-options.ts
@@ -1,17 +1,58 @@
-enum CommandLineOptions {
- showChanges = '--show-changes',
- disableResetNavigation = '--disable-reset-navigation', // development only
- disableDevtoolsOpen = '--disable-devtools-open', // development only
- forwardRendererLog = '--forward-renderer-log', // development only
+class CommandLineOption {
+ private flags: string[];
+
+ public constructor(private description: string, ...flags: string[]) {
+ this.flags = flags;
+ }
+
+ public get match(): boolean {
+ return this.flags.some((flag) => process.argv.includes(flag));
+ }
+
+ public format(): string {
+ return formatOption(this.description, ...this.flags);
+ }
+}
+
+class DevelopmentCommandLineOption extends CommandLineOption {
+ public constructor(...flags: string[]) {
+ super('', ...flags);
+ }
+
+ public get match(): boolean {
+ return process.env.NODE_ENV === 'development' && super.match;
+ }
}
-export const SHOULD_SHOW_CHANGES = process.argv.includes(CommandLineOptions.showChanges);
-export const SHOULD_DISABLE_RESET_NAVIGATION = process.argv.includes(
- CommandLineOptions.disableResetNavigation,
-);
-export const SHOULD_DISABLE_DEVTOOLS_OPEN = process.argv.includes(
- CommandLineOptions.disableDevtoolsOpen,
-);
-export const SHOULD_FORWARD_RENDERER_LOG = process.argv.includes(
- CommandLineOptions.forwardRendererLog,
-);
+export const CommandLineOptions = {
+ help: new CommandLineOption('Print this help text', '--help', '-h'),
+ version: new CommandLineOption('Print the app version', '--version'),
+ showChanges: new CommandLineOption('Show changes dialog', '--show-changes'),
+ disableResetNavigation: new DevelopmentCommandLineOption('--disable-reset-navigation'),
+ disableDevtoolsOpen: new DevelopmentCommandLineOption('--disable-devtools-open'),
+ forwardRendererLog: new DevelopmentCommandLineOption('--forward-renderer-log'),
+} as const;
+
+export function printCommandLineOptions() {
+ Object.values(CommandLineOptions).forEach((option) => {
+ if (!(option instanceof DevelopmentCommandLineOption)) {
+ console.log(option.format());
+ }
+ });
+}
+
+export function printElectronOptions() {
+ console.log(formatOption('Run without renderer process sandboxed', '--no-sandbox'));
+ console.log(formatOption('Run without hardware acceleration for graphics', '--disable-gpu'));
+}
+
+// This functions format options into one line, e.g.
+// --help Print this help text
+// The line starts with 4 spaces and the flags and description are separated with spaces to align
+// the descriptions
+function formatOption(description: string, ...flags: string[]) {
+ const joinedFlags = flags.join(', ');
+ const padding = ' ';
+ const paddedFlags = (joinedFlags + padding).slice(0, -joinedFlags.length);
+ return ' ' + paddedFlags + description;
+}
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index 6492b0865a..484f4db4b3 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -27,7 +27,11 @@ import {
import Account, { AccountDelegate, LocaleProvider } from './account';
import { getOpenAtLogin } from './autostart';
import { readChangelog } from './changelog';
-import { SHOULD_DISABLE_RESET_NAVIGATION, SHOULD_SHOW_CHANGES } from './command-line-options';
+import {
+ CommandLineOptions,
+ printCommandLineOptions,
+ printElectronOptions,
+} from './command-line-options';
import { ConnectionObserver, DaemonRpc, SubscriptionListener } from './daemon-rpc';
import Expectation from './expectation';
import { IpcMainEventChannel } from './ipc-event-channel';
@@ -56,7 +60,7 @@ import TunnelStateHandler, {
TunnelStateProvider,
} from './tunnel-state';
import UserInterface, { UserInterfaceDelegate } from './user-interface';
-import Version from './version';
+import Version, { GUI_VERSION } from './version';
const execAsync = util.promisify(exec);
@@ -400,7 +404,7 @@ class ApplicationMain
this,
this.daemonRpc,
SANDBOX_DISABLED,
- SHOULD_DISABLE_RESET_NAVIGATION,
+ CommandLineOptions.disableResetNavigation.match,
);
this.tunnelStateExpectation = new Expectation(async () => {
@@ -720,7 +724,7 @@ class ApplicationMain
windowsSplitTunnelingApplications: this.windowsSplitTunnelingApplications,
macOsScrollbarVisibility: this.macOsScrollbarVisibility,
changelog: this.changelog ?? [],
- forceShowChanges: SHOULD_SHOW_CHANGES,
+ forceShowChanges: CommandLineOptions.showChanges.match,
navigationHistory: this.navigationHistory,
}));
@@ -1040,5 +1044,25 @@ class ApplicationMain
/* eslint-enable @typescript-eslint/member-ordering */
}
-const applicationMain = new ApplicationMain();
-applicationMain.run();
+if (CommandLineOptions.help.match) {
+ console.log('Mullvad VPN');
+ console.log('Graphical interface for managing the Mullvad VPN daemon');
+
+ console.log('');
+ console.log('OPTIONS:');
+ printCommandLineOptions();
+
+ console.log('');
+ console.log('USEFUL ELECTRON/CHROMIUM OPTIONS:');
+ printElectronOptions();
+
+ process.exit(0);
+} else if (CommandLineOptions.version.match) {
+ console.log(GUI_VERSION);
+ console.log('Electron version:', process.versions.electron);
+
+ process.exit(0);
+} else {
+ const applicationMain = new ApplicationMain();
+ applicationMain.run();
+}
diff --git a/gui/src/main/user-interface.ts b/gui/src/main/user-interface.ts
index aa3e8b07f5..4376043f87 100644
--- a/gui/src/main/user-interface.ts
+++ b/gui/src/main/user-interface.ts
@@ -10,7 +10,7 @@ import { IAccountData, ILocation, TunnelState } from '../shared/daemon-rpc-types
import { messages, relayLocations } from '../shared/gettext';
import log from '../shared/logging';
import { Scheduler } from '../shared/scheduler';
-import { SHOULD_DISABLE_DEVTOOLS_OPEN, SHOULD_FORWARD_RENDERER_LOG } from './command-line-options';
+import { CommandLineOptions } from './command-line-options';
import { DaemonRpc } from './daemon-rpc';
import {
changeIpcWebContents,
@@ -110,12 +110,12 @@ export default class UserInterface implements WindowControllerDelegate {
if (process.env.NODE_ENV === 'development') {
await this.installDevTools();
- if (!SHOULD_DISABLE_DEVTOOLS_OPEN) {
+ if (!CommandLineOptions.disableDevtoolsOpen.match) {
// The devtools doesn't open on Windows if openDevTools is called without a delay here.
window.once('ready-to-show', () => window.webContents.openDevTools({ mode: 'detach' }));
}
- if (SHOULD_FORWARD_RENDERER_LOG) {
+ if (CommandLineOptions.forwardRendererLog.match) {
log.addInput(new WebContentsConsoleInput(window.webContents));
}
}
diff --git a/gui/src/main/version.ts b/gui/src/main/version.ts
index fbe5b64574..1bab7728b4 100644
--- a/gui/src/main/version.ts
+++ b/gui/src/main/version.ts
@@ -13,7 +13,7 @@ import { DaemonRpc } from './daemon-rpc';
import { IpcMainEventChannel } from './ipc-event-channel';
import { NotificationSender } from './notification-controller';
-const GUI_VERSION = app.getVersion().replace('.0', '');
+export const GUI_VERSION = app.getVersion().replace('.0', '');
/// Mirrors the beta check regex in the daemon. Matches only well formed beta versions
const IS_BETA = /^(\d{4})\.(\d+)-beta(\d+)$/;