Skip to content
Open
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
2 changes: 1 addition & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ All changes:
https://github.com/Open-MSS/MSS/milestone/48?closed=1

Version 2.0.1
---------------
-------------

Bug Fix release

Expand Down
2 changes: 1 addition & 1 deletion docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ like e.g. a running MSColab server or a QApplication instance for GUI tests,
are collected in :mod:`tests.fixtures` in the form of pytest fixtures that can be requested as needed in tests.

Keyring Features
-----------------
----------------

This document outlines step-by-step instructions for using the keyring features using the command line.

Expand Down
2 changes: 1 addition & 1 deletion docs/mssautoplot.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ of topview in the mssautoplot.json.


Settings file
--------------
-------------

This file includes configuration settings to generate plots in automated fashion. It includes,

Expand Down
2 changes: 1 addition & 1 deletion docs/samples/plugins/navaid.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.plugins.io.navaid
~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~

plugin for navaid format flight track export

Expand Down
212 changes: 212 additions & 0 deletions heading_linter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# -*- coding: utf-8 -*-
"""

mslib.modulename
~~~~~~~~~~~~~~~~

Text line as description

This file is part of MSS.

:copyright: Copyright 2017 Main Contributor
:copyright: Copyright 2017-2025 by the MSS team, see AUTHORS.
:license: APACHE-2.0, see LICENSE for details.

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.
"""

#Linux
#python3 heading_linter.py to see the errors
#python3 heading_linter.py --fix to fix them

#!/usr/bin/env python3
"""
Improved linter that checks and fixes Sphinx heading underline lengths.
Now shows exact file path, line numbers, expected length, actual length.
"""

import argparse
import glob
import os
import re
import sys

VALID_CHARS = "= - ` : \" ~ ^ _ * + # < >".split()
UNDERLINE_RE = re.compile(r'^(\s*)([=\-`:\"~^_*+#<>])\2{2,}\s*$')


def scan_repo(patterns):
files = []

if not patterns:
for root, dirs, filenames in os.walk("."):
for skip in (".git", "__pycache__", ".ipynb_checkpoints"):
if skip in dirs:
dirs.remove(skip)

for filename in filenames:
if filename.endswith(".py") or filename.endswith(".rst"):
files.append(os.path.join(root, filename))

return sorted(files)

for p in patterns:
files.extend(glob.glob(p, recursive=True))
return sorted(set(files))


def is_docstring(line):
stripped = line.strip()
return stripped in ('"""', "'''") or stripped.startswith('"""') or stripped.startswith("'''")


def process_file(path, fix=False):
try:
with open(path, "r", encoding="utf-8") as f:
lines = f.readlines()
except:
print(f"Skipping unreadable file: {path}")
return 0

errors = 0
new_lines = []
i = 0

while i < len(lines):
line = lines[i]

# --------------------------
# CASE 1: title + underline
# --------------------------
if i + 1 < len(lines):
underline = lines[i + 1]

if not is_docstring(line) and not is_docstring(underline):
m = UNDERLINE_RE.match(underline)

if m:
indent, ch = m.group(1), m.group(2)
title = line.rstrip("\n")
stripped_title = title.strip()

if stripped_title:
expected = len(stripped_title)
actual = len(underline.strip())

if expected != actual:
errors += 1
print(
f"{path}:{i+2}: ERROR — underline length mismatch\n"
f" Title: '{stripped_title}'\n"
f" Expected: {expected}\n"
f" Actual: {actual}\n"
)

if fix:
new_lines.append(line)
new_lines.append(f"{indent}{ch * expected}\n")
i += 2
continue

# --------------------------
# CASE 2: overline + title + underline
# --------------------------
if i + 2 < len(lines):
over, title, under = lines[i], lines[i + 1], lines[i + 2]

if (not is_docstring(over) and not is_docstring(title)
and not is_docstring(under)):

m1 = UNDERLINE_RE.match(over)
m2 = UNDERLINE_RE.match(under)

