forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 1
/
find_related_envoy_files.py
executable file
·91 lines (81 loc) · 3.58 KB
/
find_related_envoy_files.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python
#
# Emits related filenames given an envoy source/include/test filename.
# This can assist a text-editor with a hot-key to rotate between
# files. E.g. for Emacs this is enabled by loading
# envoy-emacs-hooks.el.
#
# Takes a filename as its only arg, and emits a list of files that are
# related to it, in a deterministic order so that by visiting the
# first file in the list, you cycle through impl, header, test, and
# interface -- whichever of those happen to exist. One file is emitted
# per line.
import os
import os.path
import sys
# Name of top level git directory.
ENVOY_ROOT = "/envoy/"
SOURCE_ROOT = "source"
TEST_ROOT = "test"
INTERFACE_REAL_ROOT = "include/envoy"
# Synthetic name for /include/envoy/, which helps us disambiguate
# the 'envoy' underneath include from the top level of the git repo.
INTERFACE_SYNTHETIC_ROOT = "include-envoy"
# We want to search the file from the leaf up for 'envoy', which is
# the name of the top level directory in the git repo. However, it's
# also the name of a subdirectory of 'include' -- the only
# subdirectory of 'include' currently, so it's easier just to treat
# that as a single element.
fname = sys.argv[1].replace("/" + INTERFACE_REAL_ROOT + "/", "/" + INTERFACE_SYNTHETIC_ROOT + "/")
# Parse the absolute location of this repo, its relative path, and
# file extension, exiting with no output along the way any time there
# is trouble.
envoy_index = fname.rfind(ENVOY_ROOT)
if envoy_index == -1:
sys.exit(0)
envoy_index += len(ENVOY_ROOT)
absolute_location = fname[0:envoy_index] # "/path/to/gitroot/envoy/"
path = fname[envoy_index:]
path_elements = path.split("/")
if len(path_elements) < 3:
sys.exit(0)
leaf = path_elements[len(path_elements) - 1]
dot = leaf.rfind(".")
if dot == -1 or dot == len(leaf) - 1:
sys.exit(0)
ext = leaf[dot:]
# Transforms the input filename based on some transformation rules. Nothing
# is emitted if the input path or extension does not match the expected pattern,
# or if the file doesn't exist.
def emit(source_path, dest_path, source_ending, dest_ending):
if fname.endswith(source_ending) and path.startswith(source_path + "/"):
path_len = len(path) - len(source_path) - len(source_ending)
new_path = (absolute_location + dest_path + path[len(source_path):-len(source_ending)] +
dest_ending)
if os.path.isfile(new_path):
print(new_path)
# Depending on which type of file is passed into the script: test, cc,
# h, or interface, emit any related ones in cyclic order.
root = path_elements[0]
if root == TEST_ROOT:
emit("test/common", INTERFACE_REAL_ROOT, "_impl_test.cc", ".h")
emit(TEST_ROOT, SOURCE_ROOT, "_test.cc", ".cc")
emit(TEST_ROOT, SOURCE_ROOT, "_test.cc", ".h")
emit(TEST_ROOT, TEST_ROOT, ".cc", ".h")
emit(TEST_ROOT, TEST_ROOT, ".cc", "_test.cc")
emit(TEST_ROOT, TEST_ROOT, ".h", "_test.cc")
emit(TEST_ROOT, TEST_ROOT, ".h", ".cc")
emit(TEST_ROOT, TEST_ROOT, "_test.cc", ".cc")
emit(TEST_ROOT, TEST_ROOT, "_test.cc", ".h")
elif root == SOURCE_ROOT and ext == ".cc":
emit(SOURCE_ROOT, SOURCE_ROOT, ".cc", ".h")
emit(SOURCE_ROOT, TEST_ROOT, ".cc", "_test.cc")
emit("source/common", INTERFACE_REAL_ROOT, "_impl.cc", ".h")
elif root == SOURCE_ROOT and ext == ".h":
emit(SOURCE_ROOT, TEST_ROOT, ".h", "_test.cc")
emit("source/common", INTERFACE_REAL_ROOT, "_impl.h", ".h")
emit(SOURCE_ROOT, SOURCE_ROOT, ".h", ".cc")
elif root == INTERFACE_SYNTHETIC_ROOT:
emit(INTERFACE_SYNTHETIC_ROOT, "source/common", ".h", "_impl.cc")
emit(INTERFACE_SYNTHETIC_ROOT, "source/common", ".h", "_impl.h")
emit(INTERFACE_SYNTHETIC_ROOT, "test/common", ".h", "_impl_test.cc")