Repository: javierbrea/eslint-plugin-boundaries (js)

Issue:
Fatal error on dependency scanning - dependencyInfo.name might be null
Hey,

thanks for this great library 👍  I was looking for a JS/TS library to do Architecture Tests (like https://www.archunit.org/, but inJS), and IMHO your library is extremely close to that!

I ran it with a medium-sized codebase; and possibly found an error:

In my case, the system broke with the following error:

```
TypeError: Cannot read property 'split' of undefined
Occurred while linting /Users/sebastian/src/kiwigrid/solarwatt-smart-setup/src/Redux/Sagas/BatteryRebootProcess.ts:2
    at ImportDeclaration (/Users/sebastian/src/kiwigrid/solarwatt-smart-setup/node_modules/eslint-plugin-boundaries/src/rules/no-external.js:62:57)
    at /Users/sebastian/src/kiwigrid/solarwatt-smart-setup/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/Users/sebastian/src/kiwigrid/solarwatt-smart-setup/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/Users/sebastian/src/kiwigrid/solarwatt-smart-setup/node_modules/eslint/lib/linter/node-event-generator.js:254:26)
    at NodeEventGenerator.applySelectors (/Users/sebastian/src/kiwigrid/solarwatt-smart-setup/node_modules/eslint/lib/linter/node-event-generator.js:283:22)
    at NodeEventGenerator.enterNode (/Users/sebastian/src/kiwigrid/solarwatt-smart-setup/node_modules/eslint/lib/linter/node-event-generator.js:297:14)
    at CodePathAnalyzer.enterNode (/Users/sebastian/src/kiwigrid/solarwatt-smart-setup/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js:634:23)
    at /Users/sebastian/src/kiwigrid/solarwatt-smart-setup/node_modules/eslint/lib/linter/linter.js:936:32
    at Array.forEach (<anonymous>)
```

... while parsing the line:

```
import { RootState } from '../index';
```

See the related Pull Request for a possible fix :-)

All the best, and keep up the good work,
Sebastian

Pull request:
Release v1.1.1
### Added
- chore(deps): Add Node.js 10.x support while it is in maintenance

### Changed
- chore(ci-cd): Migrate build and publish pipelines to github actions

