HomeBridge Reboot

- New "homebridge" CLI
- Finds and loads locally-installed "providers" from user home dir
- Written in ES6 with babel/register
This commit is contained in:
Nick Farina
2015-07-07 18:40:23 -07:00
parent 05e17be277
commit ab2f25e736
27 changed files with 181 additions and 4013 deletions

14
lib/homebridge.js Normal file
View File

@@ -0,0 +1,14 @@
import fs from 'fs';
import cli from './homebridge/cli';
//
// Main HomeBridge Module with global exports.
//
// HomeBridge version
export const HOMEBRIDGE_VERSION = JSON.parse(fs.readFileSync('package.json')).version;
// HomeBridge CLI
export { cli }
// HomeBridge API

24
lib/homebridge/cli.js Normal file
View File

@@ -0,0 +1,24 @@
import Server from './server';
import program from 'commander';
import { HOMEBRIDGE_VERSION } from '../homebridge';
export default function() {
// Global options (none currently) and version printout
program
.version(HOMEBRIDGE_VERSION);
// Run the HomeBridge server
program
.command('server')
.description('Run the HomeBridge server')
.action((options) => new Server(options).run());
// Parse options and execute HomeBridge
program.parse(process.argv);
// Display help by default if no commands or options given
if (!process.argv.slice(2).length) {
program.outputHelp();
}
}

View File

@@ -0,0 +1,89 @@
import path from 'path';
import fs from 'fs';
import semver from 'semver';
import { HOMEBRIDGE_VERSION } from '../homebridge';
// This class represents a HomeBridge Provider that may or may not be installed.
export class Provider {
constructor(name) {
this.name = name;
}
get path():string {
return path.join(Provider.installedProvidersDir, this.name);
}
load():object {
// check for a package.json
let pjsonPath:string = path.join(this.path, "package.json");
let pjson:object = null;
if (!fs.existsSync(pjsonPath)) {
throw new Error(`Provider ${this.name} does not contain a package.json.`);
}
try {
// attempt to parse package.json
pjson = JSON.parse(fs.readFileSync(pjsonPath));
}
catch (err) {
throw new Error(`Provider ${this.name} contains an invalid package.json. Error: ${err}`);
}
// pluck out the HomeBridge version requirement
if (!pjson.engines || !pjson.engines.homebridge) {
throw new Error(`Provider ${this.name} does not contain a valid HomeBridge version requirement.`);
}
let versionRequired:string = pjson.engines.homebridge;
// make sure the version is satisfied by the currently running version of HomeBridge
if (!semver.satisfies(HOMEBRIDGE_VERSION, versionRequired)) {
throw new Error(`Provider ${this.name} requires a HomeBridge version of "${versionRequired}" which does not satisfy the current HomeBridge version of ${HOMEBRIDGE_VERSION}. You may need to upgrade your installation of HomeBridge.`);
}
// figure out the main module - index.js unless otherwise specified
let main:string = pjson.main || "./index.js";
let mainPath:string = path.join(this.path, main);
// try to require() it
let loadedProvider:object = require(mainPath);
return loadedProvider;
}
// Gets all providers installed on the local system
static installed():Array<Provider> {
let providers:Array<Provider> = [];
let names = fs.readdirSync(Provider.installedProvidersDir);
for (let name of names) {
// reconstruct full path
let fullPath:string = path.join(Provider.installedProvidersDir, name);
// we only care about directories
if (!fs.statSync(fullPath).isDirectory()) continue;
providers.push(new Provider(name));
}
return providers;
}
//
// Private utility functions
//
static get userDir():string {
return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
}
static get installedProvidersDir():string {
return path.join(Provider.userDir, ".homebridge/providers/node_modules");
}
}

14
lib/homebridge/server.js Normal file
View File

@@ -0,0 +1,14 @@
import { Provider } from './provider';
export default class Server {
run() {
// get all installed providers
let providers:Array<Provider> = Provider.installed();
// validate providers - check for valid package.json, etc.
providers.forEach((provider) => provider.load());
console.log(`Loaded ${providers.length} providers.`);
}
}