Skip to content

Commit 48dba63

Browse files
authored
Fix file headers (#812)
* fix_file_headers.py Signed-off-by: Mihai Criveti <[email protected]> * fix_file_headers.py Signed-off-by: Mihai Criveti <[email protected]> * fix_file_headers.py Signed-off-by: Mihai Criveti <[email protected]> * Update file headers Signed-off-by: Mihai Criveti <[email protected]> --------- Signed-off-by: Mihai Criveti <[email protected]>
1 parent 51aadff commit 48dba63

File tree

270 files changed

+892
-592
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

270 files changed

+892
-592
lines changed

.github/tools/fix_file_headers.py

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ def show_file_lines(file_path: Path, num_lines: int = 10) -> str:
397397

398398

399399
def process_file(file_path: Path, mode: str, authors: str, show_diff: bool = False, debug: bool = False,
400-
require_shebang: Optional[bool] = None, require_encoding: bool = True) -> Optional[Dict[str, Any]]:
400+
require_shebang: Optional[bool] = None, require_encoding: bool = True) -> Optional[Dict[str, Any]]:
401401
"""Check a single file and optionally fix its header.
402402
403403
Args:
@@ -476,6 +476,8 @@ def process_file(file_path: Path, mode: str, authors: str, show_diff: bool = Fal
476476
location_match = re.search(r"^Location: \./(.*)$", docstring_node, re.MULTILINE)
477477
if not location_match:
478478
issues.append("Missing 'Location' line")
479+
elif location_match.group(1) != relative_path_str:
480+
issues.append(f"Incorrect 'Location' line: expected './{relative_path_str}', found './{location_match.group(1)}'")
479481

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

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

503-
# Extract existing header fields and body
506+
# Extract existing header fields
504507
existing_header_fields = extract_header_info(source_code, inner_content)
505508

506-
# Find where the header ends and body begins
509+
# Split docstring into lines for analysis
507510
docstring_lines = inner_content.strip().splitlines()
508-
header_end_idx = 0
511+
512+
# Separate the docstring into header and content parts
513+
content_lines = []
514+
in_header_section = False
509515

510516
for i, line in enumerate(docstring_lines):
511-
if any(line.strip().startswith(field + ":") for field in HEADER_FIELDS):
512-
header_end_idx = i + 1
513-
elif header_end_idx > 0 and line.strip():
514-
# Found first non-header content
517+
line_stripped = line.strip()
518+
519+
# Check if this line is a header field
520+
is_header_field = (any(line_stripped.startswith(field + ":") for field in HEADER_FIELDS) or
521+
line_stripped.startswith("Copyright"))
522+
523+
if is_header_field:
524+
in_header_section = True
525+
elif in_header_section and not line_stripped:
526+
# Empty line might separate header from content - continue checking
527+
continue
528+
elif in_header_section and line_stripped and not is_header_field:
529+
# Found content after header section - this and everything after is content
530+
content_lines.extend(docstring_lines[i:])
515531
break
516-
517-
# Extract body content
518-
docstring_body_lines = docstring_lines[header_end_idx:]
519-
if docstring_body_lines and not docstring_body_lines[0].strip():
520-
docstring_body_lines = docstring_body_lines[1:]
532+
elif not in_header_section and line_stripped:
533+
# Content before any header section (like module descriptions)
534+
# Look ahead to see if there are headers following
535+
has_headers_following = any(
536+
any(future_line.strip().startswith(field + ":") for field in HEADER_FIELDS) or
537+
future_line.strip().startswith("Copyright")
538+
for future_line in docstring_lines[i+1:]
539+
)
540+
if has_headers_following:
541+
# This is content, headers follow later
542+
content_lines.append(line)
543+
else:
544+
# No headers following, this is regular content
545+
content_lines.extend(docstring_lines[i:])
546+
break
521547

522548
# Build new header
523549
new_header_lines = []
524-
new_header_lines.append(existing_header_fields.get("Location") or f"Location: ./{relative_path_str}")
550+
# Always use correct location path
551+
new_header_lines.append(f"Location: ./{relative_path_str}")
525552
new_header_lines.append(existing_header_fields.get("Copyright") or f"Copyright {COPYRIGHT_YEAR}")
526553
new_header_lines.append(existing_header_fields.get("SPDX-License-Identifier") or f"SPDX-License-Identifier: {LICENSE}")
527-
new_header_lines.append(f"Authors: {authors}")
554+
# Preserve existing Authors field if it exists, otherwise use the provided authors
555+
new_header_lines.append(existing_header_fields.get("Authors") or f"Authors: {authors}")
528556

529-
# Reconstruct docstring
557+
# Reconstruct docstring with preserved content
530558
new_inner_content = "\n".join(new_header_lines)
531-
if docstring_body_lines:
532-
new_inner_content += "\n\n" + "\n".join(docstring_body_lines).strip()
559+
if content_lines:
560+
content_str = "\n".join(content_lines)
561+
new_inner_content += "\n\n" + content_str
562+
563+
# Ensure proper ending with newline before closing quotes
564+
if not new_inner_content.endswith('\n'):
565+
new_inner_content += '\n'
533566

534-
new_docstring = f"{quotes}{new_inner_content.strip()}{quotes}"
567+
new_docstring = f"{quotes}{new_inner_content}{quotes}"
535568

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

565-
if mode in ["fix-all", "fix", "interactive"]:
598+
# Generate new source code for diff preview or actual fixing
599+
if mode in ["fix-all", "fix", "interactive"] or show_diff:
566600
# Create new header
567601
new_header = get_header_template(
568602
relative_path_str,
@@ -683,15 +717,15 @@ def parse_arguments(argv: Optional[List[str]] = None) -> argparse.Namespace:
683717
# Header configuration options
684718
header_group = parser.add_argument_group("header configuration")
685719
header_group.add_argument("--require-shebang", choices=["always", "never", "auto"], default="auto",
686-
help="Require shebang line: 'always', 'never', or 'auto' (only for executable files). Default: auto")
720+
help="Require shebang line: 'always', 'never', or 'auto' (only for executable files). Default: auto")
687721
header_group.add_argument("--require-encoding", action="store_true", default=True,
688-
help="Require encoding line. Default: True")
722+
help="Require encoding line. Default: True")
689723
header_group.add_argument("--no-encoding", action="store_false", dest="require_encoding",
690-
help="Don't require encoding line.")
724+
help="Don't require encoding line.")
691725
header_group.add_argument("--copyright-year", type=int, default=COPYRIGHT_YEAR,
692-
help=f"Copyright year to use. Default: {COPYRIGHT_YEAR}")
726+
help=f"Copyright year to use. Default: {COPYRIGHT_YEAR}")
693727
header_group.add_argument("--license", type=str, default=LICENSE,
694-
help=f"License identifier to use. Default: {LICENSE}")
728+
help=f"License identifier to use. Default: {LICENSE}")
695729

696730
return parser.parse_args(argv)
697731

@@ -830,7 +864,7 @@ def print_results(issues_found: List[Dict[str, Any]], mode: str, modified_count:
830864
# Show debug info if available
831865
if "debug" in issue_info:
832866
debug = issue_info["debug"]
833-
print(f" Debug info:", file=sys.stderr)
867+
print(" Debug info:", file=sys.stderr)
834868
print(f" Executable: {debug['executable']}", file=sys.stderr)
835869
print(f" Has shebang: {debug['has_shebang']}", file=sys.stderr)
836870
print(f" Has encoding: {debug['has_encoding']}", file=sys.stderr)

mcpgateway/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# -*- coding: utf-8 -*-
2-
"""MCP Gateway - A flexible feature-rich FastAPI-based gateway for the Model Context Protocol (MCP).
3-
2+
"""Location: ./mcpgateway/__init__.py
43
Copyright 2025
54
SPDX-License-Identifier: Apache-2.0
65
Authors: Mihai Criveti
76
7+
MCP Gateway - A flexible feature-rich FastAPI-based gateway for the Model Context Protocol (MCP).
88
"""
99