if m1 and m2:
indent1, ch1 = m1.group(1), m1.group(2)
indent2, ch2 = m2.group(1), m2.group(2)
stripped = title.strip()

if stripped:
expected = len(stripped)

over_len = len(over.strip())
under_len = len(under.strip())

fix_needed = False

if over_len != expected:
errors += 1
fix_needed = True
print(
f"{path}:{i+1}: ERROR — OVERLINE mismatch\n"
f" Title: '{stripped}'\n"
f" Expected: {expected}\n"
f" Actual: {over_len}\n"
)

if under_len != expected:
errors += 1
fix_needed = True
print(
f"{path}:{i+3}: ERROR — UNDERLINE mismatch\n"
f" Title: '{stripped}'\n"
f" Expected: {expected}\n"
f" Actual: {under_len}\n"
)

if fix and fix_needed:
new_lines.append(f"{indent1}{ch1 * expected}\n")
new_lines.append(title)
new_lines.append(f"{indent2}{ch2 * expected}\n")
i += 3
continue

# Normal line
new_lines.append(line)
i += 1

# Write fixes
if fix and errors > 0:
with open(path, "w", encoding="utf-8") as f:
f.writelines(new_lines)
print(f"✔ Fixed: {path}")

return errors


def main():
parser = argparse.ArgumentParser(description="Sphinx heading underline linter")
parser.add_argument("files", nargs="*", help="Files or patterns")
parser.add_argument("--fix", action="store_true", help="Fix errors automatically")
args = parser.parse_args()

files = scan_repo(args.files)
print(f"Checking {len(files)} files...\n")

total = 0
for f in files:
if not os.path.isdir(f):
total += process_file(f, fix=args.fix)

print("\n--------------------------------------")
if total == 0:
print("✔ No heading underline errors found!")
else:
print(f"✖ Total Errors Found: {total}")
print("Run: python heading_linter.py --fix to fix them.")

sys.exit(1 if total else 0)


if __name__ == "__main__":
main()

2 changes: 1 addition & 1 deletion mslib/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.index
~~~~~~~~~~~~
~~~~~~~~~~~

shows some docs on the root url of the server

Expand Down
2 changes: 1 addition & 1 deletion mslib/mscolab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.mscolab
~~~~~~~~~~~~~~
~~~~~~~~~~~~~

init module of mscolab

Expand Down
2 changes: 1 addition & 1 deletion mslib/mscolab/chat_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.mscolab.chat_manager
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~

Code to handle socket connections in mscolab

Expand Down
2 changes: 1 addition & 1 deletion mslib/mscolab/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.mscolab.conf.py.example
~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

config for mscolab.

Expand Down
2 changes: 1 addition & 1 deletion mslib/mscolab/seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.mscolab.seed
~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~

Seeder utility for database

Expand Down
2 changes: 1 addition & 1 deletion mslib/mscolab/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.mscolab._tests.utils
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~

Utility functions for mscolab

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/airdata_dockwidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.msui.airdata_dockwidget
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Control to load airports and airspaces into the top view.

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.msui.editor
~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~

config editor for msui_settings.json.

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/linearview.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.msui.linearview
~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~

Linear view module of the msui

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/mscolab.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.msui.mscolab
~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~

Window to display authentication and operation details for mscolab

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/mscolab_admin_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.msui.mscolab_admin_window
~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Mscolab operation window, to display chat, file change

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/mscolab_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.msui.mscolab_operation
~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Mscolab operation window, to display chat, file change

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/mscolab_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""

mslib.msui.mscolab_exceptions
~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Exceptions

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/mscolab_version_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

mslib.msui.mscolab_change_history
~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Mscolab change history window to display the change history of the flight path so that users
can revert back to a previous version
Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/mss.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""
mslib.msui.mss
~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~

Mission Support System Python/Qt Rename Message

Expand Down
2 changes: 1 addition & 1 deletion mslib/msui/multilayers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
mslib.msui.multilayers
~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~

This module contains classes for object oriented managing of WMS layers.
Improves upon the old method of loading each layer on UI changes,
Expand Down
Loading
Loading