You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					98 lines
				
				1.9 KiB
			
		
		
			
		
	
	
					98 lines
				
				1.9 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								const path = require('path');
							 | 
						||
| 
								 | 
							
								const childProcess = require('child_process');
							 | 
						||
| 
								 | 
							
								const isWsl = require('is-wsl');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = (target, opts) => {
							 | 
						||
| 
								 | 
							
									if (typeof target !== 'string') {
							 | 
						||
| 
								 | 
							
										return Promise.reject(new Error('Expected a `target`'));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									opts = Object.assign({wait: true}, opts);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									let cmd;
							 | 
						||
| 
								 | 
							
									let appArgs = [];
							 | 
						||
| 
								 | 
							
									let args = [];
							 | 
						||
| 
								 | 
							
									const cpOpts = {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (Array.isArray(opts.app)) {
							 | 
						||
| 
								 | 
							
										appArgs = opts.app.slice(1);
							 | 
						||
| 
								 | 
							
										opts.app = opts.app[0];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (process.platform === 'darwin') {
							 | 
						||
| 
								 | 
							
										cmd = 'open';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (opts.wait) {
							 | 
						||
| 
								 | 
							
											args.push('-W');
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (opts.app) {
							 | 
						||
| 
								 | 
							
											args.push('-a', opts.app);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									} else if (process.platform === 'win32' || isWsl) {
							 | 
						||
| 
								 | 
							
										cmd = 'cmd' + (isWsl ? '.exe' : '');
							 | 
						||
| 
								 | 
							
										args.push('/c', 'start', '""', '/b');
							 | 
						||
| 
								 | 
							
										target = target.replace(/&/g, '^&');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (opts.wait) {
							 | 
						||
| 
								 | 
							
											args.push('/wait');
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (opts.app) {
							 | 
						||
| 
								 | 
							
											args.push(opts.app);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (appArgs.length > 0) {
							 | 
						||
| 
								 | 
							
											args = args.concat(appArgs);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										if (opts.app) {
							 | 
						||
| 
								 | 
							
											cmd = opts.app;
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											const useSystemXdgOpen = process.versions.electron || process.platform === 'android';
							 | 
						||
| 
								 | 
							
											cmd = useSystemXdgOpen ? 'xdg-open' : path.join(__dirname, 'xdg-open');
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (appArgs.length > 0) {
							 | 
						||
| 
								 | 
							
											args = args.concat(appArgs);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (!opts.wait) {
							 | 
						||
| 
								 | 
							
											// `xdg-open` will block the process unless
							 | 
						||
| 
								 | 
							
											// stdio is ignored and it's detached from the parent
							 | 
						||
| 
								 | 
							
											// even if it's unref'd
							 | 
						||
| 
								 | 
							
											cpOpts.stdio = 'ignore';
							 | 
						||
| 
								 | 
							
											cpOpts.detached = true;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									args.push(target);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (process.platform === 'darwin' && appArgs.length > 0) {
							 | 
						||
| 
								 | 
							
										args.push('--args');
							 | 
						||
| 
								 | 
							
										args = args.concat(appArgs);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const cp = childProcess.spawn(cmd, args, cpOpts);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (opts.wait) {
							 | 
						||
| 
								 | 
							
										return new Promise((resolve, reject) => {
							 | 
						||
| 
								 | 
							
											cp.once('error', reject);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											cp.once('close', code => {
							 | 
						||
| 
								 | 
							
												if (code > 0) {
							 | 
						||
| 
								 | 
							
													reject(new Error('Exited with code ' + code));
							 | 
						||
| 
								 | 
							
													return;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												resolve(cp);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									cp.unref();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return Promise.resolve(cp);
							 | 
						||
| 
								 | 
							
								};
							 |