1010
__author__ = "Mihai Criveti"

mcpgateway/admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# -*- coding: utf-8 -*-
2-
"""Admin UI Routes for MCP Gateway.
3-
2+
"""Location: ./mcpgateway/admin.py
43
Copyright 2025
54
SPDX-License-Identifier: Apache-2.0
65
Authors: Mihai Criveti
76
7+
Admin UI Routes for MCP Gateway.
88
This module contains all the administrative UI endpoints for the MCP Gateway.
99
It provides a comprehensive interface for managing servers, tools, resources,
1010
prompts, gateways, and roots through RESTful API endpoints. The module handles

mcpgateway/alembic/env.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# -*- coding: utf-8 -*-
2-
"""Alembic environment configuration for database migrations.
3-
2+
"""Location: ./mcpgateway/alembic/env.py
43
Copyright 2025
54
SPDX-License-Identifier: Apache-2.0
65
Authors: Mihai Criveti, Madhav Kandukuri
76
7+
Alembic environment configuration for database migrations.
88
This module configures the Alembic migration environment for the MCP Gateway
99
application. It sets up both offline and online migration modes, configures
1010
logging, and establishes the database connection parameters.

mcpgateway/alembic/versions/1fc1795f6983_merge_a2a_and_custom_name_changes.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# -*- coding: utf-8 -*-
2-
"""merge_a2a_and_custom_name_changes
2+
"""Location: ./mcpgateway/alembic/versions/1fc1795f6983_merge_a2a_and_custom_name_changes.py
3+
Copyright 2025
4+
SPDX-License-Identifier: Apache-2.0
5+
Authors: Mihai Criveti
6+
7+
merge_a2a_and_custom_name_changes
38
49
Revision ID: 1fc1795f6983
510
Revises: add_a2a_agents_and_metrics, c9dd86c0aac9
611
Create Date: 2025-08-20 19:04:40.589538
7-
812
"""
913

1014
# Standard

mcpgateway/alembic/versions/34492f99a0c4_add_comprehensive_metadata_to_all_.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# -*- coding: utf-8 -*-
2-
"""add_comprehensive_metadata_to_all_entities
2+
"""Location: ./mcpgateway/alembic/versions/34492f99a0c4_add_comprehensive_metadata_to_all_.py
3+
Copyright 2025
4+
SPDX-License-Identifier: Apache-2.0
5+
Authors: Mihai Criveti
6+
7+
add_comprehensive_metadata_to_all_entities
38
49
Revision ID: 34492f99a0c4
510
Revises: eb17fd368f9d
611
Create Date: 2025-08-18 08:06:17.141169
7-
812
"""
913

