-
Notifications
You must be signed in to change notification settings - Fork 0
/
EePrependMod.py
122 lines (89 loc) · 3.86 KB
/
EePrependMod.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import os
import sublime_plugin
class EePrependModCommand(sublime_plugin.TextCommand):
def run(self, edit):
if not self.is_valid_file():
return
if self.is_prepended_module_file_opened():
original_filepath = self.view.file_name().replace('ee', '')
return self.view.window().open_file(original_filepath)
prepended_module_path = self.build_prepended_module_path()
klass_name = self.build_klass_name(prepended_module_path)
if not self.is_prepend_mod_line_exist():
self.add_prepend_mod_line(edit, klass_name)
if not os.path.exists(prepended_module_path):
create_file(
prepended_module_path,
self.build_prepended_module_skeleton(klass_name)
)
self.view.window().open_file(prepended_module_path)
def build_prepended_module_path(self):
original_path = self.view.file_name()
paths = original_path.split('/')
if 'app' in paths:
main_folder_name = 'app'
elif 'lib' in paths:
main_folder_name = 'lib'
main_folder_index = paths.index(main_folder_name)
root_path = '/'.join(
paths[:main_folder_index] + [f'ee/{main_folder_name}/']
)
if main_folder_name == 'app':
if 'concerns' in paths:
return root_path + '/'.join(
paths[main_folder_index + 1:-1] + ['ee', paths[-1]]
)
else:
return root_path + '/'.join(
[paths[main_folder_index + 1], 'ee'] +
paths[main_folder_index + 2:]
)
return root_path + '/'.join(
['ee'] + paths[main_folder_index + 1:]
)
def build_klass_name(self, prepended_module_path):
# Finds <klass_path> start index from string (ee/.../ee/<klass_path>)
start_index = prepended_module_path.rindex('ee') + 2
# Filepath has extension `.rb`
end_index = prepended_module_path.index('.')
klass_path = prepended_module_path[start_index:end_index]
# Camelize & glue together with `::`
return klass_path.title().replace('_', '').replace('/', '::')[2:]
# Actions
def add_prepend_mod_line(self, edit, klass_name):
self.view.insert(edit, self.view.size(), f"\n{klass_name}.prepend_mod")
self.view.run_command('save')
# Helper methods
def is_valid_file(self):
file_name = self.view.file_name()
if not '.rb' in file_name:
return False
if 'ee' in file_name and not self.is_prepended_module_file_opened():
return False
if 'app/' not in file_name and 'lib/' not in file_name:
return False
return True
def is_prepended_module_file_opened(self):
return self.view.file_name().count('ee') == 2
def is_prepend_mod_line_exist(self):
last_line_number = self.view.rowcol(self.view.size())[0]
prelast_line_point = self.view.text_point(last_line_number - 1, 0)
prelast_line_region = self.view.line(prelast_line_point)
prelast_line_content = self.view.substr(prelast_line_region)
return 'prepend_mod' in prelast_line_content
def build_prepended_module_skeleton(self, klass_name):
skeleton = '# frozen_string_literal: true\n\n'
namespaces = ['EE'] + klass_name.split('::')
indent = 0
for namespace in namespaces:
skeleton += f"{indent * ' '}module {namespace}\n"
indent += 2
skeleton += f"{indent * ' '}extend ::Gitlab::Utils::Override\n"
while indent != 0:
indent -= 2
skeleton += f"{indent * ' '}end\n"
return skeleton
def create_file(filename, data):
os.makedirs(os.path.dirname(filename), exist_ok=True)
with open(filename, 'w') as file:
file.write(data)