Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code coverage disable check to GitHub workflows #2701

Open
wants to merge 34 commits into
base: develop-postgres
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
469a361
feat: add script to check for code coverage disable statements
Dec 21, 2024
cea12f1
Add code coverage disable check to GitHub workflows
Dec 21, 2024
70fc259
Merge branch 'develop-postgres' of https://github.com/PalisadoesFound…
Dec 22, 2024
6e68380
Formatted code_coverage_disable_check.py to comply with all coding an…
Dec 22, 2024
679fc49
add functionality in eslint_disable_check.py to run for mutliple dire…
Dec 22, 2024
01c430a
removed unnecessary comment
Dec 22, 2024
7d26173
Merge branch 'develop-postgres' into workflow
im-vedant Dec 22, 2024
b575036
excluded node_modules from eslint disable check
Dec 22, 2024
cf69d03
Merge branch 'develop-postgres' into workflow
im-vedant Dec 23, 2024
3e89e1d
Merge branch 'develop-postgres' into workflow
im-vedant Dec 23, 2024
a460044
Merge branch 'develop-postgres' of https://github.com/PalisadoesFound…
Dec 24, 2024
62d4232
removed all eslint disable statements and code coverage disable state…
Dec 24, 2024
0c3219a
Merge branch 'workflow' of https://github.com/im-vedant/talawa-admin …
Dec 24, 2024
1e7ea13
Revert "excluded node_modules from eslint disable check"
Dec 24, 2024
e841044
Revert "removed all eslint disable statements and code coverage disab…
Dec 24, 2024
793b317
excluded node_modules from eslint disable check
Dec 24, 2024
063f1de
code-coverage check runs for only changed files
Dec 25, 2024
e385ba6
add tj-actions
Dec 25, 2024
dcce073
add tj actions in check code coverage job
Dec 25, 2024
b0c79d7
Merge branch 'develop-postgres' into workflow
palisadoes Dec 25, 2024
1e1aa45
Merge branch 'develop-postgres' into workflow
im-vedant Dec 25, 2024
50df8a3
Merge branch 'develop-postgres' of https://github.com/PalisadoesFound…
Dec 26, 2024
f974bbf
Fix GitHub Actions workflow to identify and pass nearest changed dire…
Dec 26, 2024
1dc3a93
Merge branch 'workflow' of https://github.com/im-vedant/talawa-admin …
Dec 26, 2024
7467034
syntax correction
Dec 26, 2024
9dfacc7
minor fix
Dec 26, 2024
57fa9a3
minor fix
Dec 26, 2024
17aebf5
minor fix
Dec 26, 2024
5b83566
added repo root
Dec 26, 2024
624feb9
fix error
Dec 26, 2024
ffe620d
fix error
Dec 26, 2024
9e5460c
added support for checking .ts files for eslint-disable statements
Dec 26, 2024
8712ed0
added support for checking .ts files for code coverage disable statem…
Dec 26, 2024
2c26f59
Merge branch 'develop-postgres' of https://github.com/PalisadoesFound…
Dec 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions .github/workflows/code_coverage_disable_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
"""Code Coverage Disable Checker Script.

Check warning on line 1 in .github/workflows/code_coverage_disable_check.py

View workflow job for this annotation

GitHub Actions / Performs linting, formatting, type-checking, checking for different source and target branch

File ignored by default.

Methodology:

Recursively analyzes TypeScript files in the specified directories or checks specific files
to ensure they do not contain code coverage disable statements.

This script enforces proper code coverage practices in the project.

NOTE:
This script complies with our python3 coding and documentation standards.
It complies with:

1) Pylint
2) Pydocstyle
3) Pycodestyle
im-vedant marked this conversation as resolved.
Show resolved Hide resolved
4) Flake8
5) Python Black

"""

import os
import re
import argparse
import sys


def has_code_coverage_disable(file_path):
"""
Check if a TypeScript file contains code coverage disable statements.

Args:
file_path (str): Path to the TypeScript file.

Returns:
bool: True if code coverage disable statement is found, False
otherwise.
"""
code_coverage_disable_pattern = re.compile(
r"""//?\s*istanbul\s+ignore(?:\s+(?:next|-line))?[^\n]*|/\*\s*istanbul\s+ignore\s+(?:next|-line)\s*\*/""",
re.IGNORECASE,
)
try:
with open(file_path, "r", encoding="utf-8") as file:
content = file.read()
return bool(code_coverage_disable_pattern.search(content))
except FileNotFoundError:
print(f"File not found: {file_path}")
return False
except PermissionError:
print(f"Permission denied: {file_path}")
return False
except (IOError, OSError) as e:
print(f"Error reading file {file_path}: {e}")
return False


