LINUX.ORG.RU

Какой выдумать или создать формат для конфигов?

 , , ,


1

3

Хочу для своего упражнения использовать yaml. Вроде голанг его умеет читать и писать. Что говорит на эту тему духовенство? Уместен ли такой формат или же лучше взять что-то другое?

json не хочу по той причине, что в него нельзя вставлять комментарии, xml слишком многословен.

==========================================

Решение: взят обычный json, который читает - пишет структуру. Для комментария в структуре предусмотрено специальное поле Comment. Это не так удобно, зато гомоиконно.

Если в конфиге задано поле, отсутствующее в структуре, например, если название поля написано с опечаткой, то будет ошибка чтения конфига. Это важно, поскольку толерантность многих программ к опечаткам в конфигах приводит к тому, что можно часами сидеть и искать ответ на вопрос «ну почему же это дерьмо не работает»?

Код такой:

package main

import (
	"strings"; "fmt"; "os"
	"encoding/json"
	"io/ioutil"
	// "github.com/flynn/json5"
)

type SecretConfigDataStruct struct {
	Comment       string
	RecieverEMail string
	SMTPServer    string
	SMTPUser      string
	SMTPPassword  string
	SenderEMail   string }

var SecretConfigData SecretConfigDataStruct

func (sds *SecretConfigDataStruct) SaveToFile(filename string) (err error) {
	var text []byte
	text, err = json.MarshalIndent(sds,""," ")
	if err != nil { return	}	
	err = ioutil.WriteFile(filename, text, 0600)
	return }

const ConfigFileName = "secret-data.config.json"

// for development
func saveSecretConfigDataExample() {
	sds := SecretConfigDataStruct{
		Comment:       "Example config file. Copy this one to the secret-data.config.json and edit",
		SenderEMail:   "den@example.net",
		RecieverEMail: "world@example.net",
		SMTPServer:    "smtp.example.net",
		SMTPUser:      "Кирилл",
		SMTPPassword:  "bla-bla-bla"}
	err := sds.SaveToFile(ConfigFileName + ".example")
	if err != nil {	panic(err)	}}

func loadSecretConfigData() (err error) {
	sds := &SecretConfigData
	fn := ConfigFileName
	if _, err = os.Stat(fn); os.IsNotExist(err) {
		fmt.Printf("No config file %s found. Create one by copying from %s.example\n",
			fn, fn)
		return	}
	var bytes []byte
	bytes, err = ioutil.ReadFile(fn)
	if err != nil {
		fmt.Printf("Unable to read config %s\n", fn)
		return	}
		dec := json.NewDecoder(strings.NewReader(string(bytes)))
		dec.DisallowUnknownFields() 
		err = dec.Decode(sds)
	if err != nil {
		fmt.Printf("Error reading config file %s: %#v\n", fn, err)
		return	}
	fmt.Printf("playWithSecretConfigData returned %#v\n", sds)
	return }

★★★★★

Последнее исправление: den73 (всего исправлений: 4)

последняя убунта в этом модном формате сетевые конфиги держит)

darkenshvein ★★★★★
()

отличный выбор. json-yml в обе стороны отлично работает

SevikL ★★★★★
()

Тебе, кажется, не столько программировать, сколько общаться охота.

anonymous
()
Ответ на: комментарий от RazrFalcon

Как решить TOML vs yaml? Вот нашёл старую тему:

В чем суть TOML?

Не сказать, чтобы обсуждение породило у меня большой энтузиазм в направлении TOML. Идея значимых отступов мне нравится, хотя многострочные строки в сочетании с отступами - это сомнительная идея. Придётся и на yaml подробнее посмотреть под критическим углом. Насчёт dhall - я сильно усомнюсь что Хаскель подходит для «нетехнических людей», которые там упомянуты.

den73 ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Спасибо, я уже понял, что yaml сложный, и в этом его недостаток. Хотя я ещё посмотрю на историю. Вроде они при переходе с 1.1 на 1.2 упростили, а теперь уже 2.0.

