2020args = parser .parse_args ()
2121
2222TYPES = {
23- "DefineCustomBoolVariable" : "BOOLEAN" ,
24- "DefineCustomIntVariable" : "INTEGER" ,
25- "DefineCustomEnumVariable" : "ENUM" ,
23+ "DefineCustomBoolVariable" : "BOOLEAN" ,
24+ "DefineCustomIntVariable" : "INTEGER" ,
25+ "DefineCustomEnumVariable" : "ENUM" ,
2626 "DefineCustomStringVariable" : "STRING" ,
27+ "DefineCustomRealVariable" : "REAL" ,
28+ }
29+
30+ SCOPES = {
31+ "PG16_GE" : "Postgres 16 or greater" ,
32+ "TS_DEBUG" : "Debug mode" ,
33+ "USE_TELEMETRY" : "Telemetry enabled" ,
2734}
2835
2936# List of GUCs to exclude from the docs
@@ -62,8 +69,22 @@ def unwrap(gucs: list, guc_type: str) -> dict:
6269 map = {}
6370
6471 for guc in gucs :
65- # sanitize data
66- it = [re .sub (r"[\n\t]*" , "" , v ).strip () for v in guc .split ("," )]
72+ # unwrap element
73+ # first split on new line, then join on ,
74+ lines = [re .sub (r"[\n\t]*" , "" , v ).strip () for v in guc .split ("\n " )]
75+ it = []
76+ lst = []
77+ for line in lines :
78+ # ends with "," --> take all preceding values from the list
79+ # concatenate them with this element minus the trailing ","
80+ # and reset the list again
81+ if line [- 1 :] == "," :
82+ val = "" .join (lst ) + line [:- 1 ]
83+ lst = []
84+ it .append (val )
85+ else :
86+ # add the line to the list to concatenate later
87+ lst .append (line )
6788
6889 # sanitize elements
6990 name = re .sub (r"[\"\(\)]*" , "" , it [0 ])
@@ -73,20 +94,19 @@ def unwrap(gucs: list, guc_type: str) -> dict:
7394 # Exclude GUCs (if specified)
7495 if name not in EXCLUDE :
7596 map [name ] = {
76- "name" : name ,
97+ "name" : name ,
7798 "short_desc" : short_desc ,
78- "long_desc" : long_desc ,
79- "value" : get_value (guc_type , it ),
80- "type" : guc_type ,
81- "scopes" : [], # assigned later during scope discovery
99+ "long_desc" : long_desc ,
100+ "value" : get_value (guc_type , it ),
101+ "meta" : get_meta_data (guc_type , it ),
102+ "type" : guc_type ,
103+ "scopes" : [], # assigned later during scope discovery
82104 }
83-
84- logging .info ("registered %d GUCs of type: %s" % (len (map ), guc_type ))
85105 return map
86106
87107def sanitize_description (text ) -> str :
88108 # Remove all quotes and normalize whitespace to single line
89- return ' ' .join (text .replace ('"' , '' ).split ()).strip ()
109+ return strip_comment_pattern ( ' ' .join (text .replace ('"' , '' ).split ()).strip () )
90110
91111def strip_comment_pattern (text ) -> str :
92112 pattern = r'/\*\s*[a-zA-Z0-9_]*=\s*\*/'
@@ -101,12 +121,21 @@ def get_value(type: str, parts: list) -> str:
101121 """
102122 Get the value of the GUC based on the type
103123 """
124+ # ENUM needs different handling, finding the struct and the strings
125+ # identifying the options
126+
127+ # Every other type
128+ return strip_comment_pattern (parts [4 ]).strip ()
129+
130+ def get_meta_data (type : str , parts : list ) -> str :
131+ """
132+ Build any meta data if present based on the type
133+ """
104134 if type == "BOOLEAN" :
105- if parts [5 ].upper ()[0 :4 ] == "PGC_" :
106- return strip_comment_pattern (parts [4 ]).strip ()
107- else :
108- return strip_comment_pattern (parts [5 ]).strip ()
109- return strip_comment_pattern (parts [5 ]).strip ()
135+ return ""
136+ if type in ["INTEGER" , "REAL" ]:
137+ return "min: `%s`, max: `%s`" % (strip_comment_pattern (parts [5 ]).strip (), strip_comment_pattern (parts [6 ]).strip ())
138+ return ""
110139
111140"""
112141Parse GUCs and prepare them for rendering
@@ -118,26 +147,43 @@ def prepare(content: str) -> dict:
118147
119148 # Find all GUCs based on patterns and prepare them in a dict
120149 for pattern , val in TYPES .items ():
150+ # Run twice to find variants, e.g., there is a nicer way with one regex to do this
151+ # but this is not time sensitive nor consuming, so we're good
152+ # - DefineCustomStringVariable(MAKE_EXTOPTION(
153+ # - DefineCustomStringVariable(/* name= */ MAKE_EXTOPTION(
121154 map .update (unwrap (re .findall (r"%s\(MAKE_EXTOPTION(.*?)\);" % pattern , content , re .DOTALL ), val ))
155+ map .update (unwrap (re .findall (r"%s\(\/\* name= \*\/ MAKE_EXTOPTION(.*?)\);" % pattern , content , re .DOTALL ), val ))
122156
123157 # TODO: find scopes
124158 # https://github.com/timescale/timescaledb/blob/2.19.x/src/guc.c#L797
159+ # SCOPES
125160
161+ # print summary
162+ summary = {}
163+ for v in map .values ():
164+ if v ["type" ] not in summary .keys ():
165+ summary [v ["type" ]] = 0
166+ summary [v ["type" ]] += 1
167+ for k , v in summary .items ():
168+ logging .info ("registered %d GUCs of type: %s" % (v , k ))
126169
127170 # Return dict with alphabetically sorted keys
128171 return {i : map [i ] for i in sorted (map .keys ())}
129172
130173"""
131174Render the GUCs to file
132175"""
133- def render (gucs : dict , filename : str ):
176+ def render (gucs : dict , filename : str , version : str ):
134177 with open (filename , "w" ) as f :
135- f .write ("| Name | Type | Default | Long Description |\n " )
136- f .write ("| -- | -- | -- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n " )
178+ f .write ("| Name | Type | Default | Description |\n " )
179+ f .write ("| -- | -- | -- | -- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n " )
137180 for guc in gucs .values ():
138- f .write ("| `%s` | `%s` | `%s` | %s |\n " % (
139- guc ["name" ], guc ["type" ], guc ["value" ], guc ["long_desc" ]
140- ))
181+ desc = guc ["long_desc" ]
182+ if guc ["meta" ] != "" :
183+ desc += "<br />" + guc ["meta" ]
184+ f .write ("| `%s` | `%s` | `%s` | %s |\n " % (guc ["name" ], guc ["type" ], guc ["value" ], desc ))
185+ f .write ("\n " )
186+ f .write ("Version: [%s](https://github.com/timescale/timescaledb/releases/tag/%s)" % (version , version ))
141187 logging .info ("rendering completed to %s" % filename )
142188
143189"""
@@ -147,6 +193,4 @@ def render(gucs: dict, filename: str):
147193 content = get_content ("https://raw.githubusercontent.com/timescale/timescaledb/refs/tags/%s/src/guc.c" % args .tag )
148194 logging .info ("fetched guc.c file for version: %s" % args .tag )
149195 gucs = prepare (content )
150- render (gucs , args .destination )
151-
152- # print(gucs)
196+ render (gucs , args .destination , args .tag )
0 commit comments