Repository: oppia/oppia

Issue:
Remove Moment.js from the codebase
Moment.js is a legacy project and should not be used in modern applications (see project status [here](https://momentjs.com/docs/#/-project-status/)). Oppia codebase uses moment.js in `date-time-format.service.ts` for date format conversions. Changes will need to be made to replace moment with one of the alternatives mentioned [here](https://momentjs.com/docs/#/-project-status/recommendations/).
Remove Moment.js from the codebase
Moment.js is a legacy project and should not be used in modern applications (see project status [here](https://momentjs.com/docs/#/-project-status/)). Oppia codebase uses moment.js in `date-time-format.service.ts` for date format conversions. Changes will need to be made to replace moment with one of the alternatives mentioned [here](https://momentjs.com/docs/#/-project-status/recommendations/).


Discussion:

Resolving patch:
diff --git a/scripts/linters/general_purpose_linter.py b/scripts/linters/general_purpose_linter.py
--- a/scripts/linters/general_purpose_linter.py
+++ b/scripts/linters/general_purpose_linter.py
@@ -269,6 +269,14 @@
             'core/templates/pages/library-page/search-bar/'
             'search-bar.component.spec.ts'),
         'excluded_dirs': ()
+    },
+    {
+        'regexp': re.compile(r'import \{.*\} from \'lodash\''),
+        'message': (
+            'Please do not use "import { someFunction } from \'lodash\'". '
+            'Use "import someFunction from \'lodash/someFunction\'" instead.'),
+        'excluded_files': (),
+        'excluded_dirs': ()
     }
 ]
 


Test patch:
diff --git a/scripts/linters/general_purpose_linter_test.py b/scripts/linters/general_purpose_linter_test.py
--- a/scripts/linters/general_purpose_linter_test.py
+++ b/scripts/linters/general_purpose_linter_test.py
@@ -80,6 +80,8 @@
     LINTER_TESTS_DIR, 'invalid_eslint_any_type.ts')
 INVALID_BROADCAST_USE_FILEPATH = os.path.join(
     LINTER_TESTS_DIR, 'invalid_broadcast_use.ts')
+INVALID_LODASH_IMPORT_FILEPATH = os.path.join(
+    LINTER_TESTS_DIR, 'invalid_lodash_import.ts')
 
 # PY filepaths.
 INVALID_ITERKEY_FILEPATH = os.path.join(LINTER_TESTS_DIR, 'invalid_iterkeys.py')
@@ -372,6 +374,20 @@ def test_invalid_use_of_broadcast(self):
         self.assertEqual('Bad pattern', lint_task_report.name)
         self.assertTrue(lint_task_report.failed)
 
+    def test_invalid_lodash_import(self):
+        linter = general_purpose_linter.GeneralPurposeLinter(
+            [INVALID_LODASH_IMPORT_FILEPATH], FILE_CACHE)
+        lint_task_report = linter.check_bad_patterns()
+        self.assert_same_list_elements(
+            [
+                'Line 20: Please do not use "import { someFunction } '
+                'from \'lodash\'". Use "import someFunction '
+                'from \'lodash/someFunction\'" instead.',
+            ],
+            lint_task_report.trimmed_messages)
+        self.assertEqual('Bad pattern', lint_task_report.name)
+        self.assertTrue(lint_task_report.failed)
+
 
 class PythonLintTests(test_utils.LinterTestBase):
     """Test the Python lint functions."""
diff --git a/scripts/linters/test_files/invalid_lodash_import.ts b/scripts/linters/test_files/invalid_lodash_import.ts
new file mode 100644
--- /dev/null
+++ b/scripts/linters/test_files/invalid_lodash_import.ts
@@ -0,0 +1,20 @@
+// Copyright 2020 The Oppia Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Invalid .ts file with wrong lodash import,
+ * used by scripts/linters/general_purpose_linter.py.
+ */
+
+import { cloneDeep } from 'lodash';