Repository: oppia/oppia

Issue:
Address review comments on #7283
<!--
  - Thanks for taking the time to report a bug in the Oppia project.
  - Before filing a new issue, please do a quick search to check that it hasn't
  - already been filed on the [issue tracker](https://github.com/oppia/oppia/issues)._
  -->

Address [review comments](https://github.com/oppia/oppia/pull/7283#pullrequestreview-270482101) on #7283.


Discussion:

Resolving patch:
diff --git a/scripts/pre_commit_linter.py b/scripts/pre_commit_linter.py
--- a/scripts/pre_commit_linter.py
+++ b/scripts/pre_commit_linter.py
@@ -2448,8 +2448,10 @@ def _check_extra_js_files(self):
 
     def _check_constants_declaration(self):
         """Checks the declaration of constants in the TS files to ensure that
-        the constants are not declared in files other than *.constants.ts and
-        that the constants are declared only single time.
+        the constants are not declared in files other than *.constants.ajs.ts
+        and that the constants are declared only single time. This also checks
+        that the constants are declared in both *.constants.ajs.ts (for
+        AngularJS) and in *.constants.ts (for Angular 8).
         """
 
         if self.verbose_mode_enabled:
@@ -2464,10 +2466,80 @@ def _check_constants_declaration(self):
                 filepath for filepath in self.all_filepaths if (
                     filepath.endswith('.ts'))]
             constants_to_source_filepaths_dict = {}
+            angularjs_source_filepaths_to_constants_dict = {}
             for filepath in ts_files_to_check:
-                # Check that the constants are declared only in a *.constants.ts
+                # The following block extracts the corresponding Angularjs
+                # constants file for the Angular constants file. This is
+                # required since the check cannot proceed if the AngularJS
+                # constants file is not provided before the Angular constants
                 # file.
-                if not filepath.endswith('.constants.ts'):
+                if filepath.endswith('.constants.ts'):
+                    filename_without_extension = filepath[:-3]
+                    corresponding_angularjs_filepath = (
+                        filename_without_extension + '.ajs.ts')
+                    compiled_js_dir = tempfile.mkdtemp(dir=os.getcwd())
+                    try:
+                        if os.path.isfile(corresponding_angularjs_filepath):
+                            compiled_js_filepath = self._compile_ts_file(
+                                corresponding_angularjs_filepath,
+                                compiled_js_dir)
+                            file_content = FileCache.read(
+                                compiled_js_filepath).decode('utf-8')
+
+                            parsed_script = esprima.parseScript(file_content)
+                            parsed_nodes = parsed_script.body
+                            angularjs_constants_list = []
+                            components_to_check = ['constant']
+                            for parsed_node in parsed_nodes:
+                                expression = (
+                                    _get_expression_from_node_if_one_exists(
+                                        parsed_node, components_to_check))
+                                if not expression:
+                                    continue
+                                else:
+                                    # The following block populates a set to
+                                    # store constants for the Angular-AngularJS
+                                    # constants file consistency check.
+                                    angularjs_constants_name = (
+                                        expression.arguments[0].value)
+                                    angularjs_constants_value = (
+                                        expression.arguments[1].property.name)
+                                    if angularjs_constants_value != (
+                                            angularjs_constants_name):
+                                        failed = True
+                                        print ('%s --> Please ensure that the '
+                                               'constant %s is initialized '
+                                               'from the value from the '
+                                               'corresponding Angular constants'
+                                               ' file (the *.constants.ts '
+                                               'file). Please create one in the'
+                                               ' Angular constants file if it '
+                                               'does not exist there.' % (
+                                                   filepath,
+                                                   angularjs_constants_name))
+                                    angularjs_constants_list.append(
+                                        angularjs_constants_name)
+                            angularjs_constants_set = set(
+                                angularjs_constants_list)
+                            if len(angularjs_constants_set) != len(
+                                    angularjs_constants_list):
+                                failed = True
+                                print ('%s --> Duplicate constant declaration '
+                                       'found.' % (
+                                           corresponding_angularjs_filepath))
+                            angularjs_source_filepaths_to_constants_dict[
+                                corresponding_angularjs_filepath] = (
+                                    angularjs_constants_set)
+                        else:
+                            failed = True
+                            print ('%s --> Corresponding AngularJS constants '
+                                   'file not found.' % filepath)
+
+                    finally:
+                        shutil.rmtree(compiled_js_dir)
+                # Check that the constants are declared only in a
+                # *.constants.ajs.ts file.
+                if not filepath.endswith('.constants.ajs.ts'):
                     for line_num, line in enumerate(FileCache.readlines(
                             filepath)):
                         if 'oppia.constant(' in line:
@@ -2482,6 +2554,7 @@ def _check_constants_declaration(self):
                 parsed_script = self.parsed_js_and_ts_files[filepath]
                 parsed_nodes = parsed_script.body
                 components_to_check = ['constant']
+                angular_constants_list = []
                 for parsed_node in parsed_nodes:
                     expression = _get_expression_from_node_if_one_exists(
                         parsed_node, components_to_check)
@@ -2502,6 +2575,35 @@ def _check_constants_declaration(self):
                             constants_to_source_filepaths_dict[
                                 constant_name] = filepath
 
+                # Checks that the *.constants.ts and the corresponding
+                # *.constants.ajs.ts file are in sync.
+                if filepath.endswith('.constants.ts'):
+                    angular_constants_nodes = (
+                        parsed_nodes[1].declarations[0].init.callee.body.body)
+                    for angular_constant_node in angular_constants_nodes:
+                        if not angular_constant_node.expression:
+                            continue
+                        angular_constant_name = (
+                            angular_constant_node.expression.left.property.name)
+                        angular_constants_list.append(angular_constant_name)
+
+                    angular_constants_set = set(angular_constants_list)
+                    if len(angular_constants_set) != len(
+                            angular_constants_list):
+                        failed = True
+                        print ('%s --> Duplicate constant declaration found.'
+                               % filepath)
+                    if corresponding_angularjs_filepath in (
+                            angularjs_source_filepaths_to_constants_dict):
+                        angular_minus_angularjs_constants = (
+                            angular_constants_set.difference(
+                                angularjs_source_filepaths_to_constants_dict[
+                                    corresponding_angularjs_filepath]))
+                        for constant in angular_minus_angularjs_constants:
+                            failed = True
+                            print ('%s --> The constant %s is not declared '
+                                   'in the corresponding angularjs '
+                                   'constants file.' % (filepath, constant))
 
             if failed:
                 summary_message = '%s  Constants declaration check failed' % (


Test patch: