Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
88 changes: 61 additions & 27 deletions .github/tools/fix_file_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def show_file_lines(file_path: Path, num_lines: int = 10) -> str:


def process_file(file_path: Path, mode: str, authors: str, show_diff: bool = False, debug: bool = False,
require_shebang: Optional[bool] = None, require_encoding: bool = True) -> Optional[Dict[str, Any]]:
require_shebang: Optional[bool] = None, require_encoding: bool = True) -> Optional[Dict[str, Any]]:
"""Check a single file and optionally fix its header.

Args:
Expand Down Expand Up @@ -476,6 +476,8 @@ def process_file(file_path: Path, mode: str, authors: str, show_diff: bool = Fal
location_match = re.search(r"^Location: \./(.*)$", docstring_node, re.MULTILINE)
if not location_match:
issues.append("Missing 'Location' line")
elif location_match.group(1) != relative_path_str:
issues.append(f"Incorrect 'Location' line: expected './{relative_path_str}', found './{location_match.group(1)}'")

if f"Copyright {COPYRIGHT_YEAR}" not in docstring_node:
issues.append("Missing 'Copyright' line")
Expand All @@ -489,7 +491,8 @@ def process_file(file_path: Path, mode: str, authors: str, show_diff: bool = Fal
if not issues:
return None

if mode in ["fix-all", "fix", "interactive"]:
# Generate new source code for diff preview or actual fixing
if mode in ["fix-all", "fix", "interactive"] or show_diff:
# Extract the raw docstring from source
if module_body and isinstance(module_body[0], ast.Expr):
docstring_expr_node = module_body[0]
Expand All @@ -500,38 +503,68 @@ def process_file(file_path: Path, mode: str, authors: str, show_diff: bool = Fal
quotes = '"""' if raw_docstring.startswith('"""') else "'''"
inner_content = raw_docstring.strip(quotes)

# Extract existing header fields and body
# Extract existing header fields
existing_header_fields = extract_header_info(source_code, inner_content)

# Find where the header ends and body begins
# Split docstring into lines for analysis
docstring_lines = inner_content.strip().splitlines()
header_end_idx = 0

# Separate the docstring into header and content parts
content_lines = []
in_header_section = False

for i, line in enumerate(docstring_lines):
if any(line.strip().startswith(field + ":") for field in HEADER_FIELDS):
header_end_idx = i + 1
elif header_end_idx > 0 and line.strip():
# Found first non-header content
line_stripped = line.strip()

# Check if this line is a header field
is_header_field = (any(line_stripped.startswith(field + ":") for field in HEADER_FIELDS) or
line_stripped.startswith("Copyright"))

if is_header_field:
in_header_section = True
elif in_header_section and not line_stripped:
# Empty line might separate header from content - continue checking
continue
elif in_header_section and line_stripped and not is_header_field:
# Found content after header section - this and everything after is content
content_lines.extend(docstring_lines[i:])
break

# Extract body content
docstring_body_lines = docstring_lines[header_end_idx:]
if docstring_body_lines and not docstring_body_lines[0].strip():
docstring_body_lines = docstring_body_lines[1:]
elif not in_header_section and line_stripped:
# Content before any header section (like module descriptions)
# Look ahead to see if there are headers following
has_headers_following = any(
any(future_line.strip().startswith(field + ":") for field in HEADER_FIELDS) or
future_line.strip().startswith("Copyright")
for future_line in docstring_lines[i+1:]
)
if has_headers_following:
# This is content, headers follow later
content_lines.append(line)
else:
# No headers following, this is regular content
content_lines.extend(docstring_lines[i:])
break

# Build new header
new_header_lines = []
new_header_lines.append(existing_header_fields.get("Location") or f"Location: ./{relative_path_str}")
# Always use correct location path
new_header_lines.append(f"Location: ./{relative_path_str}")
new_header_lines.append(existing_header_fields.get("Copyright") or f"Copyright {COPYRIGHT_YEAR}")
new_header_lines.append(existing_header_fields.get("SPDX-License-Identifier") or f"SPDX-License-Identifier: {LICENSE}")
new_header_lines.append(f"Authors: {authors}")
# Preserve existing Authors field if it exists, otherwise use the provided authors
new_header_lines.append(existing_header_fields.get("Authors") or f"Authors: {authors}")

# Reconstruct docstring
# Reconstruct docstring with preserved content
new_inner_content = "\n".join(new_header_lines)
if docstring_body_lines:
new_inner_content += "\n\n" + "\n".join(docstring_body_lines).strip()
if content_lines:
content_str = "\n".join(content_lines)
new_inner_content += "\n\n" + content_str

# Ensure proper ending with newline before closing quotes
if not new_inner_content.endswith('\n'):
new_inner_content += '\n'

new_docstring = f"{quotes}{new_inner_content.strip()}{quotes}"
new_docstring = f"{quotes}{new_inner_content}{quotes}"

# Prepare source with appropriate headers
header_lines = []
Expand Down Expand Up @@ -562,7 +595,8 @@ def process_file(file_path: Path, mode: str, authors: str, show_diff: bool = Fal
# No docstring found
issues.append("No docstring found")

if mode in ["fix-all", "fix", "interactive"]:
# Generate new source code for diff preview or actual fixing
if mode in ["fix-all", "fix", "interactive"] or show_diff:
# Create new header
new_header = get_header_template(
relative_path_str,
Expand Down Expand Up @@ -683,15 +717,15 @@ def parse_arguments(argv: Optional[List[str]] = None) -> argparse.Namespace:
# Header configuration options
header_group = parser.add_argument_group("header configuration")
header_group.add_argument("--require-shebang", choices=["always", "never", "auto"], default="auto",
help="Require shebang line: 'always', 'never', or 'auto' (only for executable files). Default: auto")
help="Require shebang line: 'always', 'never', or 'auto' (only for executable files). Default: auto")
header_group.add_argument("--require-encoding", action="store_true", default=True,
help="Require encoding line. Default: True")
help="Require encoding line. Default: True")
header_group.add_argument("--no-encoding", action="store_false", dest="require_encoding",
help="Don't require encoding line.")
help="Don't require encoding line.")
header_group.add_argument("--copyright-year", type=int, default=COPYRIGHT_YEAR,
help=f"Copyright year to use. Default: {COPYRIGHT_YEAR}")
help=f"Copyright year to use. Default: {COPYRIGHT_YEAR}")
header_group.add_argument("--license", type=str, default=LICENSE,
help=f"License identifier to use. Default: {LICENSE}")
help=f"License identifier to use. Default: {LICENSE}")

return parser.parse_args(argv)

Expand Down Expand Up @@ -830,7 +864,7 @@ def print_results(issues_found: List[Dict[str, Any]], mode: str, modified_count:
# Show debug info if available
if "debug" in issue_info:
debug = issue_info["debug"]
print(f" Debug info:", file=sys.stderr)
print(" Debug info:", file=sys.stderr)
print(f" Executable: {debug['executable']}", file=sys.stderr)
print(f" Has shebang: {debug['has_shebang']}", file=sys.stderr)
print(f" Has encoding: {debug['has_encoding']}", file=sys.stderr)
Expand Down
4 changes: 2 additions & 2 deletions mcpgateway/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
"""MCP Gateway - A flexible feature-rich FastAPI-based gateway for the Model Context Protocol (MCP).