def check_code_coverage(files_or_dirs):
"""
Check TypeScript files for code coverage disable statements.

Args:
files_or_dirs (list): List of files or directories to check.

Returns:
bool: True if code coverage disable statement is found, False
otherwise.
"""
code_coverage_found = False

for item in files_or_dirs:
if os.path.isdir(item):
# If it's a directory, recursively walk through the files in it
for root, _, files in os.walk(item):
if "node_modules" in root:
continue
for file_name in files:
if (
file_name.endswith(".tsx")
or file_name.endswith(".ts")
):
file_path = os.path.join(root, file_name)
if has_code_coverage_disable(file_path):
print(f"File {file_path} contains code coverage disable statement.")
code_coverage_found = True
elif os.path.isfile(item):
# If it's a file, check it directly
if (
item.endswith(".tsx")
or item.endswith(".ts")
) :
if has_code_coverage_disable(item):
print(f"File {item} contains code coverage disable statement.")
code_coverage_found = True

return code_coverage_found

im-vedant marked this conversation as resolved.
Show resolved Hide resolved

def arg_parser_resolver():
"""Resolve the CLI arguments provided by the user.

Returns:
result: Parsed argument object
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"--directory",
type=str,
nargs="+",
default=[os.getcwd()],
help="""One or more directories to check for code coverage disable
statements (default: current directory).""",
)
parser.add_argument(
"--files",
type=str,
nargs="+",
default=[],
help="""One or more files to check directly for code coverage disable
statements (default: check directories).""",
)
return parser.parse_args()


def main():
"""
Execute the script's main functionality.

This function serves as the entry point for the script. It performs
the following tasks:
1. Validates and retrieves the files or directories to check from
command line arguments.
2. Checks files or directories for code coverage disable statements.
3. Provides informative messages based on the analysis.
4. Exits with an error if code coverage disable statements are found.

Raises:
SystemExit: If an error occurs during execution.
"""
args = arg_parser_resolver()

files_or_dirs = args.files if args.files else args.directory
print(files_or_dirs)
# Check code coverage in the specified files or directories
code_coverage_found = check_code_coverage(files_or_dirs)

if code_coverage_found:
print("Code coverage disable check failed. Exiting with error.")
sys.exit(1)

print("Code coverage disable check completed successfully.")


if __name__ == "__main__":
main()
93 changes: 61 additions & 32 deletions .github/workflows/eslint_disable_check.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
#!/usr/bin/env python3

Check warning on line 1 in .github/workflows/eslint_disable_check.py

View workflow job for this annotation

GitHub Actions / Performs linting, formatting, type-checking, checking for different source and target branch

File ignored by default.
# -*- coding: UTF-8 -*-
# -*- coding: UTF-8 -*-
"""ESLint Checker Script.

Methodology:

Recursively analyzes TypeScript files in the 'src' directory and its subdirectories
as well as 'setup.ts' files to ensure they do not contain eslint-disable statements.
Recursively analyzes TypeScript files in the specified directory
or checks specific files directly to ensure they do not contain eslint-disable statements.

This script enforces code quality practices in the project.

NOTE:

This script complies with our python3 coding and documentation standards.
It complies with:

1) Pylint
2) Pydocstyle
3) Pycodestyle
4) Flake8
5) Python Black

"""

import os
import re
import argparse
import sys


def has_eslint_disable(file_path):
"""
Check if a TypeScript file contains eslint-disable statements.
Expand All @@ -36,65 +36,94 @@
Returns:
bool: True if eslint-disable statement is found, False otherwise.
"""
eslint_disable_pattern = re.compile(r'//\s*eslint-disable(?:-next-line|-line)?', re.IGNORECASE)

eslint_disable_pattern = re.compile(
r"""\/\/\s*eslint-disable(?:-next-line
|-line)?[^\n]*|\/\*\s*eslint-disable[^\*]*\*\/""",
re.IGNORECASE,
)
im-vedant marked this conversation as resolved.
Show resolved Hide resolved

try:
with open(file_path, 'r', encoding='utf-8') as file:
with open(file_path, "r", encoding="utf-8") as file:
content = file.read()
return bool(eslint_disable_pattern.search(content))
except Exception as e:
except FileNotFoundError:
print(f"File not found: {file_path}")
return False
except PermissionError:
print(f"Permission denied: {file_path}")
return False
except (IOError, OSError) as e:
print(f"Error reading file {file_path}: {e}")
return False

def check_eslint(directory):

def check_eslint(files_or_directories):
"""
Recursively check TypeScript files for eslint-disable statements in the 'src' directory.
Check TypeScript files for eslint-disable statements.

