Repository: opencomponents/oc
Pull request #941 (2018-10-01 20:15:03)

[Suggestion] Handling relative path when initiating component
Not creating an issue - just a small PR that allows using relative path when initiating new component.

**Why this change?**

In our team all the components are in `/src/components` directory. All the grunt/npm tasks are defined at the top level though. When we want to create a new component it requires us to first go two levels down to do the `init` and then go back up to run registry locally or run the tests.

Supporting relative path would allow us to slightly reduce number of steps during the development process.

This change affects only init CLI.


**Test plan (required)**

Output when running `node src/cli/ init test-components/hello-test`
![image](https://user-images.githubusercontent.com/6817645/46313055-c5ee7f80-c5be-11e8-992f-021453567687.png)





Patch:
diff --git a/src/cli/commands.js b/src/cli/commands.js
index 3181e036..531940ac 100644
--- a/src/cli/commands.js
+++ b/src/cli/commands.js
@@ -61,13 +61,13 @@ module.exports = {
     },
 
     init: {
-      cmd: 'init <componentName> [templateType]',
+      cmd: 'init <componentPath> [templateType]',
       example: {
         cmd: '$0 init test-component oc-template-es6'
       },
       description:
-        'Create a new empty component of a specific template type in the current folder [templateType default: oc-template-es6]',
-      usage: 'Usage: $0 init <componentName> [templateType]'
+        'Create a new empty component of a specific template type in the current folder or in directory indicated by (relative) componentPath [templateType default: oc-template-es6]',
+      usage: 'Usage: $0 init <componentPath> [templateType]'
     },
 
     mock: {
diff --git a/src/cli/facade/init.js b/src/cli/facade/init.js
index 784436b7..f75ac108 100644
--- a/src/cli/facade/init.js
+++ b/src/cli/facade/init.js
@@ -12,13 +12,13 @@ module.exports = function(dependencies) {
     logger = dependencies.logger;
 
   return function(opts, callback) {
-    const componentName = opts.componentName;
     const templateType = _.isUndefined(opts.templateType)
       ? 'oc-template-es6'
       : opts.templateType;
     const errors = strings.errors.cli;
     const messages = strings.messages.cli;
-    const componentPath = path.join(process.cwd(), componentName);
+    const componentPath = path.join(process.cwd(), opts.componentPath);
+    const componentName = path.basename(componentPath);
 
     callback = wrapCliCallback(callback);
     local.init(
@@ -39,12 +39,7 @@ module.exports = function(dependencies) {
           }
           logger.err(format(errors.INIT_FAIL, err));
         } else {
-          logger.log(
-            messages.initSuccess(
-              componentName,
-              path.join(process.cwd(), componentName)
-            )
-          );
+          logger.log(messages.initSuccess(componentName, componentPath));
         }
 
         callback(err, componentName);


Test patch:
diff --git a/test/unit/cli-facade-init.js b/test/unit/cli-facade-init.js
index 13ba6d2d..b8b5c6d9 100644
--- a/test/unit/cli-facade-init.js
+++ b/test/unit/cli-facade-init.js
@@ -17,12 +17,12 @@ describe('cli : facade : init', () => {
     local = new Local({ logger: { log: () => {} } }),
     initFacade = new InitFacade({ local: local, logger: logSpy });
 
-  const execute = function(componentName, templateType) {
+  const execute = function(componentPath, templateType) {
     logSpy.err = sinon.spy();
     logSpy.ok = sinon.spy();
     logSpy.log = sinon.spy();
     initFacade(
-      { componentName: componentName, templateType: templateType },
+      { componentPath: componentPath, templateType: templateType },
       () => {}
     );
   };
@@ -81,6 +81,29 @@ describe('cli : facade : init', () => {
       });
     });
 
+    describe('when the component has relative path', () => {
+      beforeEach(() => {
+        sinon.stub(local, 'init').yields(null, 'yes man');
+        execute('this/is/relative/path/to/the-best-component', 'jade');
+      });
+
+      afterEach(() => {
+        local.init.restore();
+      });
+
+      it('should show a correct name in the log message', () => {
+        expect(logSpy.log.args[0][0]).to.contain(
+          'Success! Created the-best-component at'
+        );
+      });
+
+      it('should show a correct path in the log message', () => {
+        expect(logSpy.log.args[0][0]).to.contain(
+          '/this/is/relative/path/to/the-best-component'
+        );
+      });
+    });
+
     describe('when succeeds', () => {
       beforeEach(() => {
         sinon.stub(local, 'init').yields(null, 'yes man');