1014
# Standard

mcpgateway/alembic/versions/3b17fdc40a8d_add_passthrough_headers_to_gateways_and_.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# -*- coding: utf-8 -*-
2-
"""Add passthrough headers to gateways and global config
2+
"""Location: ./mcpgateway/alembic/versions/3b17fdc40a8d_add_passthrough_headers_to_gateways_and_.py
3+
Copyright 2025
4+
SPDX-License-Identifier: Apache-2.0
5+
Authors: Mihai Criveti
6+
7+
Add passthrough headers to gateways and global config
38
49
Revision ID: 3b17fdc40a8d
510
Revises: e75490e949b1
611
Create Date: 2025-08-08 03:45:46.489696
7-
812
"""
913

1014
# Standard

mcpgateway/alembic/versions/add_a2a_agents_and_metrics.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# -*- coding: utf-8 -*-
2-
"""add_a2a_agents_and_metrics
2+
"""Location: ./mcpgateway/alembic/versions/add_a2a_agents_and_metrics.py
3+
Copyright 2025
4+
SPDX-License-Identifier: Apache-2.0
5+
Authors: Mihai Criveti
6+
7+
add_a2a_agents_and_metrics
38
49
Revision ID: add_a2a_agents_and_metrics
510
Revises: add_oauth_tokens_table
611
Create Date: 2025-08-19 10:00:00.000000
7-
812
"""
913

1014
# Standard

mcpgateway/alembic/versions/add_oauth_tokens_table.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# -*- coding: utf-8 -*-
2-
"""add oauth tokens table
2+
"""Location: ./mcpgateway/alembic/versions/add_oauth_tokens_table.py
3+
Copyright 2025
4+
SPDX-License-Identifier: Apache-2.0
5+
Authors: Mihai Criveti
6+
7+
add oauth tokens table
38
49
Revision ID: add_oauth_tokens_table
510
Revises: f8c9d3e2a1b4
611
Create Date: 2024-12-20 11:00:00.000000
7-
812
"""
913

1014
# Standard

mcpgateway/alembic/versions/b77ca9d2de7e_uuid_pk_and_slug_refactor.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# -*- coding: utf-8 -*-
2-
"""uuid-pk_and_slug_refactor
2+
"""Location: ./mcpgateway/alembic/versions/b77ca9d2de7e_uuid_pk_and_slug_refactor.py
3+
Copyright 2025
4+
SPDX-License-Identifier: Apache-2.0
5+
Authors: Mihai Criveti
6+
7+
uuid-pk_and_slug_refactor
38
49
Revision ID: b77ca9d2de7e
510
Revises:
611
Create Date: 2025-06-26 21:29:59.117140
7-
812
"""
913

1014
# Standard

0 commit comments

Comments
 (0)