Skip to content

Commit

Permalink
Add automatic servicePath detection functionality
Browse files Browse the repository at this point in the history
The service directory will be automatically detected if the users CWD is a valid
Serverless service directory.
  • Loading branch information
pmuens committed May 26, 2016
1 parent 60e2d63 commit 39d30b3
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 25 deletions.
7 changes: 1 addition & 6 deletions bin/serverless
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@
// Note: TestsPlugin is only used for tests
const TestsPlugin = require('../lib/plugins/tests/tests');

let SUtils = require('../lib/classes/Utils');
SUtils = new SUtils();

const Serverless = require('../lib/Serverless');

const serverless = new Serverless({
// TODO: update config accordingly
// servicePath: SUtils.findServicePath(process.cwd()),
interactive: typeof process.env.CI === 'undefined',
});

Expand All @@ -21,4 +16,4 @@ if (process.argv.indexOf('--serverless-integration-test') > -1) {
serverless.pluginManager.addPlugin(TestsPlugin);
}

serverless.run();
serverless.init().then(() => serverless.run());
33 changes: 23 additions & 10 deletions lib/Serverless.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,20 @@ const Version = require('./../package.json').version;

class Serverless {
constructor(config) {
let configObj = config;
configObj = configObj || {};
let configObject = config;
configObject = configObject || {};

this.version = Version;

this.config = new Config(this, config);
this.yamlParser = new YamlParser(this);
this.pluginManager = new PluginManager(this);
this.utils = new Utils(this);
this.service = new Service(this);
this.cli = new CLI(this, configObj.interactive);

// use the servicePath from the options or try to find it in the CWD
configObject.servicePath = configObject.servicePath || this.utils.findServicePath();

this.config = new Config(this, configObject);

this.classes = {};
this.classes.CLI = CLI;
Expand All @@ -32,19 +35,29 @@ class Serverless {
this.classes.Utils = Utils;
this.classes.Service = Service;
this.classes.Error = SError;
}

this.pluginManager.loadAllPlugins();
init() {
return this.service.load()
.then(() => {
this.pluginManager.loadAllPlugins();

this.cli = new CLI(this, configObj.interactive,
this.pluginManager.getPlugins());
this.cli = new CLI(
this,
this.config.interactive,
this.pluginManager.getPlugins()
);

this.inputToBeProcessed = this.cli.processInput();
this.inputToBeProcessed = this.cli.processInput();
});
}

run() {
if (this.inputToBeProcessed.commands.length) {
this.pluginManager.run(this.inputToBeProcessed.commands,
this.inputToBeProcessed.options);
this.pluginManager.run(
this.inputToBeProcessed.commands,
this.inputToBeProcessed.options
);
}
}

Expand Down
4 changes: 3 additions & 1 deletion lib/classes/Service.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ class Service {
const options = opts || {};
const servicePath = that.serverless.config.servicePath;

// skip if the service path is not found
// because the user might want to create a new service
if (!servicePath) {
throw new Error('ServicePath is not configured.');
return BbPromise.resolve();
}

return that.serverless.yamlParser
Expand Down
32 changes: 32 additions & 0 deletions lib/classes/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,38 @@ class Utils {
return Math.random().toString(36).substr(2, length);
}

findServicePath() {
const that = this;

// Helper function
const isServiceDir = (dir) => {
// TODO: add support for serverless.yml
const yamlName = 'serverless.yaml';
const yamlFilePath = path.join(dir, yamlName);

return that.fileExistsSync(yamlFilePath);
};

// Check up to 10 parent levels
let previous = '.';
let servicePath = null;
let i = 10;

while (i >= 0) {
const fullPath = path.resolve(process.cwd(), previous);

if (isServiceDir(fullPath)) {
servicePath = fullPath;
break;
}

previous = path.join(previous, '..');
i--;
}

return servicePath;
}

}

module.exports = Utils;
1 change: 1 addition & 0 deletions lib/plugins/awsResourcesDeploy/tests/awsResourcesDeploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe('AwsResourcesDeploy', () => {

before(() => {
awsResourcesDeploy = new AwsResourcesDeploy(serverless);
awsResourcesDeploy.serverless.init();
});

describe('#constructor()', () => {
Expand Down
6 changes: 4 additions & 2 deletions lib/plugins/create/tests/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ const path = require('path');
const os = require('os');
const Create = require('../create');
const Serverless = require('../../../Serverless');
const S = new Serverless();

describe('Create', () => {
let create;

before(() => {
create = new Create(S);
const serverless = new Serverless();
serverless.init();

create = new Create(serverless);
});

describe('#constructor()', () => {
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
"mocha": "^2.2.5",
"mocha-lcov-reporter": "^1.2.0",
"node-uuid": "^1.4.2",
"rimraf": "^2.4.3"
"rimraf": "^2.4.3",
"sinon": "^1.17.4"
},
"dependencies": {
"async": "^1.5.2",
Expand All @@ -72,7 +73,6 @@
"replaceall": "^0.1.6",
"shelljs": "^0.6.0",
"shortid": "^2.2.2",
"traverse": "^0.6.6",
"sinon": "^1.17.4"
"traverse": "^0.6.6"
}
}
7 changes: 4 additions & 3 deletions tests/classes/Service.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,11 @@ describe('Service', () => {
serviceInstance = new Service(serverless);
});

it('should throw error if servicePath not configured', () => {
it('should resolve if no servicePath is found', (done) => {
const serverless = new Serverless();
const invalidService = new Service(serverless);
expect(() => invalidService.load()).to.throw(Error);
const noService = new Service(serverless);

return noService.load().then(() => done());
});

/*
Expand Down
34 changes: 34 additions & 0 deletions tests/classes/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,39 @@ describe('Utils', () => {
});
});
});

describe('#findServicePath()', () => {
const testDir = process.cwd();

it('should detect if the CWD is a service directory', () => {
const tmpDirPath = path.join(os.tmpdir(), (new Date).getTime().toString());
const tmpFilePath = path.join(tmpDirPath, 'serverless.yaml');

serverless.utils.writeFileSync(tmpFilePath, 'foo');
process.chdir(tmpDirPath);

const servicePath = serverless.utils.findServicePath();

expect(servicePath).to.not.equal(null);
});

it('should detect if the CWD is not a service directory', () => {
// just use the root of the tmpdir because findServicePath will
// also check parent directories (and may find matching tmp dirs
// from old tests)
const tmpDirPath = os.tmpdir();
process.chdir(tmpDirPath);

const servicePath = serverless.utils.findServicePath();

expect(servicePath).to.equal(null);
});

afterEach(() => {
// always switch back to the test directory
// so that we have a clean state
process.chdir(testDir);
});
});
});

0 comments on commit 39d30b3

Please sign in to comment.