Нашёл вот такую затею: https://habr.com/ru/post/248147/ В общем, чую, что придётся мне сделать свой язык конфигов, поэтому добавлю-ка я сюда тег «Яр».

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Но вообще это плохой конец дня. Я завязну в этом языке для конфигов. Похоже, что нужно сделать волевое усилие и применить json :( Но только это должен быть спец-json, позволяющий комментарии. А так, по идее, можно ещё сделать языком конфига ограниченное подмножество самого голанга, и/или то, что печатается по %#v. Есть ли такое где-нибудь, кто в курсе?

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Да, с конфигами беда.

Аноним выше правильно советует json5.

RazrFalcon ★★★★★
()
Ответ на: комментарий от anonymous

json5 - классная штука, но у меня ругается на «неподдерживаемый протокол» на сайте. Нашёл на гитхабе. Похоже на приемлемое.

{
  // comments
  unquoted: 'and you can quote me on that',
  singleQuotes: 'I can use "double quotes" here',
  lineBreaks: "Look, Mom! \
No \\n's!",
  hexadecimal: 0xdecaf,
  leadingDecimalPoint: .8675309, andTrailing: 8675309.,
  positiveSign: +1,
  trailingComma: 'in objects', andIn: ['arrays',],
  "backwardsCompatible": "with JSON",
}
Т.е. у меня в хорошей степени проработанности гораздо более интересная штука (похожая на вышеупомянутый Tree), но сейчас задача не в том.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от Harald

Ну ты знаешь, после лиспа на ini-файлы - это, наверное, то же ощущение, что было у белоэмигрантов, успевших на последний пароход. Пока что всё не настолько плохо.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

это, наверное, то же ощущение, что было у белоэмигрантов, успевших на последний пароход.

разве у них плохие ощущения должны были быть, успели же

Harald ★★★★★
()
Ответ на: комментарий от Harald

По сравнению с теми, кто не успел на пароход, им, конечно, повезло. Но в целом поездка не была приятной.

Я читал что-то на тему того, что они там ехали чуть ли не стоя, и какать им приходилось чуть ли ни у всех на глазах. Ехали они довольно долго. Когда доехали, первым желанием каждого было больше никогда не видеть этих людей, соседей по пароходу.

Впрочем, я могу сильно путать, даже не помню, где это я читал. Возможно, какой-то обрывок какого-то журнала в каком-нибудь сельском сортире.

den73 ★★★★★
() автор топика

DSL, очевидно. Вон, как в ntpd.conf:

listen on 0.0.0.0
listen on ::

servers pool.ntp.org
sensor *
constraints from "https://www.google.com"

Просто и удобно.

kirk_johnson ★☆
()

Смотря какая у конфига структура, может и ini хватит

annulen ★★★★★
()
#comment
type key = value 
Deleted
()

flex+bison епт

anonymous
()

Худшее что можно придумать - изобратать свой формат конфига. Пользователь будет каждый раз материться, поскольку для каждого приложения придется разбираться в новом формате.

Томл фигня. Он пытается соответсвовать ини файлам, которые, по факту, тупо key-value списки. Зачастую, для конфигов требуются сложные объекты и массивы. В томле они реализованы криво, через избыточное дублирование префиксов ключей. + у стороннего человека будет снос башки, т.к. вроде обычный ини файл, но при этом какие-то странные заголовки в группах и другие непонятные моменты.

Вообще, каждый человек пытается изобрести свой ини формат и черт их разберет. Не понятно, где ставить кавычки, где нельзя. В каких-то реализациях нельзя оставлять пустые строки, т.к. это считается окончанием предыдущей группы и т.п. Не понятно, как эскейпить символы в строках, как делать переводы строк в тексте, как создавать комметарии. В общем ад.

Json тоже не особо подходит. Проблема с комментариями (в стандарте специально их не сделали, но на практике борятся между собой js комментарии // и питонячьи #, но по факту ни те, ни другие не валидны без специальной обработки. + те же проблемы с многострочными строками.

Наиболее идеален это ямл. Да он чересчур наворочен, да, мне не нравятся принудительные отступы пробелами (я больше за табы, да и привязка структуры к отступам мне не нравится, мне не лень поставить пару фигурных скобок, которые позволят пользоваться автоматическими форматировщиками, чем руками расставлять пробелы), но несмотря на все это, он относительно распространен, имеет узнаваемый стиль, решает проблему и массивов, и объектов и многострочных текстов.

Deleted
()

Никто не упомянул libconfig. Для некоторой ниши очень неплох, на мой взгляд.

Elyas ★★★★★
()

Сделай свой, ЕОЯР. Он должен быть максимально непохож на JSON и быть невалидируемым.

anonymous
()

Даёшь бинарные конфиги!

anonymous
()

Главное, чтобы был тьюринг-полный и контекстно-зависимый. А вдруг я захочу в тетрис поиграть, а конфиг не позволяет.

anonymous
()
Ответ на: комментарий от anonymous

Тогда лучше вообще сделать конфиг произвольным исполняемым файлом, который будет конфигурировать программу через IPC.

anonymous
()
Ответ на: комментарий от theNamelessOne

Я другой видел, но там более изощеренный конфиг.

anonymous
()
Ответ на: комментарий от theNamelessOne

В принципе, s-выражения достаточно мощны, но не всем по нраву.

den73 ★★★★★
() автор топика
Ответ на: комментарий от annulen

UCL для моей задачи явно переусложнён, причём некоторые вещи выглядят ошибками проектирования, например, превращение повторяющихся ключей в массивы. Также идея о допустимости запятой в конце перечисления для меня выглядит вопиющей неграмотностью, несмотря на её популярность в последнее время.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Зато программировать не просто и не удобно, а у меня всего лишь упражнение.

Да ладно, очень просто. Для C есть bison, для всех остальных языков комбинаторные парсеры.

kirk_johnson ★☆
()
Последнее исправление: kirk_johnson (всего исправлений: 1)

Если конфиг сложный, то лучше если это будет какой-то язык программирования. В идеале --- тот, на котором написана программа. В go ведь нет eval? Тогда lua или guile.

Jini ★★
()
Ответ на: комментарий от den73

ОФФТОП

Также идея о допустимости запятой в конце перечисления для меня выглядит вопиющей неграмотностью, несмотря на её популярность в последнее время.

А почему так? Удобная фича при кодогенерации, когда не нужно отслеживать последний элемент и не добавлять запятую.

yetanother ★★
()

Если конфиг предусматривает редактирование - человеком, то только читаемый формат.
Иначе - можешь брать любой, хоть чисто бинарный и шифрованный.

Atlant ★★★★★
()
Последнее исправление: Atlant (всего исправлений: 1)
Ответ на: комментарий от Jini

Пока речь идёт только о сериализации данных, т.е. содержание должно быть как в json.

den73 ★★★★★
() автор топика
Ответ на: комментарий от Novell-ch

As an alternative, lists of objects can be created with repeated blocks, using this structure

service {
    key = "value"
}

service {
    key = "value"
}

Вот это мне не нравится совсем. Типичная опечатка превращается в валидную структуру данных.

den73 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Тебе, кажется, не столько программировать, сколько общаться охота.

Как будто это что-то плохое

Einstok_Fair ★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.