"""Location: ./mcpgateway/__init__.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

MCP Gateway - A flexible feature-rich FastAPI-based gateway for the Model Context Protocol (MCP).
"""

__author__ = "Mihai Criveti"
Expand Down
4 changes: 2 additions & 2 deletions mcpgateway/admin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
"""Admin UI Routes for MCP Gateway.

"""Location: ./mcpgateway/admin.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

Admin UI Routes for MCP Gateway.
This module contains all the administrative UI endpoints for the MCP Gateway.
It provides a comprehensive interface for managing servers, tools, resources,
prompts, gateways, and roots through RESTful API endpoints. The module handles
Expand Down
4 changes: 2 additions & 2 deletions mcpgateway/alembic/env.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
"""Alembic environment configuration for database migrations.

"""Location: ./mcpgateway/alembic/env.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti, Madhav Kandukuri

Alembic environment configuration for database migrations.
This module configures the Alembic migration environment for the MCP Gateway
application. It sets up both offline and online migration modes, configures
logging, and establishes the database connection parameters.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""merge_a2a_and_custom_name_changes
"""Location: ./mcpgateway/alembic/versions/1fc1795f6983_merge_a2a_and_custom_name_changes.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

merge_a2a_and_custom_name_changes

Revision ID: 1fc1795f6983
Revises: add_a2a_agents_and_metrics, c9dd86c0aac9
Create Date: 2025-08-20 19:04:40.589538

"""

