config file support is ready
- over.app.ConfigFile can read, create and amend config files - fix over.cmd.format_invocation - add join to over.text.paragraph
This commit is contained in:
parent
17eda81ad2
commit
5b983a3131
6 changed files with 81 additions and 19 deletions
68
over/app.py
68
over/app.py
|
@ -9,6 +9,7 @@ import sys
|
|||
import re
|
||||
import os
|
||||
import shlex
|
||||
import hashlib
|
||||
|
||||
try:
|
||||
import xdg.BaseDirectory as xdg_bd
|
||||
|
@ -112,6 +113,7 @@ class Option:
|
|||
self.abbr = abbr
|
||||
self.in_cfg_file = in_cfg_file
|
||||
self.show_in_help = show_in_help
|
||||
self.hash = hashlib.sha1(name.encode("utf-8")).hexdigest()
|
||||
|
||||
if is_boolean is None:
|
||||
self.is_boolean = callback in (bool, callback_module.boolean, callback_module.booleans)
|
||||
|
@ -231,6 +233,28 @@ def get_xdg_paths(appname):
|
|||
|
||||
# --------------------------------------------------
|
||||
|
||||
def serialize_callback(f):
|
||||
return "%s.%s" %(f.__module__, f.__name__)
|
||||
|
||||
# --------------------------------------------------
|
||||
|
||||
def format_description(description):
|
||||
colorless = text.render(description, colors=False)
|
||||
lines = text.paragraph(colorless, 55, 2, join=False)
|
||||
|
||||
# comment them out and assemble
|
||||
return "\n".join("#" + line[1:] for line in lines)
|
||||
|
||||
# --------------------------------------------------
|
||||
|
||||
def serialize_default(option):
|
||||
if option.default is Option_sources.none:
|
||||
return ""
|
||||
else:
|
||||
return cmd.format_invocation(str(x) for x in option.default)
|
||||
|
||||
# --------------------------------------------------
|
||||
|
||||
class ConfigFile:
|
||||
"""
|
||||
Config file object. Takes a {name: Option} dictionary and a file path, and:
|
||||
|
@ -244,6 +268,7 @@ class ConfigFile:
|
|||
self.dir = get_xdg_paths(app_name)["config"]
|
||||
self.path = os.path.join(self.dir, "main.cfg")
|
||||
self.print = text.Output(app_name + ".ConfigFile")
|
||||
self.seen_hashes = set()
|
||||
|
||||
self.read_config()
|
||||
self.sync_config(app_name, app_version)
|
||||
|
@ -259,20 +284,21 @@ class ConfigFile:
|
|||
for line in f:
|
||||
line = line.strip()
|
||||
|
||||
if line and line[0] != "#": # ignore comments and empty lines
|
||||
L, R = (t.strip() for t in line.split("="))
|
||||
|
||||
try:
|
||||
option = self.options[L]
|
||||
except KeyError:
|
||||
raise UnknownOption(L)
|
||||
|
||||
if option.count > 1:
|
||||
args = shlex.split(R)
|
||||
if line:
|
||||
if line[0] == "#":
|
||||
m = re.findall("# ---- ([0-9a-f]{40}) ----", line)
|
||||
if m:
|
||||
self.seen_hashes.add(m[0])
|
||||
else:
|
||||
args = [R]
|
||||
|
||||
option.set_value(args, Option_sources.config_file)
|
||||
L, R = (t.strip() for t in line.split("="))
|
||||
|
||||
try:
|
||||
option = self.options[L]
|
||||
except KeyError:
|
||||
raise UnknownOption(L)
|
||||
|
||||
args = shlex.split(R)
|
||||
option.set_value(args, Option_sources.config_file)
|
||||
|
||||
def sync_config(self, app_name, app_version):
|
||||
"""
|
||||
|
@ -292,7 +318,21 @@ class ConfigFile:
|
|||
|
||||
# add new or otherwise missing options
|
||||
with open(self.path, "a") as f:
|
||||
...
|
||||
for option in self.options.values():
|
||||
if option.hash not in self.seen_hashes:
|
||||
self.print("adding <W>--<G>%s<.> to config file" %(option.name))
|
||||
|
||||
f.write(docs.config_file_item %(
|
||||
option.hash,
|
||||
("--{0} or --no-{0}" if (option.is_boolean and option.count == 0) else "--{0}").format(option.name),
|
||||
serialize_callback(option.callback),
|
||||
option.count or "no",
|
||||
"" if option.count == 1 else "s",
|
||||
"the last instance counts" if option.overwrite else "can be specified multiple times",
|
||||
format_description(option.description),
|
||||
option.name,
|
||||
serialize_default(option)
|
||||
))
|
||||
|
||||
def __repr__(self):
|
||||
return "ConfigFile(%s)" %(self.path)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue