Флаги командной строки Golang

У меня возникают проблемы с запуском тестов с помощью gocheck. Мне нужно передать ему флаг, чтобы указать, какой тест выполнить, например. go test -gocheck.f ApiSuite.TestSomeFunction.

Мой тестовый файл импортирует пакет настроек, в котором есть функция init(), которая указывает свои собственные флаги и вызывает flag.parseFlags(). Проблема, с которой я сталкиваюсь, заключается в том, что это, по-видимому, переопределяет флаги gocheck, поэтому я получаю сообщение об ошибке, что флаг -gocheck.f не распознается.

Примечание. Не уверен, что это актуально, но это происходит только в некоторых моих пакетах, а не в других. Я предполагаю, что это просто основано на заказе go, решает импортировать пакеты, но я думал, что упомянул об этом в случае, если это имеет значение.

Кто-нибудь еще сталкивается с этой проблемой? Есть ли простой способ просто объединить все флаги без скрежета или сделать флаги gocheck приоритетными над моими пользовательскими флагами?

Ответ 1

Если несколько пакетов обращаются к флагу. Без каких-либо проблем с другими пакетами, определяющими другие флаги, у вас возникают проблемы (как вы уже испытали). Состояние пакета "флаг" является глобальным состоянием, поэтому оно более или менее такое же, как если бы разные пакеты конкурировали, чтобы установить значение глобальной переменной во время init для разных значений. Очевидно, что это может не закончиться хорошо.

Простой способ предотвратить это: flag.Parse следует вызывать только один раз (в первом приближении). Вот почему он обычно рассматривается только в пакете "main". Если ваш не основной пакет вызывает flag.Parse, тогда он обычно конфликтует с любым flag.Parse, вызываемым в пакете "main". Обратите внимание, что go test синтезирует package main, чтобы протестировать пакет, и flag.Parse вызывается из этого синтезированного "основного" пакета.

С другой стороны, это более "безопасно" (но конфликты возможны в любом случае), чтобы определять флаги только в неосновном пакете и полагаться на flag.Parse будет вызываться в пакете "main". В неосновном пакете можно проверить, что flag.Parse был вызван с помощью flag.Parsed().

Написанное выше упрощено. Для дополнительных опций проверьте флагом пакета документация. Более "власть" может быть приобретена в некоторых сценариях, например, используя flag.Flagset, то есть используя локальное состояние для опций флага в пакете.

Тем не менее, я лично предпочитаю не использовать флаг "флажок" вне пакета "main" каким-либо образом и скорее настраивать любое настраиваемое поведение пакета через свой API. Исключения существуют, хотя, например, в файлах * _test или в других особых случаях.