From a1d952b8ff23bea9046d088e24b26cd1896f0a10 Mon Sep 17 00:00:00 2001
From: KunQian <kunqian@gitlab.cn>
Date: Mon, 23 Aug 2021 21:43:38 +0800
Subject: [PATCH] Add JH vue components entry

---
 app/assets/javascripts/main.js    |  1 +
 app/assets/javascripts/main_jh.js |  1 +
 config/webpack.config.js          | 21 +++++++++++++++++++--
 jest.config.base.js               | 22 ++++++++++++++++++++++
 jest.config.integration.js        |  4 ++++
 lib/gitlab/gon_helper.rb          |  1 +
 6 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 app/assets/javascripts/main_jh.js

diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 1aaefcaa13b7a..abd13a3015635 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -37,6 +37,7 @@ import initBroadcastNotifications from './broadcast_notification';
 import { initTopNav } from './nav';
 
 import 'ee_else_ce/main_ee';
+import 'jh_else_ce/main_jh';
 
 applyGitLabUIConfig();
 
diff --git a/app/assets/javascripts/main_jh.js b/app/assets/javascripts/main_jh.js
new file mode 100644
index 0000000000000..13a6b8f3d3d17
--- /dev/null
+++ b/app/assets/javascripts/main_jh.js
@@ -0,0 +1 @@
+// This is an empty file to satisfy jh_else_ce import for the JH main entry point
diff --git a/config/webpack.config.js b/config/webpack.config.js
index b81b56110418f..0b130565d3255 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -157,6 +157,9 @@ const alias = {
   // the following resolves files which are different between CE and EE
   ee_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'),
 
+  // the following resolves files which are different between CE and JH
+  jh_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'),
+
   // override loader path for icons.svg so we do not duplicate this asset
   '@gitlab/svgs/dist/icons.svg': path.join(
     ROOT_PATH,
@@ -180,10 +183,13 @@ if (IS_EE) {
 if (IS_JH) {
   Object.assign(alias, {
     jh: path.join(ROOT_PATH, 'jh/app/assets/javascripts'),
+    jh_component: path.join(ROOT_PATH, 'jh/app/assets/javascripts'),
+    jh_empty_states: path.join(ROOT_PATH, 'jh/app/views/shared/empty_states'),
     jh_icons: path.join(ROOT_PATH, 'jh/app/views/shared/icons'),
     jh_images: path.join(ROOT_PATH, 'jh/app/assets/images'),
     jh_spec: path.join(ROOT_PATH, 'jh/spec/javascripts'),
     jh_jest: path.join(ROOT_PATH, 'jh/spec/frontend'),
+    jh_else_ce: path.join(ROOT_PATH, 'jh/app/assets/javascripts'),
   });
 }
 
@@ -519,6 +525,15 @@ module.exports = {
         );
       }),
 
+    !IS_JH &&
+      new webpack.NormalModuleReplacementPlugin(/^jh_component\/(.*)\.vue/, (resource) => {
+        // eslint-disable-next-line no-param-reassign
+        resource.request = path.join(
+          ROOT_PATH,
+          'app/assets/javascripts/vue_shared/components/empty_component.js',
+        );
+      }),
+
     new CopyWebpackPlugin({
       patterns: [
         {
@@ -634,10 +649,12 @@ module.exports = {
       }),
 
     new webpack.DefinePlugin({
-      // This one is used to define window.gon.ee and other things properly in tests:
+      // These are used to define window.gon.ee, window.gon.jh and other things properly in tests:
       'process.env.IS_EE': JSON.stringify(IS_EE),
-      // This one is used to check against "EE" properly in application code
+      'process.env.IS_JH': JSON.stringify(IS_JH),
+      // These are used to check against "EE" properly in application code
       IS_EE: IS_EE ? 'window.gon && window.gon.ee' : JSON.stringify(false),
+      IS_JH: IS_JH ? 'window.gon && window.gon.jh' : JSON.stringify(false),
       // This is used by Sourcegraph because these assets are loaded dnamically
       'process.env.SOURCEGRAPH_PUBLIC_PATH': JSON.stringify(SOURCEGRAPH_PUBLIC_PATH),
     }),
diff --git a/jest.config.base.js b/jest.config.base.js
index 997f3c254b4dc..3ace87c49bc62 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -1,10 +1,12 @@
 const IS_EE = require('./config/helpers/is_ee_env');
 const isESLint = require('./config/helpers/is_eslint');
+const IS_JH = require('./config/helpers/is_jh_env');
 
 module.exports = (path, options = {}) => {
   const {
     moduleNameMapper: extModuleNameMapper = {},
     moduleNameMapperEE: extModuleNameMapperEE = {},
+    moduleNameMapperJH: extModuleNameMapperJH = {},
   } = options;
 
   const reporters = ['default'];
@@ -29,6 +31,9 @@ module.exports = (path, options = {}) => {
     testMatch.push(`<rootDir>/ee/${glob}`);
   }
 
+  if (IS_JH) {
+    testMatch.push(`<rootDir>/jh/${glob}`);
+  }
   // workaround for eslint-import-resolver-jest only resolving in test files
   // see https://github.com/JoinColony/eslint-import-resolver-jest#note
   if (isESLint(module)) {
@@ -41,8 +46,11 @@ module.exports = (path, options = {}) => {
     '^~(/.*)$': '<rootDir>/app/assets/javascripts$1',
     '^ee_component(/.*)$':
       '<rootDir>/app/assets/javascripts/vue_shared/components/empty_component.js',
+    '^jh_component(/.*)$':
+      '<rootDir>/app/assets/javascripts/vue_shared/components/empty_component.js',
     '^shared_queries(/.*)$': '<rootDir>/app/graphql/queries$1',
     '^ee_else_ce(/.*)$': '<rootDir>/app/assets/javascripts$1',
+    '^jh_else_ce(/.*)$': '<rootDir>/app/assets/javascripts$1',
     '^helpers(/.*)$': '<rootDir>/spec/frontend/__helpers__$1',
     '^vendor(/.*)$': '<rootDir>/vendor/assets/javascripts$1',
     [TEST_FIXTURES_PATTERN]: '<rootDir>/tmp/tests/frontend/fixtures$1',
@@ -70,6 +78,19 @@ module.exports = (path, options = {}) => {
     collectCoverageFrom.push(rootDirEE.replace('$1', '/**/*.{js,vue}'));
   }
 
+  if (IS_JH) {
+    const rootDirJH = '<rootDir>/jh/app/assets/javascripts$1';
+    Object.assign(moduleNameMapper, {
+      '^jh(/.*)$': rootDirJH,
+      '^jh_component(/.*)$': rootDirJH,
+      '^jh_else_ce(/.*)$': rootDirJH,
+      '^jh_jest/(.*)$': '<rootDir>/jh/spec/frontend/$1',
+      ...extModuleNameMapperJH,
+    });
+
+    collectCoverageFrom.push(rootDirJH.replace('$1', '/**/*.{js,vue}'));
+  }
+
   const coverageDirectory = () => {
     if (process.env.CI_NODE_INDEX && process.env.CI_NODE_TOTAL) {
       return `<rootDir>/coverage-frontend/jest-${process.env.CI_NODE_INDEX}-${process.env.CI_NODE_TOTAL}`;
@@ -107,6 +128,7 @@ module.exports = (path, options = {}) => {
     testEnvironment: '<rootDir>/spec/frontend/environment.js',
     testEnvironmentOptions: {
       IS_EE,
+      IS_JH,
     },
   };
 };
diff --git a/jest.config.integration.js b/jest.config.integration.js
index 92296fb751e19..da8e813a2cb57 100644
--- a/jest.config.integration.js
+++ b/jest.config.integration.js
@@ -8,9 +8,13 @@ module.exports = {
     moduleNameMapper: {
       '^test_helpers(/.*)$': '<rootDir>/spec/frontend_integration/test_helpers$1',
       '^ee_else_ce_test_helpers(/.*)$': '<rootDir>/spec/frontend_integration/test_helpers$1',
+      '^jh_else_ce_test_helpers(/.*)$': '<rootDir>/spec/frontend_integration/test_helpers$1',
     },
     moduleNameMapperEE: {
       '^ee_else_ce_test_helpers(/.*)$': '<rootDir>/ee/spec/frontend_integration/test_helpers$1',
     },
+    moduleNameMapperJH: {
+      '^jh_else_ce_test_helpers(/.*)$': '<rootDir>/jh/spec/frontend_integration/test_helpers$1',
+    },
   }),
 };
diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb
index 16a8b5f959e59..6297ee2a9cc9a 100644
--- a/lib/gitlab/gon_helper.rb
+++ b/lib/gitlab/gon_helper.rb
@@ -35,6 +35,7 @@ def add_gon_variables
       gon.first_day_of_week      = current_user&.first_day_of_week || Gitlab::CurrentSettings.first_day_of_week
       gon.time_display_relative  = true
       gon.ee                     = Gitlab.ee?
+      gon.jh                     = Gitlab.jh?
       gon.dot_com                = Gitlab.com?
 
       if current_user
-- 
GitLab