### Fixed
- fix(#65): Fixed error on dependency scanning when dependencyInfo.name is null (thanks to @skurfuerst)

**Closing issues**

closes #65 


Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..e29ddae
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,69 @@
+name: build
+on:
+  push:
+    branches:
+      - master
+      - release
+  pull_request:
+jobs:
+  test:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        node: ["10.23.0", "12.19.0", "14.15.0", "15.2.0"]
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Extract branch name
+        shell: bash
+        run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
+        id: extract-branch
+      - name: Use Node.js
+        uses: actions/setup-node@v1
+        with:
+          node-version: ${{ matrix.node }}
+      - name: Cache node modules
+        uses: actions/cache@v2
+        env:
+          cache-name: cache-node-modules
+        with:
+          # npm cache files are stored in `~/.npm` on Linux/macOS
+          path: ~/.npm
+          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
+          restore-keys: |
+            ${{ runner.os }}-build-${{ env.cache-name }}-
+            ${{ runner.os }}-build-
+            ${{ runner.os }}-
+      - name: Install dependencies
+        run: npm ci
+      - name: Lint
+        run: npm run lint
+      - name: Test unit
+        run: npm run test:unit
+      - name: Upload test results
+        uses: actions/upload-artifact@v2
+        with:
+          name: coverage-${{ matrix.node }}
+          path: coverage
+          retention-days: 1
+  quality:
+    runs-on: ubuntu-latest
+    needs: test
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Download test results
+        uses: actions/download-artifact@v2
+        with:
+          name: coverage-15.2.0
+          path: coverage
+      - name: Coveralls
+        uses: coverallsapp/github-action@master
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+      - name: SonarCloud Scan
+        uses: sonarsource/sonarcloud-github-action@master
+        if: env.SONAR_TOKEN != ''
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
diff --git a/.github/workflows/publish-to-github-registry.yml b/.github/workflows/publish-to-github.yml
similarity index 95%
rename from .github/workflows/publish-to-github-registry.yml
rename to .github/workflows/publish-to-github.yml
index 0db0463..511901c 100644
--- a/.github/workflows/publish-to-github-registry.yml
+++ b/.github/workflows/publish-to-github.yml
@@ -1,4 +1,4 @@
-name: publish-to-github-registry
+name: publish-to-github
 on:
   release:
     types: [created]
diff --git a/.github/workflows/publish-to-npm.yml b/.github/workflows/publish-to-npm.yml
new file mode 100644
index 0000000..de14137
--- /dev/null
+++ b/.github/workflows/publish-to-npm.yml
@@ -0,0 +1,17 @@
+name: publish-to-npm
+on:
+  release:
+    types: [created]
+jobs:
+  publish:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-node@v1
+      with:
+        node-version: '12.x'
+        registry-url: 'https://registry.npmjs.org/'
+    - run: npm ci
+    - run: npm publish
+      env:
+        NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d4ce167..d5dcb6c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,10 +5,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ## [unreleased]
+### Added
 ### Changed
 ### Fixed
 ### Removed
 
+## [1.1.1] - 2020-12-11
+### Added
+- chore(deps): Add Node.js 10.x support while it is in maintenance
+
+### Changed
+- chore(ci-cd): Migrate build and publish pipelines to github actions
+- chore(deps): Update dependencies
+
+### Fixed
+- fix(#65): Fixed error on dependency scanning when dependencyInfo.name is null (thanks to @skurfuerst)
+
+
 ## [1.1.0] - 2020-11-12
 ### Added
 - feat(no-external): Allow forbid importing external libraries specifiers
diff --git a/README.md b/README.md
index 87f29e0..27f1474 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build status][travisci-image]][travisci-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Quality Gate][quality-gate-image]][quality-gate-url]
+[![Build status][build-image]][build-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Quality Gate][quality-gate-image]][quality-gate-url]
 
 [![NPM dependencies][npm-dependencies-image]][npm-dependencies-url] [![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com) [![Last commit][last-commit-image]][last-commit-url] [![Last release][release-image]][release-url]
 
@@ -162,8 +162,8 @@ MIT, see [LICENSE](./LICENSE) for details.
 
 [coveralls-image]: https://coveralls.io/repos/github/javierbrea/eslint-plugin-boundaries/badge.svg
 [coveralls-url]: https://coveralls.io/github/javierbrea/eslint-plugin-boundaries
-[travisci-image]: https://travis-ci.com/javierbrea/eslint-plugin-boundaries.svg?branch=master
-[travisci-url]: https://travis-ci.com/javierbrea/eslint-plugin-boundaries
+[build-image]: https://github.com/javierbrea/eslint-plugin-boundaries/workflows/build/badge.svg?branch=master
+[build-url]: https://github.com/javierbrea/eslint-plugin-boundaries/actions?query=workflow%3Abuild+branch%3Amaster
 [last-commit-image]: https://img.shields.io/github/last-commit/javierbrea/eslint-plugin-boundaries.svg
 [last-commit-url]: https://github.com/javierbrea/eslint-plugin-boundaries/commits
 [license-image]: https://img.shields.io/npm/l/eslint-plugin-boundaries.svg
diff --git a/package-lock.json b/package-lock.json
index 7005dc9..7afd712 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint-plugin-boundaries",
-  "version": "1.1.0",
+  "version": "1.1.1",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -1718,19 +1718,6 @@
         "yaml": "^1.10.0"
       }
     },
-    "coveralls": {
-      "version": "3.0.9",
-      "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.9.tgz",
-      "integrity": "sha512-nNBg3B1+4iDox5A5zqHKzUTiwl2ey4k2o0NEcVZYvl+GOSJdKBj4AJGKLv6h3SvWch7tABHePAQOSZWM9E2hMg==",
-      "dev": true,
-      "requires": {
-        "js-yaml": "^3.13.1",
-        "lcov-parse": "^1.0.0",
-        "log-driver": "^1.2.7",
-        "minimist": "^1.2.0",
-        "request": "^2.88.0"
-      }
-    },
     "cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -2025,9 +2012,9 @@
       }
     },
     "eslint": {
-      "version": "7.13.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.13.0.tgz",
-      "integrity": "sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==",
+      "version": "7.14.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.14.0.tgz",
+      "integrity": "sha512-5YubdnPXrlrYAFCKybPuHIAH++PINe1pmKNc5wQRB9HSbqIK1ywAnntE3Wwua4giKu0bjligf1gLF6qxMGOYRA==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.0.0",
@@ -3817,12 +3804,6 @@
       "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
       "dev": true
     },
-    "lcov-parse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz",
-      "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=",
-      "dev": true
-    },
     "leven": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -3846,9 +3827,9 @@
       "dev": true
     },
     "lint-staged": {
-      "version": "10.5.1",
-      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.1.tgz",
-      "integrity": "sha512-fTkTGFtwFIJJzn/PbUO3RXyEBHIhbfYBE7+rJyLcOXabViaO/h6OslgeK6zpeUtzkDrzkgyAYDTLAwx6JzDTHw==",
+      "version": "10.5.2",
+      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.2.tgz",
+      "integrity": "sha512-e8AYR1TDlzwB8VVd38Xu2lXDZf6BcshVqKVuBQThDJRaJLobqKnpbm4dkwJ2puypQNbLr9KF/9mfA649mAGvjA==",
       "dev": true,
       "requires": {
         "chalk": "^4.1.0",
@@ -3869,9 +3850,9 @@
       },
       "dependencies": {
         "debug": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
-          "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+          "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"
@@ -3897,9 +3878,9 @@
       }
     },
     "listr2": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.2.tgz",
