v0.5.0: Initial Release
This commit is contained in:
parent
f95897cf30
commit
f97f217bc6
|
@ -0,0 +1 @@
|
|||
node_modules
|
|
@ -0,0 +1,28 @@
|
|||
# serviceman
|
||||
|
||||
A cross-platform service manager
|
||||
|
||||
```bash
|
||||
serviceman add --name "my-project" node ./serve.js --port 3000
|
||||
serviceman stop my-project
|
||||
serviceman start my-project
|
||||
```
|
||||
|
||||
Works with launchd (Mac), systemd (Linux), or standalone (Windows).
|
||||
|
||||
## Meta Package
|
||||
|
||||
This is a meta-package to fetch and install the correction version of
|
||||
[go-serviceman](https://git.rootprojects.org/root/serviceman)
|
||||
for your architecture and platform.
|
||||
|
||||
```bash
|
||||
npm install serviceman
|
||||
```
|
||||
|
||||
## How does it work?
|
||||
|
||||
1. Resolves executable from PATH, or hashbang (ex: `#!/usr/bin/env node`)
|
||||
2. Resolves file and directory paths to absolute paths (ex: `/Users/me/my-project/serve.js`)
|
||||
3. Creates a template `.plist` (Mac), `.service` (Linux), or `.json` (Windows) file
|
||||
4. Calls `launchd` (Mac), `systemd` (Linux), or `serviceman-runner` (Windows) to enable/start/stop/etc
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "serviceman",
|
||||
"version": "0.5.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@root/mkdirp": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz",
|
||||
"integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA=="
|
||||
},
|
||||
"@root/request": {
|
||||
"version": "1.3.11",
|
||||
"resolved": "https://registry.npmjs.org/@root/request/-/request-1.3.11.tgz",
|
||||
"integrity": "sha512-3a4Eeghcjsfe6zh7EJ+ni1l8OK9Fz2wL1OjP4UCa0YdvtH39kdXB9RGWuzyNv7dZi0+Ffkc83KfH0WbPMiuJFw=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "serviceman",
|
||||
"version": "0.5.0",
|
||||
"description": "A cross-platform service manager",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"postinstall": "bin/install-serviceman.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.rootprojects.org/root/serviceman.git"
|
||||
},
|
||||
"keywords": [
|
||||
"launchd",
|
||||
"systemd",
|
||||
"winsvc",
|
||||
"launchctl",
|
||||
"systemctl",
|
||||
"HKEY_CURRENT_USER",
|
||||
"HKCU",
|
||||
"Run"
|
||||
],
|
||||
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"@root/mkdirp": "^1.0.0",
|
||||
"@root/request": "^1.3.11"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
'use strict';
|
||||
var os = require('os');
|
||||
|
||||
// https://nodejs.org/api/os.html#os_os_arch
|
||||
// 'arm', 'arm64', 'ia32', 'mips', 'mipsel', 'ppc', 'ppc64', 's390', 's390x', 'x32', and 'x64'
|
||||
var arch = os.arch(); // process.arch
|
||||
|
||||
// https://nodejs.org/api/os.html#os_os_platform
|
||||
// 'aix', 'darwin', 'freebsd', 'linux', 'openbsd', 'sunos', 'win32'
|
||||
var platform = os.platform(); // process.platform
|
||||
var ext = 'windows' === platform ? '.exe' : '';
|
||||
|
||||
// This is _probably_ right. It's good enough for us
|
||||
// https://github.com/nodejs/node/issues/13629
|
||||
if ('arm' === arch) {
|
||||
arch += 'v' + process.config.variables.arm_version;
|
||||
}
|
||||
|
||||
var map = {
|
||||
// arches
|
||||
armv6: 'armv6',
|
||||
armv7: 'armv7',
|
||||
arm64: 'armv8',
|
||||
ia32: '386',
|
||||
x32: '386',
|
||||
x64: 'amd64',
|
||||
// platforms
|
||||
darwin: 'darwin',
|
||||
linux: 'linux',
|
||||
win32: 'windows'
|
||||
};
|
||||
|
||||
arch = map[arch];
|
||||
platform = map[platform];
|
||||
|
||||
if (!arch || !platform) {
|
||||
console.error(
|
||||
"'" + os.platform() + "' on '" + os.arch() + "' isn't supported yet."
|
||||
);
|
||||
console.error(
|
||||
'Please open an issue at https://git.rootprojects.org/root/serviceman/issues'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var newVer = require('../package.json').version;
|
||||
var fs = require('fs');
|
||||
var exec = require('child_process').exec;
|
||||
var request = require('@root/request');
|
||||
var mkdirp = require('@root/mkdirp');
|
||||
|
||||
function needsUpdate(oldVer, newVer) {
|
||||
// "v1.0.0-pre" is BEHIND "v1.0.0"
|
||||
newVer = newVer.replace(/^v/, '').split(/[\.\-\+]/);
|
||||
oldVer = oldVer.replace(/^v/, '').split(/[\.\-\+]/);
|
||||
//console.log(oldVer, newVer);
|
||||
|
||||
if (newVer[3] && !oldVer[3]) {
|
||||
// don't install beta over stable
|
||||
return false;
|
||||
}
|
||||
|
||||
if (oldVer[3]) {
|
||||
if (oldVer[2] > 0) {
|
||||
oldVer[2] -= 1;
|
||||
} else if (oldVer[1] > 0) {
|
||||
oldVer[2] = 999;
|
||||
oldVer[1] -= 1;
|
||||
} else if (oldVer[0] > 0) {
|
||||
oldVer[2] = 999;
|
||||
oldVer[1] = 999;
|
||||
oldVer[0] -= 1;
|
||||
} else {
|
||||
// v0.0.0
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (newVer[3]) {
|
||||
if (newVer[2] > 0) {
|
||||
newVer[2] -= 1;
|
||||
} else if (newVer[1] > 0) {
|
||||
newVer[2] = 999;
|
||||
newVer[1] -= 1;
|
||||
} else if (newVer[0] > 0) {
|
||||
newVer[2] = 999;
|
||||
newVer[1] = 999;
|
||||
newVer[0] -= 1;
|
||||
} else {
|
||||
// v0.0.0
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//console.log(oldVer, newVer);
|
||||
if (oldVer[0] > newVer[0]) {
|
||||
return false;
|
||||
} else if (oldVer[0] < newVer[0]) {
|
||||
return true;
|
||||
} else if (oldVer[1] > newVer[1]) {
|
||||
return false;
|
||||
} else if (oldVer[1] < newVer[1]) {
|
||||
return true;
|
||||
} else if (oldVer[2] > newVer[2]) {
|
||||
return false;
|
||||
} else if (oldVer[2] < newVer[2]) {
|
||||
return true;
|
||||
} else if (!oldVer[3] && newVer[3]) {
|
||||
return false;
|
||||
} else if (oldVer[3] && !newVer[3]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Same version
|
||||
console.log(false === needsUpdate('0.5.0', '0.5.0'));
|
||||
// No previous version
|
||||
console.log(true === needsUpdate('', '0.5.1'));
|
||||
// The new version is slightly newer
|
||||
console.log(true === needsUpdate('0.5.0', '0.5.1'));
|
||||
console.log(true === needsUpdate('0.4.999-pre1', '0.5.0-pre1'));
|
||||
// The new version is slightly older
|
||||
console.log(false === needsUpdate('0.5.0', '0.5.0-pre1'));
|
||||
console.log(false === needsUpdate('0.5.1', '0.5.0'));
|
||||
*/
|
||||
|
||||
exec('serviceman version', { windowsHide: true }, function(err, stdout) {
|
||||
var oldVer = (stdout || '').split(' ')[0];
|
||||
console.log(oldVer, newVer);
|
||||
if (!needsUpdate(oldVer, newVer)) {
|
||||
console.info(
|
||||
'Current serviceman version is new enough:',
|
||||
oldVer,
|
||||
newVer
|
||||
);
|
||||
return;
|
||||
//} else {
|
||||
// console.info('Current serviceman version is older:', oldVer, newVer);
|
||||
}
|
||||
|
||||
var url = 'https://rootprojects.org/serviceman/dist/{{ .Platform }}/{{ .Arch }}/serviceman{{ .Ext }}'
|
||||
.replace(/{{ .Version }}/g, newVer)
|
||||
.replace(/{{ .Platform }}/g, platform)
|
||||
.replace(/{{ .Arch }}/g, arch)
|
||||
.replace(/{{ .Ext }}/g, ext);
|
||||
|
||||
console.info('Installing from', url);
|
||||
return request({ uri: url, encoding: null }, function(err, resp) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
//console.log(resp.body.byteLength);
|
||||
//console.log(typeof resp.body);
|
||||
var serviceman = 'serviceman' + ext;
|
||||
return fs.writeFile(serviceman, resp.body, null, function(err) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
fs.chmodSync(serviceman, parseInt('0755', 8));
|
||||
|
||||
var path = require('path');
|
||||
var localdir = '/usr/local/bin';
|
||||
fs.rename(serviceman, path.join(localdir, serviceman), function(
|
||||
err
|
||||
) {
|
||||
if (err) {
|
||||
//console.error(err);
|
||||
}
|
||||
// ignore
|
||||
});
|
||||
|
||||
var homedir = require('os').homedir();
|
||||
var bindir = path.join(homedir, '.local', 'bin');
|
||||
return mkdirp(bindir, function(err) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var localsrv = path.join(bindir, serviceman);
|
||||
return fs.writeFile(localsrv, resp.body, function(err) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
fs.chmodSync(localsrv, parseInt('0755', 8));
|
||||
console.info('Wrote', serviceman, 'to', bindir);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue