Projekt

Obecné

Profil

Stáhnout (1.89 KB) Statistiky
| Větev: | Revize:
1
'use strict';
2
const path = require('path');
3
const childProcess = require('child_process');
4
const isWsl = require('is-wsl');
5

    
6
module.exports = (target, opts) => {
7
	if (typeof target !== 'string') {
8
		return Promise.reject(new Error('Expected a `target`'));
9
	}
10

    
11
	opts = Object.assign({wait: true}, opts);
12

    
13
	let cmd;
14
	let appArgs = [];
15
	let args = [];
16
	const cpOpts = {};
17

    
18
	if (Array.isArray(opts.app)) {
19
		appArgs = opts.app.slice(1);
20
		opts.app = opts.app[0];
21
	}
22

    
23
	if (process.platform === 'darwin') {
24
		cmd = 'open';
25

    
26
		if (opts.wait) {
27
			args.push('-W');
28
		}
29

    
30
		if (opts.app) {
31
			args.push('-a', opts.app);
32
		}
33
	} else if (process.platform === 'win32' || isWsl) {
34
		cmd = 'cmd' + (isWsl ? '.exe' : '');
35
		args.push('/c', 'start', '""', '/b');
36
		target = target.replace(/&/g, '^&');
37

    
38
		if (opts.wait) {
39
			args.push('/wait');
40
		}
41

    
42
		if (opts.app) {
43
			args.push(opts.app);
44
		}
45

    
46
		if (appArgs.length > 0) {
47
			args = args.concat(appArgs);
48
		}
49
	} else {
50
		if (opts.app) {
51
			cmd = opts.app;
52
		} else {
53
			const useSystemXdgOpen = process.versions.electron || process.platform === 'android';
54
			cmd = useSystemXdgOpen ? 'xdg-open' : path.join(__dirname, 'xdg-open');
55
		}
56

    
57
		if (appArgs.length > 0) {
58
			args = args.concat(appArgs);
59
		}
60

    
61
		if (!opts.wait) {
62
			// `xdg-open` will block the process unless
63
			// stdio is ignored and it's detached from the parent
64
			// even if it's unref'd
65
			cpOpts.stdio = 'ignore';
66
			cpOpts.detached = true;
67
		}
68
	}
69

    
70
	args.push(target);
71

    
72
	if (process.platform === 'darwin' && appArgs.length > 0) {
73
		args.push('--args');
74
		args = args.concat(appArgs);
75
	}
76

    
77
	const cp = childProcess.spawn(cmd, args, cpOpts);
78

    
79
	if (opts.wait) {
80
		return new Promise((resolve, reject) => {
81
			cp.once('error', reject);
82

    
83
			cp.once('close', code => {
84
				if (code > 0) {
85
					reject(new Error('Exited with code ' + code));
86
					return;
87
				}
88

    
89
				resolve(cp);
90
			});
91
		});
92
	}
93

    
94
	cp.unref();
95

    
96
	return Promise.resolve(cp);
97
};
(1-1/5)