-      "integrity": "sha512-AajqcZEUikF2ioph6PfH3dIuxJclhr3i3kHgTOP0xeXdWQohrvJAAmqVcV43/GI987HFY/vzT73jYXoa4esDHg==",
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.3.tgz",
+      "integrity": "sha512-vUb80S2dSUi8YxXahO8/I/s29GqnOL8ozgHVLjfWQXa03BNEeS1TpBLjh2ruaqq5ufx46BRGvfymdBSuoXET5w==",
       "dev": true,
       "requires": {
         "chalk": "^4.1.0",
@@ -3932,12 +3913,6 @@
       "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
       "dev": true
     },
-    "log-driver": {
-      "version": "1.2.7",
-      "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
-      "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==",
-      "dev": true
-    },
     "log-symbols": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
@@ -4464,9 +4439,9 @@
       "dev": true
     },
     "prettier": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
-      "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
+      "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
       "dev": true
     },
     "prettier-linter-helpers": {
diff --git a/package.json b/package.json
index ddd9094..8d4974d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint-plugin-boundaries",
-  "version": "1.1.0",
+  "version": "1.1.1",
   "description": "Eslint plugin checking architecture boundaries between elements",
   "keywords": [
     "eslint",
@@ -18,12 +18,10 @@
   ],
   "main": "index.js",
   "scripts": {
-    "coveralls": "cat ./coverage/lcov.info | coveralls",
     "lint": "eslint index.js src *.js",
     "lint-staged": "lint-staged",
     "test": "jest",
-    "test:coverage": "npm run test",
-    "test:ci": "npm run test"
+    "test:unit": "npm run test"
   },
   "peerDependencies": {
     "eslint": "^6.0.0 || ^7.0.0"
@@ -33,14 +31,13 @@
     "globule": "1.3.2"
   },
   "devDependencies": {
-    "coveralls": "3.0.9",
-    "eslint": "7.13.0",
+    "eslint": "7.14.0",
     "eslint-config-prettier": "6.15.0",
     "eslint-plugin-prettier": "3.1.4",
     "husky": "4.3.0",
     "jest": "26.6.3",
-    "lint-staged": "10.5.1",
-    "prettier": "2.1.2"
+    "lint-staged": "10.5.2",
+    "prettier": "2.2.1"
   },
   "lint-staged": {
     "src/**/*.js": "eslint",
@@ -52,6 +49,6 @@
     }
   },
   "engines": {
-    "node": "12.x || 14.x || 15.x"
+    "node": "10.x || 12.x || 14.x || 15.x"
   }
 }
diff --git a/sonar-project.properties b/sonar-project.properties
index 12cae00..35670d8 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -1,6 +1,6 @@
 sonar.organization=javierbrea
 sonar.projectKey=eslint-plugin-boundaries
-sonar.projectVersion=1.1.0
+sonar.projectVersion=1.1.1
 
 sonar.javascript.file.suffixes=.js
 sonar.sourceEncoding=UTF-8
diff --git a/src/rules/no-external.js b/src/rules/no-external.js
index 39b0a31..e0bf567 100644
--- a/src/rules/no-external.js
+++ b/src/rules/no-external.js
@@ -59,9 +59,9 @@ module.exports = {
     return {
       ImportDeclaration: (node) => {
         const dependencyInfo = getDependencyInfo(fileName, node.source.value, context.settings);
-        const cleanDependencyName = dependencyInfo.name.split("/")[0];
 
         if (!dependencyInfo.isLocal && currentElementOptions) {
+          const cleanDependencyName = dependencyInfo.name.split("/")[0];
           if (currentElementOptions.includes(cleanDependencyName)) {
             // library is not allowed
             context.report({


Test patch:
diff --git a/test/src/rules/no-external.spec.js b/test/src/rules/no-external.spec.js
index c962b69..a2752c8 100644
--- a/test/src/rules/no-external.spec.js
+++ b/test/src/rules/no-external.spec.js
@@ -54,6 +54,12 @@ ruleTester.run(RULE, rule, {
         "boundaries/ignore": [codeFilePath("src/components/component-a/**/*.js")],
       },
     },
+    // Modules can import any non-recognized local file
+    {
+      filename: absoluteFilePath("src/modules/module-a/ModuleA.js"),
+      code: "import { foo } from '../../foo/index'",
+      options,
+    },
     // Modules can import react-router-dom
     {
       filename: absoluteFilePath("src/modules/module-a/ModuleA.js"),