2020logger = logging .getLogger (__name__ )
2121
2222
23+ DEFAULT_FORMAT = "rst"
24+ DEFAULT_CHANGELOG = "CHANGELOG.${config:format}"
25+
26+
2327@attr .s
2428class _Options :
2529 """
@@ -42,13 +46,17 @@ class _Options:
4246 # What format for fragments? reStructuredText ("rst") or Markdown ("md").
4347 format = attr .ib (
4448 type = str ,
45- default = "rst" ,
46- validator = attr .validators .in_ (["rst" , "md" ]),
49+ default = None ,
50+ validator = attr .validators .optional ( attr . validators . in_ (["rst" , "md" ]) ),
4751 metadata = {
4852 "doc" : """\
4953 The format to use for fragments and for the output changelog
5054 file. Can be either "rst" or "md".
5155 """ ,
56+ "doc_default" : f"""\
57+ Derived from the changelog file name if provided,
58+ otherwise "{ DEFAULT_FORMAT } ".
59+ """ ,
5260 },
5361 )
5462
@@ -74,12 +82,13 @@ class _Options:
7482
7583 changelog = attr .ib (
7684 type = str ,
77- default = "CHANGELOG.${config:format}" ,
85+ default = None ,
7886 metadata = {
7987 "doc" : """\
8088 The changelog file managed and read by scriv. The old name
8189 for this setting is :ref:`output_file <deprecated_config>`.
8290 """ ,
91+ "doc_default" : f"``{ DEFAULT_CHANGELOG } ``" ,
8392 },
8493 )
8594
@@ -223,6 +232,15 @@ class _Options:
223232 },
224233 )
225234
235+ def post_create (self ):
236+ if self .format is None :
237+ if self .changelog is not None and "${" not in self .changelog :
238+ self .format = Path (self .changelog ).suffix [1 :]
239+ else :
240+ self .format = DEFAULT_FORMAT
241+ if self .changelog is None :
242+ self .changelog = DEFAULT_CHANGELOG
243+
226244
227245# Map of old config names to new config names.
228246DEPRECATED_NAMES = [
@@ -255,10 +273,12 @@ class Config:
255273
256274 """
257275
258- def __init__ (self , ** kwargs ):
276+ def __init__ (self , post_create_ = True , ** kwargs ):
259277 """All values in _Options can be set as keywords."""
260278 with validator_exceptions ():
261279 self ._options = _Options (** kwargs )
280+ if post_create_ :
281+ self ._options .post_create ()
262282
263283 def __getattr__ (self , name ):
264284 """Proxy to self._options, and resolve the value."""
@@ -292,7 +312,7 @@ def read(cls) -> Config:
292312 The section can be named ``[scriv]`` or ``[tool.scriv]``.
293313
294314 """
295- config = cls ()
315+ config = cls (post_create_ = False )
296316 config .read_one_config ("setup.cfg" )
297317 config .read_one_config ("tox.ini" )
298318 config .read_one_toml ("pyproject.toml" )
@@ -301,6 +321,7 @@ def read(cls) -> Config:
301321 )
302322 with validator_exceptions ():
303323 attr .validate (config ._options )
324+ config ._options .post_create ()
304325 return config
305326
306327 def get_set_option (self , scriv_data , config_name , opt_name ):
@@ -393,7 +414,8 @@ def resolve_value(self, value: str) -> str:
393414 "command:" read the output of a shell command.
394415
395416 """
396- value = value .replace ("${config:format}" , self ._options .format )
417+ if self ._options .format is not None :
418+ value = value .replace ("${config:format}" , self ._options .format )
397419 if value .startswith ("file:" ):
398420 file_name = value .partition (":" )[2 ].strip ()
399421 value = self .read_file_value (file_name )
0 commit comments