Args:
directory (str): Path to the directory.
files_or_directories (list): List of files or directories to check.

Returns:
bool: True if eslint-disable statement is found, False otherwise.
"""
eslint_found = False

for root, dirs, files in os.walk(os.path.join(directory, 'src')):
for file_name in files:
if file_name.endswith('.tsx') and not file_name.endswith('.test.tsx'):
file_path = os.path.join(root, file_name)
if has_eslint_disable(file_path):
print(f'File {file_path} contains eslint-disable statement.')
for item in files_or_directories:
if os.path.isfile(item):
# If it's a file, directly check it
if item.endswith(".ts") or item.endswith(".tsx"):
if has_eslint_disable(item):
print(f"File {item} contains eslint-disable statement.")
eslint_found = True

setup_path = os.path.join(directory, 'setup.ts')
if os.path.exists(setup_path) and has_eslint_disable(setup_path):
print(f'Setup file {setup_path} contains eslint-disable statement.')
eslint_found = True
elif os.path.isdir(item):
# If it's a directory, walk through it and check all .ts and .tsx files
for root, _, files in os.walk(item):
if "node_modules" in root:
continue
for file_name in files:
if file_name.endswith(".ts") or file_name.endswith(".tsx"):
file_path = os.path.join(root, file_name)
if has_eslint_disable(file_path):
print(f"File {file_path} contains eslint-disable statement.")
eslint_found = True

return eslint_found


def arg_parser_resolver():
"""Resolve the CLI arguments provided by the user.

Returns:
result: Parsed argument object
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"--files",
type=str,
nargs="+",
default=[],
help="""List of files to check for eslint disable
statements (default: None).""",
)
parser.add_argument(
"--directory",
type=str,
default=os.getcwd(),
help="Path to the directory to check (default: current directory)"
nargs="+",
default=[os.getcwd()],
help="""One or more directories to check for eslint disable
statements (default: current directory).""",
)
return parser.parse_args()


def main():
"""
Execute the script's main functionality.

This function serves as the entry point for the script. It performs
the following tasks:
1. Validates and retrieves the directory to check from
1. Validates and retrieves the files and directories to check from
command line arguments.
2. Recursively checks TypeScript files for eslint-disable statements.
3. Provides informative messages based on the analysis.
Expand All @@ -105,18 +134,18 @@
"""
args = arg_parser_resolver()

if not os.path.exists(args.directory):
print(f"Error: The specified directory '{args.directory}' does not exist.")
sys.exit(1)

# Check eslint in the specified directory
eslint_found = check_eslint(args.directory)
# Determine whether to check files or directories based on the arguments
files_or_directories = args.files if args.files else args.directory
print(files_or_directories)
# Check eslint in the specified files or directories
eslint_found = check_eslint(files_or_directories)

if eslint_found:
print("ESLint-disable check failed. Exiting with error.")
sys.exit(1)

print("ESLint-disable check completed successfully.")


if __name__ == "__main__":
main()
28 changes: 26 additions & 2 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
##############################################################################

Check warning on line 1 in .github/workflows/pull-request.yml

View workflow job for this annotation

GitHub Actions / Performs linting, formatting, type-checking, checking for different source and target branch

File ignored by default.
##############################################################################
#
# NOTE!
Expand Down Expand Up @@ -178,19 +178,43 @@
- name: Checkout code
uses: actions/checkout@v4

- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v45

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.9

- name: Run Python script
run: |
python .github/workflows/eslint_disable_check.py --files ${{ steps.changed-files.outputs.all_changed_files }}

Check-Code-Coverage-Disable:
name: Check for code coverage disable
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v45

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.9

- name: Run Python script
run: |
python .github/workflows/eslint_disable_check.py
python .github/workflows/code_coverage_disable_check.py --files ${{ steps.changed-files.outputs.all_changed_files }}

Test-Application:
im-vedant marked this conversation as resolved.
Show resolved Hide resolved
name: Test Application
runs-on: ubuntu-latest
needs: [Code-Quality-Checks, Check-ESlint-Disable]
needs: [Code-Quality-Checks, Check-ESlint-Disable,Check-Code-Coverage-Disable]
steps:
- name: Checkout the Repository
uses: actions/checkout@v4
Expand Down
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ const { setItem } = useLocalStorage();
*
* @returns The rendered routes and components of the application.
*/
// eslint-disable

// istanbul ignore next
function app(): JSX.Element {
/*const { updatePluginLinks, updateInstalled } = bindActionCreators(
actionCreators,
Expand Down
2 changes: 1 addition & 1 deletion src/setupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

// eslint-disable
global.fetch = jest.fn();

import { format } from 'util';
Expand Down
Loading