nginx-lens 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
commands/graph.py CHANGED
@@ -3,6 +3,7 @@ from rich.console import Console
3
3
  from parser.nginx_parser import parse_nginx_config
4
4
  from exporter.graph import tree_to_dot, tree_to_mermaid
5
5
  from rich.text import Text
6
+ import os
6
7
 
7
8
  app = typer.Typer()
8
9
  console = Console()
@@ -65,6 +66,7 @@ def graph(
65
66
  if not routes:
66
67
  console.print("[yellow]Не найдено ни одного маршрута[/yellow]")
67
68
  return
69
+ main_file = os.path.abspath(config_path)
68
70
  # Красивый вывод
69
71
  seen = set()
70
72
  for route in routes:
@@ -78,25 +80,44 @@ def graph(
78
80
  # Получаем label для server
79
81
  server_val = route[0][1]
80
82
  server_block = None
81
- # Найти сам блок server по arg
82
83
  for d in tree.directives:
83
84
  if d.get('block') == 'server' and (d.get('arg','') == server_val or (not d.get('arg') and (server_val == '[no arg]' or not server_val))):
84
85
  server_block = d
85
86
  break
86
87
  label = get_server_label(server_block) if server_block else (server_val or 'default')
88
+ server_file = server_block.get('__file__') if server_block else None
87
89
  t.append(f"[", style="white")
88
90
  t.append(f"server: {label}", style="bold blue")
91
+ if server_file and os.path.abspath(server_file) != main_file:
92
+ t.append(f" ({server_file})", style="grey50")
89
93
  t.append("]", style="white")
90
94
  for i, (typ, val) in enumerate(route[1:]):
95
+ block = None
96
+ if typ == 'location' and server_block:
97
+ # Найти location-блок внутри server
98
+ for sub in server_block.get('directives', []):
99
+ if sub.get('block') == 'location' and sub.get('arg') == val:
100
+ block = sub
101
+ break
102
+ elif typ == 'upstream':
103
+ # Найти upstream-блок
104
+ for d in tree.directives:
105
+ if d.get('upstream') == val:
106
+ block = d
107
+ break
91
108
  if typ == 'location':
92
109
  t.append(f" -> [", style="white")
93
110
  t.append(f"location: {val}", style="yellow")
111
+ if block and block.get('__file__') and os.path.abspath(block['__file__']) != main_file:
112
+ t.append(f" ({block['__file__']})", style="grey50")
94
113
  t.append("]", style="white")
95
114
  elif typ == 'proxy_pass':
96
115
  t.append(f" -> proxy_pass: {val}", style="green")
97
116
  elif typ == 'upstream':
98
117
  t.append(f" -> [", style="white")
99
118
  t.append(f"upstream: {val}", style="magenta")
119
+ if block and block.get('__file__') and os.path.abspath(block['__file__']) != main_file:
120
+ t.append(f" ({block['__file__']})", style="grey50")
100
121
  t.append("]", style="white")
101
122
  elif typ == 'upstream_server':
102
123
  t.append(f" -> [", style="white")
commands/route.py CHANGED
@@ -46,9 +46,16 @@ def route(
46
46
  location = res['location']
47
47
  proxy_pass = res['proxy_pass']
48
48
  text = f"[bold]Config:[/bold] {conf}\n"
49
- text += f"[bold]Server:[/bold] {server.get('arg','') or '[no arg]'}\n"
49
+ if server:
50
+ text += f"[bold]Server:[/bold] {server.get('arg','') or '[no arg]'}"
51
+ if server.get('__file__'):
52
+ text += f" ([dim]{server.get('__file__')}[/dim])"
53
+ text += "\n"
50
54
  if location:
51
- text += f"[bold]Location:[/bold] {location.get('arg','')}\n"
55
+ text += f"[bold]Location:[/bold] {location.get('arg','')}"
56
+ if location.get('__file__'):
57
+ text += f" ([dim]{location.get('__file__')}[/dim])"
58
+ text += "\n"
52
59
  if proxy_pass:
53
60
  text += f"[bold]proxy_pass:[/bold] {proxy_pass}\n"
54
61
  console.print(Panel(text, title="Route", style="green"))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nginx-lens
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: CLI-инструмент для анализа, визуализации и диагностики конфигураций Nginx
5
5
  Author: Daniil Astrouski
6
6
  Author-email: shelovesuastra@gmail.com
@@ -14,24 +14,24 @@ commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  commands/analyze.py,sha256=W6begSgXNjgKJGoGeguR3WKgHPLkClWXxxpDcqvsJdc,8343
15
15
  commands/cli.py,sha256=9HwDJ-po5al0ceb4Wkyw5F2wzqxbJTo0CbHQ2AQ8obo,722
16
16
  commands/diff.py,sha256=C7gRIWh6DNWHzjiQBPVTn-rZ40m2KCY75Zd6Q4URJIE,2076
17
- commands/graph.py,sha256=8CnpKqVx9yUpDMcjDX-kN_SqUrS9dFqCUTrsalm-iMg,4967
17
+ commands/graph.py,sha256=9Zr-vdS9UdNncUi18v6eQZH_HyE6sEHteGHlk1Vb-sg,6117
18
18
  commands/health.py,sha256=SuD2gOeMf9ZaoUfeqx1Nip0xQDBkDus6z872Fhw2Z9w,1682
19
19
  commands/include.py,sha256=5PTYG5C00-AlWfIgpQXLq9E7C9yTFSv7HrZkM5ogDps,2224
20
20
  commands/logs.py,sha256=RkPUdIpbO9dOVL56lemreYRuAjMjcqqMxRCKOFv2gC4,3691
21
- commands/route.py,sha256=DfevWTwJfup1Ifmd99pYeuRteFNaldkAvISV8hC5a-c,2650
21
+ commands/route.py,sha256=L2aPicgBsp0YkQlCQQDoeeS9DxATUE-s7xXXHEHHzDw,2961
22
22
  commands/syntax.py,sha256=ZWFdaL8LVv9S694wlk2aV3HJKb0OSKjw3wNgTlNvFR8,3418
23
23
  commands/tree.py,sha256=mDfx0Aeg1EDQSYQoJ2nJIkSd_uP7ZR7pEqy7Cw3clQ0,2161
24
24
  exporter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  exporter/graph.py,sha256=WYUrqUgCaK6KihgxAcRHaQn4oMo6b7ybC8yb_36ZIsA,3995
26
26
  exporter/html.py,sha256=uquEM-WvBt2aV9GshgaI3UVhYd8sD0QQ-OmuNtvYUdU,798
27
27
  exporter/markdown.py,sha256=_0mXQIhurGEZ0dO-eq9DbsuKNrgEDIblgtL3DAgYNo8,724
28
- nginx_lens-0.1.7.dist-info/licenses/LICENSE,sha256=g8QXKdvZZC56rU8E12vIeYF6R4jeTWOsblOnYAda3K4,1073
28
+ nginx_lens-0.1.8.dist-info/licenses/LICENSE,sha256=g8QXKdvZZC56rU8E12vIeYF6R4jeTWOsblOnYAda3K4,1073
29
29
  parser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- parser/nginx_parser.py,sha256=JqZ3clNy4Nf-bmbsx_rJUL7EgRoB79b87eEu_isMeqg,3577
30
+ parser/nginx_parser.py,sha256=Sa9FtGAkvTqNzoehBvgLUWPJHLLIZYWH9ugSHW50X8s,3699
31
31
  upstream_checker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  upstream_checker/checker.py,sha256=9-6CMUTN7gXUACP8EwX722QogfujZyV-WWWUeM3a79k,455
33
- nginx_lens-0.1.7.dist-info/METADATA,sha256=eN2OiSpnQpDN8kRzVdynuAwJamWiMme1UlIr-cXvfC4,520
34
- nginx_lens-0.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- nginx_lens-0.1.7.dist-info/entry_points.txt,sha256=qEcecjSyLqcJjbIVlNlTpqAhPqDyaujUV5ZcBTAr3po,48
36
- nginx_lens-0.1.7.dist-info/top_level.txt,sha256=mxLJO4rZg0rbixVGhplF3fUNFs8vxDIL25ronZNvRy4,51
37
- nginx_lens-0.1.7.dist-info/RECORD,,
33
+ nginx_lens-0.1.8.dist-info/METADATA,sha256=Ybslp9g9RAwjkL9KIpru2CjSlB5wJxHEtEsiajI148g,520
34
+ nginx_lens-0.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
+ nginx_lens-0.1.8.dist-info/entry_points.txt,sha256=qEcecjSyLqcJjbIVlNlTpqAhPqDyaujUV5ZcBTAr3po,48
36
+ nginx_lens-0.1.8.dist-info/top_level.txt,sha256=mxLJO4rZg0rbixVGhplF3fUNFs8vxDIL25ronZNvRy4,51
37
+ nginx_lens-0.1.8.dist-info/RECORD,,
parser/nginx_parser.py CHANGED
@@ -14,7 +14,7 @@ class NginxConfigTree:
14
14
  def _strip_comments(line: str) -> str:
15
15
  return line.split('#', 1)[0].strip()
16
16
 
17
- def _parse_block(lines, base_dir) -> (List[Any], Dict[str, List[str]]):
17
+ def _parse_block(lines, base_dir, source_file=None) -> (List[Any], Dict[str, List[str]]):
18
18
  directives = []
19
19
  upstreams = {}
20
20
  i = 0
@@ -29,7 +29,7 @@ def _parse_block(lines, base_dir) -> (List[Any], Dict[str, List[str]]):
29
29
  for inc_path in glob.glob(pattern):
30
30
  with open(inc_path) as f:
31
31
  inc_lines = f.readlines()
32
- inc_directives, inc_upstreams = _parse_block(inc_lines, os.path.dirname(inc_path))
32
+ inc_directives, inc_upstreams = _parse_block(inc_lines, os.path.dirname(inc_path), inc_path)
33
33
  directives.extend(inc_directives)
34
34
  for k, v in inc_upstreams.items():
35
35
  upstreams.setdefault(k, []).extend(v)
@@ -56,7 +56,7 @@ def _parse_block(lines, base_dir) -> (List[Any], Dict[str, List[str]]):
56
56
  if m_srv:
57
57
  servers.append(m_srv.group(1).strip())
58
58
  upstreams[name] = servers
59
- directives.append({'upstream': name, 'servers': servers})
59
+ directives.append({'upstream': name, 'servers': servers, '__file__': source_file})
60
60
  continue
61
61
  # Блоки (например, server, http, location)
62
62
  m = re.match(r'(\S+)\s*(\S+)?\s*{', line)
@@ -75,15 +75,15 @@ def _parse_block(lines, base_dir) -> (List[Any], Dict[str, List[str]]):
75
75
  if depth > 0:
76
76
  block_lines.append(l)
77
77
  i += 1
78
- sub_directives, sub_upstreams = _parse_block(block_lines, base_dir)
79
- directives.append({'block': block_name, 'arg': block_arg, 'directives': sub_directives})
78
+ sub_directives, sub_upstreams = _parse_block(block_lines, base_dir, source_file)
79
+ directives.append({'block': block_name, 'arg': block_arg, 'directives': sub_directives, '__file__': source_file})
80
80
  for k, v in sub_upstreams.items():
81
81
  upstreams.setdefault(k, []).extend(v)
82
82
  continue
83
83
  # Обычная директива
84
84
  m = re.match(r'(\S+)\s+([^;]+);', line)
85
85
  if m:
86
- directives.append({'directive': m.group(1), 'args': m.group(2)})
86
+ directives.append({'directive': m.group(1), 'args': m.group(2), '__file__': source_file})
87
87
  i += 1
88
88
  return directives, upstreams
89
89
 
@@ -91,5 +91,5 @@ def parse_nginx_config(path: str) -> NginxConfigTree:
91
91
  base_dir = os.path.dirname(os.path.abspath(path))
92
92
  with open(path) as f:
93
93
  lines = f.readlines()
94
- directives, upstreams = _parse_block(lines, base_dir)
94
+ directives, upstreams = _parse_block(lines, base_dir, path)
95
95
  return NginxConfigTree(directives, upstreams)