##// END OF EJS Templates
ini: extract .ini handling from scripts/generate-ini.py to kallithea/lib/inifile.py...
Mads Kiilerich -
r6809:e3cce237 default
parent child Browse files
Show More
@@ -0,0 +1,85 b''
1 # -*- coding: utf-8 -*-
2 # This program is free software: you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation, either version 3 of the License, or
5 # (at your option) any later version.
6 #
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
11 #
12 # You should have received a copy of the GNU General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
15 """
16 kallithea.lib.inifile
17 ~~~~~~~~~~~~~~~~~~~~~
18
19 Handling of .ini files, mainly creating them from Mako templates and adding
20 other custom values.
21 """
22
23 import logging
24 import re
25
26
27 log = logging.getLogger(__name__)
28
29
30 def expand(template, desc, selected_mako_conditionals, mako_variable_values, settings):
31 """Expand mako template and tweak it.
32 Not entirely stable for random templates as input, but good enough for our
33 single template.
34 """
35 # select the right mako conditionals for the other less sophisticated formats
36 def sub_conditionals(m):
37 """given a %if...%endif match, replace with just the selected
38 conditional sections enabled and the rest as comments
39 """
40 conditional_lines = m.group(1)
41 def sub_conditional(m):
42 """given a conditional and the corresponding lines, return them raw
43 or commented out, based on whether conditional is selected
44 """
45 criteria, lines = m.groups()
46 if criteria not in selected_mako_conditionals:
47 lines = '\n'.join((l if not l or l.startswith('#') else '#' + l) for l in lines.split('\n'))
48 return lines
49 conditional_lines = re.sub(r'^%(?:el)?if (.*):\n((?:^[^%\n].*\n|\n)*)',
50 sub_conditional, conditional_lines, flags=re.MULTILINE)
51 return conditional_lines
52 mako_no_conditionals = re.sub(r'^(%if .*\n(?:[^%\n].*\n|%elif .*\n|\n)*)%endif\n',
53 sub_conditionals, template, flags=re.MULTILINE)
54
55 # expand mako variables
56 def pyrepl(m):
57 return mako_variable_values.get(m.group(1), m.group(0))
58 mako_no_variables = re.sub(r'\${([^}]*)}', pyrepl, mako_no_conditionals)
59
60 # remove utf-8 coding header
61 ini_lines = re.sub(r'^## -\*- coding: utf-8 -\*-\n', '', mako_no_variables)
62
63 ini_lines = re.sub(
64 '# Kallithea - config file generated with kallithea-config *#\n',
65 ''.join('# %-77s#\n' % l.strip() for l in desc.strip().split('\n')),
66 ini_lines)
67 def process_section(m):
68 """process a ini section, replacing values as necessary"""
69 sectionname, lines = m.groups()
70 if sectionname in settings:
71 section_settings = settings[sectionname]
72 def process_line(m):
73 """process a section line and update value if necessary"""
74 key, value = m.groups()
75 line = m.group(0)
76 if key in section_settings:
77 line = '%s = %s' % (key, section_settings[key])
78 if '$' not in value:
79 line = '#%s = %s\n%s' % (key, value, line)
80 return line.rstrip()
81 lines = re.sub(r'^([^#\n].*) = ?(.*)', process_line, lines, flags=re.MULTILINE)
82 return sectionname + '\n' + lines
83 ini_lines = re.sub(r'^(\[.*\])\n((?:(?:[^[\n].*)?\n)*)', process_section, ini_lines, flags=re.MULTILINE)
84
85 return ini_lines
@@ -1,152 +1,106 b''
1 #!/usr/bin/env python2
1 #!/usr/bin/env python2
2 """
2 """
3 Based on kallithea/lib/paster_commands/template.ini.mako, generate
3 Based on kallithea/lib/paster_commands/template.ini.mako, generate
4 development.ini
4 development.ini
5 kallithea/tests/test.ini
5 kallithea/tests/test.ini
6 """
6 """
7
7
8 import re
8 import re
9
9
10 from kallithea.lib import inifile
11
10 makofile = 'kallithea/lib/paster_commands/template.ini.mako'
12 makofile = 'kallithea/lib/paster_commands/template.ini.mako'
11
13
12 # the mako conditionals used in all other ini files and templates
14 # the mako conditionals used in all other ini files and templates
13 selected_mako_conditionals = set([
15 selected_mako_conditionals = set([
14 "database_engine == 'sqlite'",
16 "database_engine == 'sqlite'",
15 "http_server == 'waitress'",
17 "http_server == 'waitress'",
16 "error_aggregation_service == 'appenlight'",
18 "error_aggregation_service == 'appenlight'",
17 "error_aggregation_service == 'sentry'",
19 "error_aggregation_service == 'sentry'",
18 ])
20 ])
19
21
20 # the mako variables used in all other ini files and templates
22 # the mako variables used in all other ini files and templates
21 mako_variable_values = {
23 mako_variable_values = {
22 'host': '127.0.0.1',
24 'host': '127.0.0.1',
23 'port': '5000',
25 'port': '5000',
24 'uuid()': '${app_instance_uuid}',
26 'uuid()': '${app_instance_uuid}',
25 }
27 }
26
28
27 # files to be generated from the mako template
29 # files to be generated from the mako template
28 ini_files = [
30 ini_files = [
29 ('kallithea/tests/test.ini',
31 ('kallithea/tests/test.ini',
30 '''
32 '''
31 Kallithea - config for tests:
33 Kallithea - config for tests:
32 sqlalchemy and kallithea_test.sqlite
34 sqlalchemy and kallithea_test.sqlite
33 custom logging
35 custom logging
34 ''',
36 ''',
35 {
37 {
36 '[server:main]': {
38 '[server:main]': {
37 'port': '4999',
39 'port': '4999',
38 },
40 },
39 '[app:main]': {
41 '[app:main]': {
40 'app_instance_uuid': 'test',
42 'app_instance_uuid': 'test',
41 'show_revision_number': 'true',
43 'show_revision_number': 'true',
42 'beaker.cache.sql_cache_short.expire': '1',
44 'beaker.cache.sql_cache_short.expire': '1',
43 'beaker.session.secret': '{74e0cd75-b339-478b-b129-07dd221def1f}',
45 'beaker.session.secret': '{74e0cd75-b339-478b-b129-07dd221def1f}',
44 },
46 },
45 '[handler_console]': {
47 '[handler_console]': {
46 'formatter': 'color_formatter',
48 'formatter': 'color_formatter',
47 },
49 },
48 # The 'handler_console_sql' block is very similar to the one in
50 # The 'handler_console_sql' block is very similar to the one in
49 # development.ini, but without the explicit 'level=DEBUG' setting:
51 # development.ini, but without the explicit 'level=DEBUG' setting:
50 # it causes duplicate sqlalchemy debug logs, one through
52 # it causes duplicate sqlalchemy debug logs, one through
51 # handler_console_sql and another through another path.
53 # handler_console_sql and another through another path.
52 '[handler_console_sql]': {
54 '[handler_console_sql]': {
53 'formatter': 'color_formatter_sql',
55 'formatter': 'color_formatter_sql',
54 },
56 },
55 },
57 },
56 ),
58 ),
57 ('development.ini',
59 ('development.ini',
58 '''
60 '''
59 Kallithea - Development config:
61 Kallithea - Development config:
60 listening on *:5000
62 listening on *:5000
61 sqlite and kallithea.db
63 sqlite and kallithea.db
62 initial_repo_scan = true
64 initial_repo_scan = true
63 debug = true
65 debug = true
64 verbose and colorful logging
66 verbose and colorful logging
65 ''',
67 ''',
66 {
68 {
67 '[server:main]': {
69 '[server:main]': {
68 'host': '0.0.0.0',
70 'host': '0.0.0.0',
69 },
71 },
70 '[app:main]': {
72 '[app:main]': {
71 'initial_repo_scan': 'true',
73 'initial_repo_scan': 'true',
72 'debug': 'true',
74 'debug': 'true',
73 'app_instance_uuid': 'development-not-secret',
75 'app_instance_uuid': 'development-not-secret',
74 'beaker.session.secret': 'development-not-secret',
76 'beaker.session.secret': 'development-not-secret',
75 },
77 },
76 '[handler_console]': {
78 '[handler_console]': {
77 'formatter': 'color_formatter',
79 'formatter': 'color_formatter',
78 },
80 },
79 '[handler_console_sql]': {
81 '[handler_console_sql]': {
80 'formatter': 'color_formatter_sql',
82 'formatter': 'color_formatter_sql',
81 },
83 },
82 },
84 },
83 ),
85 ),
84 ]
86 ]
85
87
86
88
87 def main():
89 def main():
88 # make sure all mako lines starting with '#' (the '##' comments) are marked up as <text>
90 # make sure all mako lines starting with '#' (the '##' comments) are marked up as <text>
89 print 'reading:', makofile
91 print 'reading:', makofile
90 mako_org = open(makofile).read()
92 mako_org = open(makofile).read()
91 mako_no_text_markup = re.sub(r'</?%text>', '', mako_org)
93 mako_no_text_markup = re.sub(r'</?%text>', '', mako_org)
92 mako_marked_up = re.sub(r'\n(##.*)', r'\n<%text>\1</%text>', mako_no_text_markup, flags=re.MULTILINE)
94 mako_marked_up = re.sub(r'\n(##.*)', r'\n<%text>\1</%text>', mako_no_text_markup, flags=re.MULTILINE)
93 if mako_marked_up != mako_org:
95 if mako_marked_up != mako_org:
94 print 'writing:', makofile
96 print 'writing:', makofile
95 open(makofile, 'w').write(mako_marked_up)
97 open(makofile, 'w').write(mako_marked_up)
96
98
97 # select the right mako conditionals for the other less sophisticated formats
98 def sub_conditionals(m):
99 """given a %if...%endif match, replace with just the selected
100 conditional sections enabled and the rest as comments
101 """
102 conditional_lines = m.group(1)
103 def sub_conditional(m):
104 """given a conditional and the corresponding lines, return them raw
105 or commented out, based on whether conditional is selected
106 """
107 criteria, lines = m.groups()
108 if criteria not in selected_mako_conditionals:
109 lines = '\n'.join((l if not l or l.startswith('#') else '#' + l) for l in lines.split('\n'))
110 return lines
111 conditional_lines = re.sub(r'^%(?:el)?if (.*):\n((?:^[^%\n].*\n|\n)*)',
112 sub_conditional, conditional_lines, flags=re.MULTILINE)
113 return conditional_lines
114 mako_no_conditionals = re.sub(r'^(%if .*\n(?:[^%\n].*\n|%elif .*\n|\n)*)%endif\n',
115 sub_conditionals, mako_no_text_markup, flags=re.MULTILINE)
116
117 # expand mako variables
118 def pyrepl(m):
119 return mako_variable_values.get(m.group(1), m.group(0))
120 mako_no_variables = re.sub(r'\${([^}]*)}', pyrepl, mako_no_conditionals)
121
122 # remove utf-8 coding header
123 base_ini = re.sub(r'^## -\*- coding: utf-8 -\*-\n', '', mako_no_variables)
124
125 # create ini files
99 # create ini files
126 for fn, desc, settings in ini_files:
100 for fn, desc, settings in ini_files:
127 print 'updating:', fn
101 print 'updating:', fn
128 ini_lines = re.sub(
102 ini_lines = inifile.expand(mako_no_text_markup, desc, selected_mako_conditionals, mako_variable_values, settings)
129 '# Kallithea - config file generated with kallithea-config *#\n',
130 ''.join('# %-77s#\n' % l.strip() for l in desc.strip().split('\n')),
131 base_ini)
132 def process_section(m):
133 """process a ini section, replacing values as necessary"""
134 sectionname, lines = m.groups()
135 if sectionname in settings:
136 section_settings = settings[sectionname]
137 def process_line(m):
138 """process a section line and update value if necessary"""
139 setting, value = m.groups()
140 line = m.group(0)
141 if setting in section_settings:
142 line = '%s = %s' % (setting, section_settings[setting])
143 if '$' not in value:
144 line = '#%s = %s\n%s' % (setting, value, line)
145 return line.rstrip()
146 lines = re.sub(r'^([^#\n].*) = ?(.*)', process_line, lines, flags=re.MULTILINE)
147 return sectionname + '\n' + lines
148 ini_lines = re.sub(r'^(\[.*\])\n((?:(?:[^[\n].*)?\n)*)', process_section, ini_lines, flags=re.MULTILINE)
149 open(fn, 'w').write(ini_lines)
103 open(fn, 'w').write(ini_lines)
150
104
151 if __name__ == '__main__':
105 if __name__ == '__main__':
152 main()
106 main()
General Comments 0
You need to be logged in to leave comments. Login now