# Standard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""add_comprehensive_metadata_to_all_entities
"""Location: ./mcpgateway/alembic/versions/34492f99a0c4_add_comprehensive_metadata_to_all_.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

add_comprehensive_metadata_to_all_entities

Revision ID: 34492f99a0c4
Revises: eb17fd368f9d
Create Date: 2025-08-18 08:06:17.141169

"""

# Standard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""Add passthrough headers to gateways and global config
"""Location: ./mcpgateway/alembic/versions/3b17fdc40a8d_add_passthrough_headers_to_gateways_and_.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

Add passthrough headers to gateways and global config

Revision ID: 3b17fdc40a8d
Revises: e75490e949b1
Create Date: 2025-08-08 03:45:46.489696

"""

# Standard
Expand Down
8 changes: 6 additions & 2 deletions mcpgateway/alembic/versions/add_a2a_agents_and_metrics.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""add_a2a_agents_and_metrics
"""Location: ./mcpgateway/alembic/versions/add_a2a_agents_and_metrics.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

add_a2a_agents_and_metrics

Revision ID: add_a2a_agents_and_metrics
Revises: add_oauth_tokens_table
Create Date: 2025-08-19 10:00:00.000000

"""

# Standard
Expand Down
8 changes: 6 additions & 2 deletions mcpgateway/alembic/versions/add_oauth_tokens_table.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""add oauth tokens table
"""Location: ./mcpgateway/alembic/versions/add_oauth_tokens_table.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

add oauth tokens table

Revision ID: add_oauth_tokens_table
Revises: f8c9d3e2a1b4
Create Date: 2024-12-20 11:00:00.000000

"""

# Standard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""uuid-pk_and_slug_refactor
"""Location: ./mcpgateway/alembic/versions/b77ca9d2de7e_uuid_pk_and_slug_refactor.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

uuid-pk_and_slug_refactor

Revision ID: b77ca9d2de7e
Revises:
Create Date: 2025-06-26 21:29:59.117140

"""

# Standard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""remove original_name_slug and added custom_name
"""Location: ./mcpgateway/alembic/versions/c9dd86c0aac9_remove_original_name_slug_and_added_.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

remove original_name_slug and added custom_name

Revision ID: c9dd86c0aac9
Revises: add_oauth_tokens_table
Create Date: 2025-08-19 15:15:26.509036

"""

# Standard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""add_tags_support_to_all_entities
"""Location: ./mcpgateway/alembic/versions/cc7b95fec5d9_add_tags_support_to_all_entities.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

add_tags_support_to_all_entities

Revision ID: cc7b95fec5d9
Revises: e75490e949b1
Create Date: 2025-08-06 22:27:08.682814

"""

# Standard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""Add annotations to tables
"""Location: ./mcpgateway/alembic/versions/e4fc04d1a442_add_annotations_to_tables.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

Add annotations to tables

Revision ID: e4fc04d1a442
Revises: b77ca9d2de7e
Create Date: 2025-06-27 21:45:35.099713

"""

# Standard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# -*- coding: utf-8 -*-
"""Add enabled and reachable columns in tools and gateways tables and migrate data (is_active ➜ enabled,reachable).
"""Location: ./mcpgateway/alembic/versions/e75490e949b1_add_improved_status_to_tables.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

Add enabled and reachable columns in tools and gateways tables and migrate data (is_active ➜ enabled,reachable).

Revision ID: e75490e949b1
Revises: e4fc04d1a442
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""merge passthrough headers and tags support
"""Location: ./mcpgateway/alembic/versions/eb17fd368f9d_merge_passthrough_headers_and_tags_.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

merge passthrough headers and tags support

Revision ID: eb17fd368f9d
Revises: 3b17fdc40a8d, cc7b95fec5d9
Create Date: 2025-08-08 05:31:10.857718

"""

# Standard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
"""add oauth config to gateways
"""Location: ./mcpgateway/alembic/versions/f8c9d3e2a1b4_add_oauth_config_to_gateways.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

add oauth config to gateways

Revision ID: f8c9d3e2a1b4
Revises: eb17fd368f9d
Create Date: 2024-12-20 10:00:00.000000

"""

# Standard
Expand Down
Loading
Loading