Go: cmd/go: добавить поддержку версии пакета в цепочку инструментов Go

Созданный на 7 мар. 2018  ·  242Комментарии  ·  Источник: golang/go

предложение: добавить поддержку версии пакета в набор инструментов Go

Давно пора добавить версии в рабочий словарь как разработчиков Go, так и наших инструментов.
Связанное предложение описывает способ сделать это. См., в частности, раздел «Обоснование» для обсуждения альтернатив.

Этот выпуск GitHub предназначен для обсуждения существа предложения.

Другие ссылки:

Proposal Proposal-Accepted modules

Самый полезный комментарий

Это предложение активно обсуждалось более двух месяцев: @rsc и @spf13 провели сеансы обратной связи и получили ценный вклад от сообщества, что привело к пересмотру предложения. @rsc также проводил еженедельные встречи с @sdboyer , чтобы получить дополнительную обратную связь. По предложению были получены ценные отзывы, в результате которых были внесены дополнительные изменения. Все чаще эта обратная связь относится к сопутствующей реализации, а не к предложению. После тщательного рассмотрения мы считаем, что пришло время принять это предложение и позволить широкой экосистеме разработчиков инструментов Go начать вносить критические корректировки, чтобы наша пользовательская база могла получить наилучший возможный опыт.

Было два возражения против этого предложения, с которыми, как нам кажется, нам следует поговорить:

  1. Предложение потребует от людей изменить некоторые методы использования и выпуска библиотек.
  2. В предложении не предусмотрено техническое решение для всех возможных сценариев, связанных с несовместимостью.

Они точны в своих наблюдениях, но работают по назначению. Авторы и пользователи кода _должны_ изменить некоторые свои методы использования и выпуска библиотек, точно так же, как разработчики адаптировались к другим деталям Go, таким как запуск gofmt. Изменение лучших практик иногда является правильным решением. Точно так же vgo не нужно обрабатывать все возможные ситуации, связанные с несовместимостью. Как отметил Расс в своем недавнем выступлении на Gophercon Singapore , единственное постоянное решение проблемы несовместимости — это совместная работа над исправлением несовместимости и поддержанием экосистемы пакетов Go. Временные обходные пути в таких инструментах, как vgo или dep, должны работать достаточно долго, чтобы дать разработчикам время для решения реальной проблемы, и vgo достаточно хорошо справляется с этой задачей.

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

- Комитет по рассмотрению предложений Go

Все 242 Комментарий

Часто задаваемые вопросы

Этот комментарий к проблеме отвечает на наиболее часто задаваемые вопросы, будь то из обсуждения ниже или из других обсуждений. Другие вопросы из обсуждения — в комментарии к следующему выпуску.

Почему в предложении нет «использовать Деп »?

В начале пути, который привел к этому предложению, почти два года назад, мы все полагали, что ответ будет заключаться в следовании подходу к управлению версиями пакетов, примером которого является Ruby Bundler, а затем Rust Cargo: помеченные семантические версии, отредактированный вручную файл ограничения зависимостей. известный как манифест, отдельное сгенерированное машиной описание транзитивной зависимости, известное как файл блокировки, решатель версий для вычисления файла блокировки, удовлетворяющего манифесту, и репозитории как единица управления версиями. Dep почти точно следует этому грубому плану и изначально предназначался для использования в качестве модели для интеграции команд go. Однако, чем больше я понимал детали подхода Bundler/Cargo/Dep и то, что они будут означать для Go, особенно встроенного в команду go, и чем больше я обсуждал эти детали с другими в команде Go, некоторые детали казался все менее и менее подходящим для Go. В предложении эти детали корректируются в надежде создать систему, которую разработчикам будет легче понять и использовать. Дополнительные сведения о конкретных деталях, которые мы хотели изменить, см. в разделе обоснования предложения , а также в сообщении блога, объявляющем о предложении .

Почему номера основных версий должны указываться в путях импорта?

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

Почему основные версии v0, v1 исключены из путей импорта?

v1 исключен из путей импорта по двум причинам. Во-первых, многие разработчики будут создавать пакеты, которые никогда не будут вносить критические изменения после достижения версии 1, что мы поощряли с самого начала. Мы не считаем, что всех этих разработчиков следует принуждать к явной версии 1, когда они могут не иметь намерения когда-либо выпускать версию 2. v1 становится просто шумом. Если эти разработчики в конце концов создадут v2, тогда вступит в силу дополнительная точность, чтобы отличить от значения по умолчанию, v1. Есть веские аргументы в пользу видимой стабильности для вездесущей версии v1, и если бы мы разрабатывали систему с нуля, возможно, это сделало бы ее близкой. Но вес существующего кода сильно склоняет чашу весов в пользу отказа от v1.

v0 не указан в путях импорта, потому что, согласно semver , для этих версий вообще нет гарантий совместимости. Требование явного элемента v0 мало что сделало бы для обеспечения совместимости; вам нужно сказать v0.1.2, чтобы быть абсолютно точным, обновляя все пути импорта при каждом обновлении библиотеки. Это кажется излишеством. Вместо этого мы надеемся, что разработчики будут просто смотреть на список модулей, от которых они зависят, и должным образом опасаться любых версий v0.xy, которые они найдут.

Это приводит к тому, что v0 и v1 не различаются в путях импорта, но обычно v0 представляет собой последовательность критических изменений, ведущих к v1, поэтому имеет смысл рассматривать v1 как последний шаг в этой последовательности прерывания, а не что-то, что нужно отличать от v0. . Как выразился @Merovius (https://github.com/golang/go/issues/24301#issuecomment-376213693):

Используя v0.x, вы соглашаетесь с тем, что v0.(x+1) может заставить вас исправить код. Почему возникает проблема, если v0.(x+1) вместо этого называется v1.0?

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

Почему я должен создавать новую ветку для v2 вместо того, чтобы продолжать работать над мастером?

Вам не нужно создавать новую ветку. Сообщение о модулях vgo, к сожалению, производит такое впечатление при обсуждении макета репозитория «основной ветки». Но vgo не заботится о ветках. Он только просматривает теги и определяет, на какие конкретные коммиты они указывают. Если вы разрабатываете v1 на master, вы решили, что полностью закончили с v1, и хотите начать делать коммиты v2 на master, это нормально: начните помечать master тегами v2.xy. Но обратите внимание, что некоторые из ваших пользователей будут продолжать использовать v1, и иногда вы можете захотеть выпустить незначительное исправление ошибки v1. Вы можете, по крайней мере, захотеть разветвить новую ветку v1 для этой работы в тот момент, когда вы начинаете использовать master для v2.

Не помешает ли минимальный выбор версии разработчикам получать важные обновления?

Это распространенный страх, но я действительно думаю, что в случае чего произойдет обратное. Цитируя раздел «Скорость обновления» https://research.swtch.com/vgo-mvs :

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

Например, предположим, что вы пишете программу, которая зависит от нескольких других модулей, каждый из которых зависит от какого-то очень распространенного модуля, такого как gopkg.in/yaml.v2. Сборка вашей программы будет использовать самую новую версию YAML из тех, которые запрошены вашим модулем и несколькими зависимостями. Даже одна добросовестная зависимость может заставить вашу сборку обновить множество других зависимостей. Это противоположно проблеме клиента Kubernetes Go, о которой я упоминал ранее.

Во всяком случае, выбор минимальной версии вместо этого столкнулся бы с противоположной проблемой: этот ответ «максимум из минимумов» служит храповым механизмом, который заставляет зависимости продвигаться вперед слишком быстро. Но я думаю, что на практике зависимости будут продвигаться вперед с нужной скоростью, которая в конечном итоге будет медленнее, чем у Cargo и друзей.

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

См. также ответ https://github.com/golang/go/issues/24301#issuecomment -375992900 от @Merovius.

Если $GOPATH устарел, где находится загруженный код?

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

Vgo требуется некоторое пространство для хранения загруженного исходного кода и установки двоичных файлов, и для этого он по-прежнему использует $GOPATH, который в Go 1.9 по умолчанию равен $HOME/go. Таким образом, разработчикам никогда не потребуется устанавливать $GOPATH, если они не хотят, чтобы эти файлы находились в другом каталоге. Чтобы изменить только место установки двоичного файла, они могут установить $GOBIN (как всегда).

Почему вы вводите комментарий // import ?

Не были. Это было ранее существовавшее соглашение . Смысл этого примера в туре состоял в том, чтобы показать, как go.mod может вывести правильные пути модулей из комментариев импорта, если они существуют. Как только все проекты будут использовать файлы go.mod , комментарии импорта станут полностью излишними и, вероятно, устаревшими.

Резюме обсуждения (последнее обновление 25 апреля 2017 г.)

Этот комментарий к проблеме содержит краткое изложение приведенного ниже обсуждения.

Как мы можем справиться с миграцией?

[ https://github.com/golang/go/issues/24301#issuecomment -374739116 @ChrisHines.]

Ответ https://github.com/golang/go/issues/24301#issuecomment -377529520 от @rsc. Первоначальное предложение предполагает, что миграция выполняется авторами, перемещающимися в подкаталоги, когда для них важна совместимость, но, конечно, такая мотивация неверна. Совместимость наиболее важна для пользователей, которые мало влияют на перемещение авторов. И это не помогает старым версиям. Связанный комментарий, теперь также # 25069, предлагает минимальное изменение старого «go build», чтобы иметь возможность потреблять и создавать код с поддержкой модулей.

Как мы можем работать с одноэлементными регистрациями?

[ https://github.com/golang/go/issues/24301#issuecomment -374791885 @jimmyfrasche.]

Ответ https://github.com/golang/go/issues/24301#issuecomment -377527249 от @rsc. Предложение не затрагивает одноэлементные коллизии регистрации (например, http.Handle одного и того же пути) между совершенно разными модулями. Для коллизий между различными основными версиями одного модуля авторы могут написать различные основные версии, которые должны быть согласованы, обычно путем вызова v1 в v2, а затем использовать цикл требований, чтобы убедиться, что v2 не используется с более старой версией v1, которая не не знаю о координации.

Как мы должны установить версионную команду?

[ https://github.com/golang/go/issues/24301#issuecomment -375106068 @leonklingele.]

Ответ https://github.com/golang/go/issues/24301#issuecomment -377417565 от @rsc. Короче говоря, используйте go get. Мы по-прежнему используем $GOPATH/bin для места установки. Помните, что $GOPATH теперь по умолчанию имеет значение $HOME/go, поэтому команды будут заканчиваться в $HOME/go/bin, а $GOBIN может переопределить это.

Почему v0, v1 опущены в путях импорта? Почему должны появиться остальные? Почему v0, v1 никогда не должны появляться?

[ https://github.com/golang/go/issues/24301#issuecomment -374818326 @justinian.]
[ https://github.com/golang/go/issues/24301#issuecomment -374831822 @jayschwa.]
[ https://github.com/golang/go/issues/24301#issuecomment -375437150 @mrkanister.]
[ https://github.com/golang/go/issues/24301#issuecomment -376093912 @mrkanister.]
[ https://github.com/golang/go/issues/24301#issuecomment -376135447 от @kaikuehne.]
[ https://github.com/golang/go/issues/24301#issuecomment -376141888 @kaikuehne.]
[ https://github.com/golang/go/issues/24301#issuecomment -376213693 от @Merovius.]
[ https://github.com/golang/go/issues/24301#issuecomment -376247926 от @kaikuehne.]

Добавлено в FAQ выше.

Почему в предложении упоминаются zip-файлы?

[ https://github.com/golang/go/issues/24301#issuecomment -374839409 @nightlyone.]

Экосистема выиграет от определения конкретного формата обмена. Это позволит использовать прокси и другие инструменты. В то же время мы отказываемся от прямого использования контроля версий (см. обоснование вверху этого поста ). И то, и другое мотивирует описание конкретного формата. Большинству разработчиков вообще не нужно думать о zip-файлах; разработчикам не нужно заглядывать внутрь них, если только они не создают что-то вроде godoc.org.

См. также #24057 о zip и tar.

Разве размещение основных версий в путях импорта не нарушает DRY?

[ https://github.com/golang/go/issues/24301#issuecomment -374831822 @jayschwa.]

Нет, потому что семантика импорта должна быть понятна без ссылки на файл go.mod. Файл go.mod указывает только более мелкие детали. См. вторую половину раздела семантического импорта версий предложения , начиная с кавычек.

Кроме того, если вы слишком сильно СУШИТЕ, вы получите хрупкую систему. Избыточность может быть хорошей вещью. Так что «нарушение DRY» — то есть ограниченное повторение себя — не всегда плохо. Например, мы помещаем предложение пакета в каждый файл .go в каталоге, а не только в один. Это на раннем этапе выявляло честные ошибки, а позже превратилось в простой способ отличить внешние тестовые пакеты (пакет x от пакета x_test). Нужно соблюдать баланс.

Какой часовой пояс используется для отметки времени в псевдоверсиях?

[ https://github.com/golang/go/issues/24301#issuecomment -374882685 от @tpng.]

УНИВЕРСАЛЬНОЕ ГЛОБАЛЬНОЕ ВРЕМЯ. Заметьте также, что вам никогда не придется вводить псевдоверсию самостоятельно. Вы можете ввести хэш коммита git (или префикс хэша), и vgo вычислит и заменит соответствующую псевдоверсию.

Будет ли vgo обращаться к зависимостям, отличным от Go, таким как C или буферы протоколов? Сгенерированный код?

[ https://github.com/golang/go/issues/24301#issuecomment -374907338 от @AlexRouSg.]
[ https://github.com/golang/go/issues/24301#issuecomment -376606788 от @stevvooe.]
[ https://github.com/golang/go/issues/24301#issuecomment -377186949 @nim-nim.]

Разработка, не связанная с Go, по-прежнему не является целью команды go , поэтому не будет поддержки управления библиотеками C и т. п., а также не будет явной поддержки протокольных буферов.

Тем не менее, мы, конечно же, понимаем, что использование буферов протоколов с Go слишком сложно, и мы хотели бы, чтобы это рассматривалось отдельно.

Что касается сгенерированного кода в более общем плане, то ответом является настоящая кросс-языковая система сборки, особенно потому, что мы не хотим, чтобы у каждого пользователя были установлены правильные генераторы. Автору лучше запустить генераторы и проверить результат.

Не помешает ли минимальный выбор версии разработчикам получать важные обновления?

[ https://github.com/golang/go/issues/24301#issuecomment -375090551 от @TocarIP.]
[ https://github.com/golang/go/issues/24301#issuecomment -375985244 @nim-nim.]
[ https://github.com/golang/go/issues/24301#issuecomment -375992900 от @Merovius.]

Добавлено в FAQ.

### Могу ли я использовать master для разработки v1, а затем повторно использовать его для разработки v2?

[ https://github.com/golang/go/issues/24301#issuecomment -375248753 @mrkanister.]
[ https://github.com/golang/go/issues/24301#issuecomment -375989173 @aarondl.]

да. Добавлено в FAQ.

Каковы сроки для этого?

[ https://github.com/golang/go/issues/24301#issuecomment -375415904 от @flibustenet.]

Ответ в https://github.com/golang/go/issues/24301#issuecomment-377413777 от @rsc. Короче говоря, цель состоит в том, чтобы получить «предварительный просмотр технологии» в Go 1.11; работа может продолжаться несколько недель после заморозки, но не дольше. Вероятно, не отправляйте PR с добавлением go.mod в каждую библиотеку, которую вы можете найти, пока предложение не будет помечено как принятое и копия cmd/go для разработки не будет обновлена.

Как я могу внести обратно несовместимое изменение безопасности?

[ https://github.com/golang/go/issues/24301#issuecomment -376236546 от @buro9.]

Ответ в https://github.com/golang/go/issues/24301#issuecomment-377415652 от @rsc. Короче говоря, рекомендации по совместимости с Go 1 разрешают вносить критические изменения из соображений безопасности, чтобы избежать наезда на основную версию, но всегда лучше делать это таким образом, чтобы существующий код работал как можно лучше. Например, не удаляйте функцию. Вместо этого сделайте функцию panic или log.Fatal только в случае неправильного вызова.

Если одно репо содержит разные модули в подкаталогах (скажем, v2, v3, v4), может ли vgo смешивать и сопоставлять разные коммиты?

[ https://github.com/golang/go/issues/24301#issuecomment -376266648 @jimmyfrasche.]
[ https://github.com/golang/go/issues/24301#issuecomment -376270750 от @AlexRouSg.]

да. Он рассматривает каждый тег версии как соответствующий только одному поддереву общего репозитория и может использовать другой тег (и, следовательно, разные фиксации) для каждого решения.

Что делать, если проекты неправильно используют semver? Должны ли мы разрешать второстепенные версии в путях импорта?

[ https://github.com/golang/go/issues/24301#issuecomment -376640804 от @pbx0.]
[ https://github.com/golang/go/issues/24301#issuecomment -376645212 @powerman.]
[ https://github.com/golang/go/issues/24301#issuecomment -376650153 от @pbx0.]
[ https://github.com/golang/go/issues/24301#issuecomment -376660236 от @powerman.]

Как отмечает @powerman , нам определенно нужно предоставить средство проверки согласованности API, чтобы проекты, по крайней мере, могли быть предупреждены, когда они собираются выпустить явно критическое изменение.

Можете ли вы определить, есть ли у вас более одного пакета в сборке?

[ https://github.com/golang/go/issues/24301#issuecomment -376640804 от @pbx0.]

Проще всего было бы использовать goversion -m для полученного двоичного файла. Мы должны сделать опцию go, чтобы показать то же самое без создания двоичного файла.

Опасения по поводу зависимости vgo от прокси-сервера по сравнению с поставщиком, особенно с открытым исходным кодом по сравнению с предприятием.

[ https://github.com/golang/go/issues/24301#issuecomment -376925845 от @joeshaw.]
[ https://github.com/golang/go/issues/24301#issuecomment -376936614 @kardianos.]
[ https://github.com/golang/go/issues/24301#issuecomment -376947621 @Merovius.]
[ https://github.com/golang/go/issues/24301#issuecomment -376979054 @joeshaw.]
[ https://github.com/golang/go/issues/24301#issuecomment -376988873 @jamiethermo.]
[ https://github.com/golang/go/issues/24301#issuecomment -377134575 @Merovius.]

Ответ: [ https://github.com/golang/go/issues/24301#issuecomment -377411175 @rsc.] Будут поддерживаться и прокси, и поставщик. Прокси очень важен для предприятия, а поставщик очень важен для открытого исходного кода. Мы также хотим построить надежную зеркальную сеть, но только после того, как vgo станет go.

Опасения по поводу protobuild в зависимости от семантики GOPATH.

[ https://github.com/golang/go/issues/24301#issuecomment -377601170 от @stevvooe.]

Ответ [ https://github.com/golang/go/issues/24301#issuecomment -377602765 @rsc] запросил более подробную информацию в новом выпуске, но этот вопрос, похоже, не был зарегистрирован.

Предложение добавить специальный тег vgo-v1-lock .

[ https://github.com/golang/go/issues/24301#issuecomment -377662150 @kybin.]

Сначала это кажется привлекательным, но приводит к особым случаям, за которые, вероятно, не стоит браться. Полный ответ в https://github.com/golang/go/issues/24301#issuecomment-384344659 .

Как исправить глубокую зависимость без вендора?

[ https://github.com/golang/go/issues/24301#issuecomment -378255833 @chirino.]

Ответ [ https://github.com/golang/go/issues/24301#issuecomment -378261916 от @kardianos.] С помощью директивы replace.

Что мы будем делать с изменением имен модулей?

[ https://github.com/golang/go/issues/24301#issuecomment -379020339 @jimmyfrasche.]

Ответ [ https://github.com/golang/go/issues/24301#issuecomment -379307176 @rsc.]
Это реальные, ранее существовавшие проблемы, которые предложение vgo не пытается решить напрямую, но очевидно, что в конечном итоге мы должны их решить. Решение проблемы исчезновения кода — наличие кэширующих прокси-серверов (зеркал) и причины им доверять; это будущая работа. (Или, если хотите, используйте вендорство в проекте верхнего уровня.) Ответом на перемещение кода является добавление явной концепции перенаправления модулей или пакетов, подобно тому, как псевдонимы типов являются перенаправлениями типов; это также работа на будущее.

Как насчет подключения к локальным серверам Git?

[ https://github.com/golang/go/issues/24301#issuecomment -383168012 @korya.]

В план снова добавлен прямой доступ к git. См. № 24915.

А как насчет бинарных пакетов?

[ https://github.com/golang/go/issues/24301#issuecomment -382793364 @sdwarwick.]

Пакеты только для двоичных файлов когда-либо поддерживались только в ограниченных случаях какой-либо внеполосной установки в GOPATH/pkg. Go get никогда не поддерживал извлечение и установку только бинарных пакетов и не будет поддерживать это. Бинарный пакет работает только с одним конкретным компилятором и одной конкретной копией зависимостей, что сильно ограничивает его поддержку. Правильный ответ почти всегда состоит в том, чтобы вместо этого использовать исходный код.

Должны ли мы использовать синтаксис path@version в файле go.mod?

[ https://github.com/golang/go/issues/24301#issuecomment -382791513 @sdwarwick.]

Это номер 24119. Сначала это казалось хорошей идеей, но после тщательного рассмотрения оказалось, что нет.

.

.

Изменение https://golang.org/cl/101678 упоминает эту проблему: design: add 24301-versioned-go

Это предложение впечатляет, и мне больше всего в нем нравится все. Тем не менее, я отправил следующее сообщение в список рассылки, но так и не получил ответов. Тем временем я видел эту проблему, поднятую другими на слабом канале Gophers для vgo, и не нашел там удовлетворительного ответа.

От: https://groups.google.com/d/msg/golang-dev/Plc42fslQEk/rlfeNlazAgAJ

Я больше всего обеспокоен тем, что путь миграции между миром до vgo и миром vgo идет плохо. Я думаю, что мы рискуем причинить большую боль сообществу Go, если не будет гладкого пути миграции. Очевидно, что миграция не может быть атомарной для всего сообщества, но если я понял все, что вы написали о vgo до сих пор, могут быть некоторые ситуации, когда существующие широко используемые пакеты не будут использоваться как инструментами до vgo, так и после. -вго инструменты.

В частности, я считаю, что существующие пакеты, которые уже имеют тегированные выпуски с основными версиями >= 2, не будут работать с vgo, пока у них не будет файла go.mod, а также они не будут импортированы с расширенным путем импорта /vN. Однако, как только эти изменения будут внесены в репозиторий, это нарушит использование пакета до vgo.

Похоже, это создает другую проблему импорта алмазов, в которой два родственных пакета в середине алмаза импортируют общий пакет v2+. Меня беспокоит то, что одноуровневые пакеты должны атомарно использовать пути импорта vgo, чтобы пакет в верхней части ромба не находился в состоянии невозможности сборки, независимо от того, использует ли он инструменты vgo или pre-vgo.

Я еще не видел ничего, что объясняло бы путь миграции в этом сценарии.

В предложении говорится:

Сборки с поддержкой модулей могут импортировать пакеты, не поддерживающие модули (которые находятся за пределами дерева с файлом go.mod), при условии, что они помечены семантической версией v0 или v1. Они также могут ссылаться на любую конкретную фиксацию, используя «псевдоверсию» формы v0.0.0-yyyymmddhhmmss-commit. Форма псевдоверсии позволяет ссылаться на непомеченные фиксации, а также на фиксации, помеченные семантическими версиями версии 2 или выше, но не соответствующие соглашению об управлении версиями семантического импорта.

Но я не вижу способа для пакетов, не поддерживающих модули, импортировать пакеты с поддержкой модулей с транзитивными зависимостями >= v2. Это, по-видимому, вызывает фрагментацию экосистемы, которая еще не решена. Если у вас есть зависимая от модулей зависимость с пакетом >= v2 где-то в своих транзитивных зависимостях, кажется, что все зависимые от нее зависимости также принимают vgo, чтобы сборка работала.

Обновление: см. также https://github.com/golang/go/issues/24454 .

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

Мне непонятно, что это значит и как это меняется от текущей ситуации. Мне кажется, это описывает и текущую ситуацию: если я нарушу это правило, апгрейды и go-get не пройдут. AIUI на самом деле ничего не меняет, и я бы предложил убрать хотя бы упоминание о «большем количестве зубов». Если, конечно, этот абзац не подразумевает, что существуют дополнительные механизмы для наказания/предотвращения поломок?

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

Если основной версией является v0 или v1, элемент номера версии должен быть опущен; в противном случае он должен быть включен.

Почему это? В связанном посте я вижу только обоснование того, что это то, что в настоящее время разработчики делают для создания альтернативных путей при внесении критических изменений, но это обходной путь для того факта, что они изначально не планируют, чтобы инструменты не обрабатывали версии для них. . Если мы переходим на новую практику, почему бы не разрешить и не поощрять (или даже обязать) включать в новые пакеты с поддержкой vgo v0 или v1 ? Кажется, что пути без версий — это просто возможность запутаться. (Это пакет в стиле vgo? Где граница модуля? и т.д.)

В целом мне нравится это предложение, но я зациклен на требовании основных версий в путях импорта:

  1. Это нарушает принцип DRY, когда основная версия уже может быть известна из go.mod . Понимание того, что произойдет, если между ними возникнет несоответствие, также трудно понять интуитивно.
  2. Неправильность разрешения отсутствия v0 и v1 также нелогична.
  3. Изменение всех путей импорта при обновлении зависимости кажется потенциально утомительным.

Я понимаю, что такие сценарии, как пример moauth , должны быть работоспособными, но, надеюсь, не за счет упрощения более распространенных сценариев.

Прежде всего: Впечатляющая работа!

Одна вещь, которая мне совершенно непонятна и кажется немного недоработанной:

Почему в этом предложении есть zip-файлы?

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

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

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

Какой часовой пояс используется для отметки времени в псевдоверсии (v0.0.0-yyyymmddhhmmss-commit)?

Редактировать:
Он находится в формате UTC, как указано в https://research.swtch.com/vgo-module.

@rsc Будете ли вы обращаться к зависимостям C?

Похоже, что выбор минимальной версии делает распространение некритических изменений очень медленным. Предположим, у нас есть популярная библиотека Foo, которую используют проекты A, B и C. Кто-то улучшает производительность Foo, не меняя API. В настоящее время получение обновлений является процессом отказа. Если в проекте A реализован Foo, а в B и C нет, автору нужно только отправить pr с обновлением зависимостей от поставщика для A. Таким образом, вклады, не нарушающие API, не будут иметь такого большого влияния на сообщество и несколько обескуражены по сравнению с текущими ситуация. Это еще более проблематично для обновлений безопасности. Если какой-то заброшенный/небольшой/не очень активный проект (не библиотека) объявляет прямую зависимость от старой версии, например, x/crypto, все пользователи этого проекта будут уязвимы для уязвимости в x/crypto до тех пор, пока проект не будет обновлен, возможно, навсегда. В настоящее время пользователи таких проектов получают последнюю исправленную версию, что ухудшает ситуацию с безопасностью. IIRC было несколько предложений, как исправить это в обсуждении списка рассылки, но, насколько я могу судить, это предложение не упоминает об этом.

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

См. упоминание go get -p .

См. упоминание о go get -p.

Я видел это, но это все еще механизм отказа.
Я думал о том, как библиотека пометит все предыдущие выпуски как небезопасные, чтобы заставить пользователя запустить go get -p или явно подписаться на небезопасную библиотеку.

Если поддержка go get в том виде, в каком мы ее знаем сегодня, будет объявлена ​​устаревшей и в конечном итоге удалена, как тогда рекомендуется получать и устанавливать (без тегов) бинарные файлы Go? Требует ли git clone сначала выполнить проект, а затем вручную go install установить двоичный файл?
Если $GOPATH устарело, куда будут установлены эти двоичные файлы?

@leonklingele : насколько я понимаю, go get не устареет, наоборот.
Он будет дополнен возможностями автоматического и прозрачного управления версиями. Если проект зависит от нетегированного проекта, он просто возьмет мастер и «поставит» его в этой точной версии.
Опять же, мое собственное понимание, прочитанное немного о vgo. Я все еще в процессе полного понимания.

Интересно, как это повлияет на поток работы с репозиторием Git в целом, также опираясь на это предложение из предложения:

Если основной версией является v0 или v1, элемент номера версии должен быть опущен; в противном случае он должен быть включен.

На данный момент кажется обычным работать над мастером (для меня это включает в себя недолговечные ветки функций) и время от времени помечать коммит новой версией. Я чувствую, что этот рабочий процесс становится более запутанным с модулями Go, как только я выпускаю v2 моей библиотеки, потому что теперь у меня есть ветка master и v2 . Я ожидаю, что master будет текущей ветвью, а v2 будет обслуживающей ветвью, но все как раз наоборот.

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

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

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

теперь у меня есть мастер и ветка v2

Вместо этого вы можете создать подкаталог v2/ в master.

@мрканистер

Я бы предпочел мастер и ветку v1, но я не уверен, как именно это будет соответствовать предложению.

Насколько я понимаю, https://research.swtch.com/vgo-module vgo использует теги, а не ветки для идентификации версий. Таким образом, вы можете продолжать разработку на master и переходить на v1, пока теги указывают на правильную ветку и коммит.

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

Это проблематичный стиль мышления, который, как мне кажется, сильно мешал Го в прошлом. Для одного человека в одном проекте переключение ветки по умолчанию в данный момент просто, да. Но нарушение правил рабочего процесса приведет к тому, что люди забудут, особенно если они работают на нескольких языках. И это будет еще один причудливый пример того, как Go делает вещи совершенно по-другому, и новичкам придется учиться. Идти против общепринятых соглашений о рабочем процессе программиста — совсем не меньшая цена.

Идти против общепринятых соглашений о рабочем процессе программиста — совсем не второстепенная цена.

Отказ от традиционного пути иногда является необходимым условием для инноваций.

Если я правильно понял часть предложения, вам никогда не придется создавать подкаталог или новую ветку. Потенциально вы можете иметь только основную ветку и git тегировать свое репо с 0.0 на 1.0, на 2.0 и так далее , если вы обязательно обновите свой go.module до правильного пути импорта для вашей библиотеки.

@mrkanister Я думаю, что для dev ваш клон вашего мастера (или любой ветки dev) и используйте директиву «replace» (см. vgo-tour), чтобы указать на него. (если я понимаю, что вы имеете в виду, не уверен).

@rsc Я хотел бы попросить вас быть более точным в отношении дорожной карты и того, что мы должны делать сейчас.
Будет ли он следовать политике Go и замораживать функции vgo через 3 месяца (сейчас 2)?
Должны ли мы теперь пойти с нашей паломнической палочкой и попросить каждого сопровождающего libs добавить файл go.mod, или мы должны дождаться официального принятия предложения (чтобы быть уверенными, что имя и синтаксис не изменятся)?

Инструменты @flibustenet не подпадают под действие политики 1.0, поэтому все может измениться.

https://golang.org/doc/go1compat

Наконец, цепочка инструментов Go (компиляторы, компоновщики, инструменты сборки и т. д.) находится в активной разработке и может изменить свое поведение. Это означает, например, что сценарии, которые зависят от местоположения и свойств инструментов, могут быть нарушены при доработке.

Также из предложения

План, при условии утверждения предложения, состоит в том, чтобы выпустить поддержку модулей в Go 1.11 в качестве дополнительной функции, которая еще может измениться. Релиз Go 1.11 даст пользователям возможность использовать модули «по-настоящему» и давать критические отзывы. Несмотря на то, что детали могут измениться, будущие выпуски смогут использовать деревья исходного кода, совместимые с Go 1.11. Например, Go 1.12 поймет, как использовать синтаксис файла go.mod Go 1.11, даже если к тому времени синтаксис файла или даже имя файла изменились. В более позднем выпуске (скажем, Go 1.12) мы объявим о завершении поддержки модуля. В более позднем выпуске (скажем, Go 1.13) мы прекратим поддержку go get немодулей. Поддержка работы в GOPATH будет продолжаться бесконечно.

Спасибо за ответ.

@AlexRouSg

Насколько я понимаю, https://research.swtch.com/vgo-module vgo использует теги, а не ветки для идентификации версий. Таким образом, вы можете продолжать разработку на master и переходить на v1, пока теги указывают на правильную ветку и коммит.

Вы правы, это будет продолжать работать, как и раньше (просто дважды проверил, чтобы быть уверенным), хороший улов!

С учетом этого, то, что я (и, по-видимому, другие) не понимаю, - это причина, по которой запрещается существование пакета v1 . Я попытался импортировать один, используя /v1 в конце импорта, а также добавив это в go.mod импортируемого пакета, но vgo будет искать папку с именем v1 Вместо этого

@мрканистер
Я думаю, что основная причина запрета v1 или v0 в пути импорта заключается в том, чтобы обеспечить наличие только одного пути импорта для каждой совместимой версии пакета.
Использование простого пути импорта вместо /v1 упрощает переход, поэтому вам не нужно обновлять все пути импорта, чтобы добавить /v1 в конце.

Привет,

Хотя многие пункты в предложении более чем приветствуются и помогут укротить большие кодовые базы Go, появившиеся с течением времени, правило «использовать минимальную версию» весьма вредно:

  • вы хотите, чтобы ваша экосистема кода развивалась. Это означает, что вы хотите, чтобы люди тестировали и использовали новые версии и обнаруживали проблемы раньше, чем они накапливаются.
  • вы хотите, чтобы новые выпуски модулей, устраняющие проблемы безопасности, применялись как можно скорее
  • вы хотите иметь возможность применять новые выпуски модулей, которые устраняют проблемы безопасности, как можно скорее. Они не всегда отмечены в исправлениях безопасности. Если вы избегаете новых выпусков, вы также избегаете этих исправлений.
  • даже если новый выпуск не содержит исправлений безопасности, раннее применение его изменений означает, что будет меньше изменений для проверки, когда будет опубликован следующий выпуск, который содержит исправления безопасности (и последнее, что вы хотите, когда такой выпуск опубликован, и вам нужно быть быстрым означает увязнуть в промежуточных изменениях, на которые вы раньше не обращали внимания).
  • применение промежуточных выпусков вредно только в том случае, если они нарушают совместимость, а они не должны нарушать совместимость, и если они нарушают совместимость, лучше обнаружить это и сообщить авторам модулей, прежде чем они сделают это привычкой для следующих выпусков, вы в конечном итоге абсолютно необходимость.
  • вы не хотите, чтобы старые фрагменты кода тянули вас вниз, потому что они все еще указывают древнюю версию зависимости, и никто не находит время для обновления своего манифеста. Использование последней версии крупного релиза удовлетворяет эту социальную потребность в других экосистемах кода: заставить разработчиков тестировать последнюю версию, а не откладывать ее до тех пор, пока не станет слишком поздно, потому что «есть более важные» (т. е. более интересные) дела.

    • в то время как теоретически вы можете поставлять неограниченное количество версий модуля, чтобы каждый фрагмент кода мог использовать ту, которую он хочет, на практике, как только вы составляете два модуля, использующих одно и то же dep, вы должны выбрать версию, поэтому чем сложнее ваш программное обеспечение, тем меньше вы будете терпеть несколько версий. Так что вскоре вы столкнетесь со старой проблемой, что делать с отставшими, которые замедляют весь конвой. Я никогда не встречал человеческую культуру, которая решала бы эту проблему, говоря отставшим: «Вы правы, идите так медленно, как хотите, все будут ждать вас». Это может быть мило и альтруистично, но непродуктивно.

Бороться с человеческой инертностью тяжело и болезненно, и мы боремся с ней, потому что это необходимо для прогресса, а не потому, что это приятно. Создание приятных инструментов, которые избегают проблемы и побуждают людей откладывать еще немного, совершенно бесполезно, это только ускорит седиментацию проекта и накопление технического долга. На github уже есть десятки проектов Go, и большая часть их readme посвящена автору, умоляющему своих пользователей обновиться, потому что он внес важные исправления, по умолчанию самый старый выпуск обобщает проблему.

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

Мой оставшийся без ответа вопрос скопирован из списка рассылки:

Мы ожидаем, что большинство разработчиков предпочтут следовать обычному соглашению о «основной ветке», согласно которому разные основные версии размещаются в разных ветках. В этом случае корневой каталог в ветке v2 будет иметь go.mod, указывающий v2, например:

Похоже, что есть подкаталоги и это основное соглашение о ветках, которые оба поддерживаются vgo. По моему неподтвержденному опыту, ни один репозиторий не следует этому соглашению в Go или других языках (на самом деле я не могу придумать ни одного, кроме тех, которые принудительно использует gopkg.in, который в наши дни кажется относительно неиспользуемым). Основная ветвь - это самая последняя ветка, и в ее истории есть теги v2.3.4. Теги существуют для разделения всего (не только второстепенных версий). Если необходимо исправить старую версию, ветка временно создается из последнего тега v1, фиксируется, добавляется новый тег, и ветка удаляется. Нет ветки для версий, это просто текущие ветки master/dev/feature + теги версии. Я знаю, что в Git «все является ссылкой», но для других систем контроля версий различие может быть не таким нечетким.

Сказав это, я протестировал описанный выше рабочий процесс с vgo (только с тегами v2.0.0, v2.0.1 и без веток), и, похоже, он работает. Итак, мой вопрос: хотя это работает сейчас, это предназначено? Поскольку он описан не так подробно, как два других рабочих процесса в блоге, и я хочу убедиться, что работа без ветки v2/v3... не является случайной функциональностью, которая исчезнет, ​​поскольку, как я объяснил выше, я никогда не видел, как этот (или другой) описанный рабочий процесс в посте будет массово принят кем-либо (особенно за пределами сообщества Go).

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

Спасибо за все ваши усилия.

Может ли кто-нибудь прояснить, как предлагаемая альтернативная модель MVS будет работать для улучшения частоты обновления? Потому что мне непонятно. Мое понимание альтернативной (широко используемой) модели таково:

  • Разработчик создает вручную манифест, в котором перечислены ограничения версий для всех используемых зависимостей.
  • Разработчик запускает $solver, который создает файл блокировки, перечисляющий выбранное подмножество версий транзитивных зависимостей, которые удовлетворяют указанным ограничениям.
  • Этот файл блокировки фиксируется и используется во время сборки и установки, чтобы гарантировать воспроизводимость сборок.
  • Когда новая версия зависимости выпущена и будет использоваться, разработчик потенциально обновляет манифест, повторно запускает решатель и повторно фиксирует новый файл блокировки.

Предлагаемая модель MVS, насколько я понимаю,

  • Разработчик автоматически генерирует go.mod на основе набора путей импорта в модуле, выбирая самую новую на данный момент версию любой транзитивной зависимости.
  • go.mod фиксируется и используется для получения нижних границ версий во время сборки и установки. MVS гарантирует воспроизводимость сборок
  • Когда новая версия зависимости выпущена и предназначена для использования, разработчик запускает vgo get -u , который извлекает самые новые версии транзитивных зависимостей и перезаписывает go.mod новыми нижними границами. Затем это отправляется.

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

Очевидно, я что-то упускаю (и буду чувствовать себя глупо примерно через 5 м), что это?

@tpng

Использование простого пути импорта вместо /v1 упрощает переход, поэтому вам не нужно обновлять все пути импорта, чтобы добавить /v1 в конце.

На самом деле это не должно быть необходимо. Позвольте мне привести пример:

В настоящее время пользователь использует, например, v1.0.0 библиотеки, закрепленной менеджером зависимостей и тегом в вышестоящем репозитории. Теперь восходящий поток решает создать go.mod и также вызывает модуль /v1 . Это должно привести к новой фиксации и новому тегу (например, v1.0.1 ). Так как vgo никогда не будет пытаться обновлять зависимости самостоятельно, это не должно ничего сломать для пользователя, но он/она может сознательно обновиться, также изменив путь импорта (pr vgo может сделать это для него/нее).

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

Да, я думаю, я действительно вижу этот момент, чтобы не смущать новых пользователей библиотеки.

Если основной версией является v0 или v1, элемент номера версии должен быть опущен; в противном случае он должен быть включен.

Может кто-нибудь объяснить причину этого? Что мне делать как пользователю библиотеки, когда я пока не хочу использовать версию 1, потому что она внесла критическое изменение, которое было бы совершенно нормально при семантическом управлении версиями (новая основная версия)?

Я бы предпочел опустить только версию до версии 1, что указывает на нестабильный/незавершенный пакет. Начиная с версии 1, я хочу иметь возможность рассчитывать на то, что получу стабильный релиз. Отсутствие v1 в пути импорта сбивает с толку, потому что вы не знаете, отслеживаете ли вы постоянно меняющуюся библиотеку или стабильную версию. Я думаю, что это также не очень хорошо работает со схемой семантического версионирования, где v1 точно указывает на первый стабильный выпуск, который используется для четкого отличия этой версии от версий 0.x.

@kaikuehne

Что мне делать как пользователю библиотеки, когда я пока не хочу использовать версию 1, потому что она внесла критическое изменение, которое было бы совершенно нормально при семантическом управлении версиями (новая основная версия)?

Насколько я понял, vgo никогда не будет обновлять зависимости самостоятельно, даже до патчной версии, а вместо этого оставляет это как сознательное решение для вас. Поэтому, если вы зависите от версии 0.4.5 библиотеки (у которой есть тег для нее), теоретически вы можете продолжать использовать ее вечно. Вы также сможете вручную закрепить версию в файле go.mod .

Что, если другая зависимость, которую я использую, зависит от того же пакета, но версии v1? Оба пакета импортируются с использованием одного и того же пути импорта. Нет ли конфликта при компиляции их в один и тот же двоичный файл?

Если бы мы потребовали, чтобы версия 1 также была частью пути импорта, оба пакета считались бы разными пакетами, чем они и являются.

@kaikuehne, тогда он обновится до минимальной общей версии, которая работает. (в моем понимании)

@kaikuehne Я не понимаю ваших рассуждений. Вы используете v0, поэтому, по-видимому, у вас все в порядке с критическими изменениями; почему это может быть проблемой, если v1 сломается, учитывая, что вы уже используете версию, не имеющую гарантии стабильности? Кроме того, скажем, вместо того, чтобы переходить от версии 0.1 к версии 1.0 с критическим изменением, апстрим добавит разрыв к версии 0.2, а затем выпустит (некритическую) версию 1.0. Казалось бы, это вполне соответствует ожиданиям относительно семантических версий, но для вас это будет означать точно такое же количество тяжелого труда (независимо от используемого менеджера пакетов). Т.е. я действительно не понимаю, как "автор внезапно перестал ломать свой API" представляет собой проблему, которая не вызвана использованием версии до 1.0.

Другими словами: используя v0.x, вы соглашаетесь с тем, что v0.(x+1) может заставить вас исправить код. Почему возникает проблема, если v0.(x+1) вместо этого называется v1.0?

По пункту обсуждения 4: явное принятие правила совместимости импорта и «новый пакет должен быть обратно совместим со старым пакетом»…

В моем случае у меня есть пакет безопасности https://github.com/microcosm-cc/bluemonday , и недавно (в конце прошлого года) у меня был сценарий, в котором я узнал, что общедоступная функция принципиально не подходит для этой цели. Поэтому я удалил его.

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

Чтобы избежать этого, я, вероятно, вместо этого log.Fatal() внутри функции, которую я хотел удалить, исключительно для того, чтобы существующий код не использовал небезопасную конечную точку, а для сохранения совместимости.

Учитывая, что ни один из них не идеален ... как мы предвидим исправления безопасности, которые требуют, чтобы общедоступная функция была жестко устаревшей? (если не удивить разработчика runtime log.Fatal()?)

Для тех, кто хочет увидеть коммит для этого: https://github.com/microcosm-cc/bluemonday/commit/a5d7ef6b249a7c01e66856b585a359970f03502c

@Merovius Спасибо за разъяснение при использовании версий 0.x. Как вы сказали, нет никаких гарантий, на которые можно полагаться при использовании версии до 1.0, и что версии 0.x являются особым случаем в semver. Если я правильно понял, то изложенные правила на самом деле вообще не относятся к версиям 0.x. Мой вопрос заключается в том, имеет ли смысл отражать это различие и в коде, особенно при именовании пакетов. Например, если пакет только импортирует пакеты без версии, вы сразу увидите, что он построен на нестабильном коде. Если все импорты содержат версию v1, вы видите, что она использует стабильные версии.

@buro9 В предложении предлагается примерно следовать гарантиям совместимости go1, которые содержат исключения для сбоев API, связанных с безопасностью.

@kaikuehne Спасибо, это проясняет вашу озабоченность.

Меня беспокоит взаимодействие функций (при условии, что я правильно все понимаю).

Если у вас есть модуль M, который использует овеществленные версии (буквальные каталоги vN в исходном коде, а не синтетические элементы пути импорта, полученные из тегов), и вы создаете программу P, которая транзитивно опирается на несколько основных версий M, не будет ли это должны нарушать выбор минимальной версии в некоторых сценариях?

То есть, скажем, P зависит от основных версий 2, 3 и 4 M. Для каждой основной версии M указана минимальная полная версия. Поскольку версии M совместно используют исходный код специально для того, чтобы иметь возможность делать такие вещи, как прозрачное использование одного и того же определения типа с псевдонимами типов, тогда только одна копия M может быть включена для всех трех основных версий вместо одной копии для каждой основной версии. Любой выбор полной версии для одной основной версии фиксирует выбор полной версии двух других основных версий и может привести к выбору не минимальной версии для одной или обеих других основных версий.

Как vgo справляется с этим? Может ли это вызвать какие-либо проблемы, кроме того, что иногда они немного меньше минимальных? (Например, можно случайно построить набор модулей, которые не дают решения или вызывают зацикливание решателя?)

@джиммифраше

Если вы используете каталоги основных версий, vgo по-прежнему будет использовать теги, а затем получит только соответствующую папку версии этого тега. например, вы зависите от версий 2, 3, 4. vgo будет проверять тег v2.nm, v3.nm, v4.nm
А то из тега v2.nm получить только папку v2 и так далее. Итак, в конце концов, все по-прежнему следует за тегами.

Я задал вопрос в этом сообщении списка рассылки , но не увидел конкретного ответа. Я повторю это здесь:

что произойдет с ресурсами, отличными от Go, такими как protobufs или c-файлы? Приносим извинения, если на этот вопрос уже был дан ответ в ваших сообщениях, но мы используем путь поставщика для распространения и установки пути импорта для файлов protobuf. Хотя мы собирали пакеты Go на основе предварительно скомпилированного вывода protobuf, мы также должны рассмотреть случай компиляции новых пакетов Go из файлов protobuf, зависящих от вендорных зависимостей (т. е. ссылающихся на rpc.Status из другого файла protobuf). Я могу привести еще несколько конкретных примеров, если это описание слишком сложное.

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

Это было большой проблемой при работе с protobufs для нас, и этот проект решил многие из этих проблем. Было бы обидно, если бы это было совершенно несовместимо с предложением.

Еще раз извините, если я что-то упустил.

Мне нравится это предложение. Меня беспокоит только то, что слишком много проектов часто вносят небольшие критические изменения между второстепенными версиями и резервируют изменения основной версии только для очень больших критических изменений. Если второстепенные изменения, нарушающие версию, происходят часто, то возникают проблемы с алмазной зависимостью, поскольку это нарушает предположение SIV. Интересно, поможет ли включение второстепенной версии в заявление об импорте большему количеству проектов соблюдать контракт о ненарушающих изменениях? Я думаю, что недостатком является дополнительный импорт, а обновление младших версий становится более сложным (и более явным).

Это поднимает еще один вопрос, который у меня есть: легко ли (сегодня) с vgo определить, есть ли у вас более 1 версии пакета в сборке? Хотя разрешение двух версий одного и того же пакета иногда имеет решающее значение для продвижения вперед, похоже, что большинство проектов хотели бы избежать этого, если только это не временно из-за возможных непредвиденных побочных эффектов инициализации. Простой способ проверить это может быть полезен, и некоторые проекты могут захотеть применить его во время проверки кода.

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

Критическое изменение — это критическое изменение. Он не может быть маленьким или большим. Я предполагаю, что такие пакеты в конечном итоге будут отвергнуты сообществом как слишком ненадежные и не соответствующие требованиям. Даже если они будут следовать за semver и быстро доберутся до больших мажорных номеров вроде 42.xx, пользоваться ими все равно будет очень неудобно. Итак, если вы хотите внести много критических изменений, просто продолжайте использовать старший номер 0. Таким образом, он будет продолжать работать так же, как текущий go get , с теми же проблемами. Если вы хотите поэкспериментировать с API после выпуска основной версии, отличной от 0, переместите эти эксперименты в отдельный «экспериментальный» пакет с постоянным основным 0 и увеличьте основной пакет, когда вы закончите с «небольшими критическими изменениями», и, наконец, получите следующий стабильный API.

Включение второстепенных в путь импорта нарушает идеологию semver и не предоставляет никаких новых функций по сравнению с включением основных.

Хотя я понимаю, что это то, что должны делать авторы, учитывая семантику semver, я опасаюсь, что незначительные критические изменения среди второстепенных версий являются обычным и заманчивым случаем для тех, кто уже прошел версию 1. По моему неподтвержденному опыту, авторы пакетов не следовать точной семантике semver, и часто компании резервируют основные версии для маркетинговых целей. Так что мой призыв не к тому, что идеально, а к тому, возможно ли внести определенные изменения, чтобы лучше справляться с беспорядочной человеческой реальностью, которая такова.

Может быть, даже можно опционально включить минорную версию для пакетов, не подчиняющихся semver, может быть, это портит все предложение, мне нужно подумать над этим подробнее. Я не утверждаю, что это лучший способ, просто я заинтересован в дальнейшем изучении компромиссов либо при необходимости включения, либо при обязательном включении второстепенной версии в импорт.

Вероятно, здесь можно получить более качественные данные из корпуса go (и инструмента, который ищет очевидные критические изменения), чтобы определить, как часто semver чаще всего используется среди существующих популярных проектов, использующих теги semver.

Предложение vgo позволяет основным версиям корректно нарушать изменения API. Он (сам по себе) ничего не делает для их предотвращения.

Предложение vgo позволяет одной основной версии ссылаться на другую основную версию, что позволяет изящно повторно использовать код. Это не делает ничего, чтобы заставить это.

Предложение vgo MVS позволяет обновлять пакеты до более новых. Это не заставляет вас обновляться.


Вот вещи, которые мы можем создать с гораздо большей легкостью в мире vgo:

  1. Инструменты для отслеживания изменений торможения API перед отправкой на хост модуля. Каждая версия находится в zip-архиве и может быть сравнена без множества различных инструментов и команд vcs.
  2. Реестр проблем безопасности. Хостинг рядом с хостингом модулей для добавления ценности. Инструменты могут запрашивать их аналогично go list вручную или автоматически и получать уведомления о проблемах, отфильтрованных запросом.

vgo упрощает это:

  • Ограничение проблемного пространства (работа только с zip-файлами, нет необходимости хранить произвольную историю git/hg/svn для сравнения API).

    • Определение проблемного пространства (MVS, определение версии)

  • Инструментальная часть сборки.

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

Мы не должны путать то, что позволяет vgo, с тем, что vgo есть.

@ pbx0 Я не уверен, что это подходящее место для такого обсуждения, может быть, больше подходит список рассылки. В любом случае происходят критические изменения без изменения основного номера. Даже изредка. Semver ответил на этот случай в FAQ:

Как только вы поймете, что нарушили спецификацию Semantic Versioning, исправьте проблему и выпустите новую дополнительную версию, которая исправляет проблему и восстанавливает обратную совместимость.

Но я думаю, что здесь есть место для улучшения. Я полагаю, должно быть достаточно просто реализовать автоматическую проверку API (возможно, она даже уже существует), которая будет принимать все пакеты, перечисленные на godoc.org, и периодически проверять наличие новых версий, а в случае обнаружения новой версии проверять, совместима ли новая версия с предыдущей. API версии, если она использует теги semver, а мажор не изменился. Затем попробуйте связаться с автором в случае обнаружения несовместимых изменений — возможно, автоматически открывать проблемы на github или использовать электронную почту из учетной записи github. Это не охватывает все возможные случаи, но может быть очень полезно для сообщества.

Я твердо верю в использование путей для охвата основных версий и хотел выразить свою поддержку, FWIW.

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

Почти двадцать лет назад мне понадобилась VCS для моего стартапа, и я перепробовал около десяти разных. Я сразу же исключил Perforce, потому что он раскрывал ветки, используя каталоги. Таким образом, ветка v2 будет содержать тот же код, но в папке v2. Я ненавидел эту идею. Но после запуска пилотных проектов с другими девятью я обнаружил, что часто хотел иметь обе версии ветки в своей локальной файловой системе, и оказалось, что Perforce сделал это тривиально простым, тогда как другие сделали это на удивление сложным. Файловая система — это наша метафора сдерживания. Давайте использовать его.

Из предложения:

Определите схему URL-адресов для загрузки модулей Go с прокси-серверов, используемую как для установки модулей с использованием пользовательских доменных имен, так и при установке переменной среды $GOPROXY. Последний позволяет компаниям и частным лицам отправлять все запросы на загрузку модулей через прокси-сервер по соображениям безопасности, доступности или по другим причинам.

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

Проекту, использующему вендорство сегодня, требуется только инструментальная цепочка Go и Git (или другая система контроля версий). Существует только одна единственная точка отказа: репозиторий git. После проверки кода его можно собрать и перестроить без повторного подключения к сети, что является важным фактором безопасности. Для большинства из нас вендорский проект не требует дополнительной инфраструктуры — только ваш локальный компьютер и бесплатная учетная запись GitHub.

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

Другие языки позволяют использовать кэширующие прокси. Python — это тот, с которым у меня больше всего опыта, и, по моему опыту, он редко используется из-за накладных расходов на его настройку. Возможно, проект Go может сделать это проще, но если он не будет использоваться по умолчанию, мы обнаружим, что он используется реже, и доступность сборок Go в дикой природе существенно снизится. В этом отношении влияние события NPM на левой панели является отличным примером.

Если модуль и прокси-система позволяют нам проверять зависимости вместе с кодом нашего собственного проекта (аналогично сегодняшнему вендорингу, но не обязательно такой же реализацией), и реализация прокси-сервера vgo может использовать его, это решит мои проблемы. Но если это намерение, я думаю, что это должно быть отражено в предложении более полно.

@joeshaw Вы по-прежнему сможете использовать каталог поставщика для создания автономной сборки.

Из предложения:

Запретить использование каталогов поставщиков, за исключением одного ограниченного использования: каталог поставщиков в верхней части дерева файлов создаваемого модуля верхнего уровня по-прежнему применяется к сборке, чтобы по-прежнему разрешать автономные репозитории приложений. (Игнорирование каталогов других поставщиков гарантирует, что Go вернется к сборкам, в которых каждый путь импорта имеет одинаковое значение на протяжении всей сборки, и установит, что в данной сборке используется только одна копия пакета с заданным путем импорта.)

Проекту, использующему вендорство сегодня, требуется только инструментальная цепочка Go и Git (или другая система контроля версий). Существует только одна единственная точка отказа: репозиторий git.

Сегодня, если вы размещаете пакеты в своем собственном домене, вам необходимо: а) разместить git-репозиторий и б) обслуживать теги <meta> , необходимые для того, чтобы go-get мог его найти. В будущем вам нужно: а) предоставить файлы .zip и .json , необходимые vgo для извлечения кода. Кажется, что для чистого хостинга требуется меньше точек отказа и меньше инфраструктуры. Конечно, вам по-прежнему необходимо размещать репозиторий для разработки, но это не только приводит нас в худшем случае к тому же уровню, что и раньше, но и сам репозиторий также требует гораздо менее масштабируемого и надежного хостинга, поскольку он используется только людьми, которые действительно разрабатывают.

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

Если, OTOH, вы не используете импорт тщеславия, вы игнорируете всю инфраструктуру, которую github работает для вас. Так что это не похоже на сравнение яблок с яблоками: единственный способ выйти на первое место — это позволить другим людям решать сложные проблемы. Но ничто не мешает вам сделать это в будущем. AIUI Microsoft и другие компании уже вызвались выделить инженерные часы и ресурсы для выполнения этой задачи. Я ожидаю, что в будущем усилия по размещению пакетов Go будут примерно ниже ограничены усилиями по размещению пакетов npm, драгоценных камней или ящиков: у вас есть репозиторий github, а затем вы нажимаете кнопку «сделать это доступным» на каком-то централизованном управляемая служба для размещения почтовых индексов.

vgo зависит от прокси

Лично мне не нравится слово «прокси» для того, что делает необходимая инфраструктура. "Зеркало" кажется более подходящим. Зеркало может быть реализовано как прокси, но оно также может быть просто набором файлов, обслуживаемых выбранным вами веб-сервером, скрытым за cloudflare для почти бесконечной масштабируемости и времени безотказной работы.

Другие языки позволяют использовать кэширующие прокси.

Я бы сказал, что другие языки служат прекрасной моделью, объясняющей, почему это не проблема. Они, как правило, полагаются на централизованный хостинг для своих пакетов для размещения пакетов - vgo не только очень хорошо поддерживает эту модель, но и делает ее необязательной (так что вы получаете все преимущества без каких-либо недостатков) и очень проста. внедрять, масштабировать и эксплуатировать.


ИМО, если вы напрямую сравните то, что происходит до и после, и в Go, и в других языках, должно быть ясно, что есть много эквивалентов 1: 1. И единственная причина, по которой кажется , что в будущем потребуется больше усилий, заключается в том, что мы принимаем существующую инфраструктуру как должное и видим, что новой инфраструктуры еще не существует. Но я не думаю, что у нас есть веские причины сомневаться в этом.

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

Верно, но _огромное_ меньшинство пакетов использует тщеславные домены, так что я не думаю, что это сильный контраргумент. (У меня также есть другие практические проблемы с тщеславными доменами, а именно то, что их доступность, как правило, _намного хуже_, чем просто использование GitHub.)

Если, OTOH, вы не используете импорт тщеславия, вы игнорируете всю инфраструктуру, которую github работает для вас.

Да, точно! Я чувствую, что это делает мою точку зрения для меня. Вы получаете всю эту замечательную работу по инфраструктуре и поддержанию безотказной работы бесплатно или по разумной цене. Что еще более важно, это не требует вашего собственного времени.

Если GitHub в конечном итоге запустит vgo совместимое зеркало, то, возможно, это не будет проблемой, хотя мне нравится элегантность одной Git-выборки — атомарного действия с точки зрения пользователя — содержащего весь код. Мне нужно построить проект.

Я бы сказал, что другие языки служат прекрасной моделью, объясняющей, почему это не проблема. Они, как правило, полагаются на централизованный хостинг своих пакетов для размещения пакетов — vgo не только чрезвычайно хорошо поддерживает эту модель, но и делает ее необязательной (так что вы получаете все преимущества без каких-либо недостатков) и очень прост в реализации, масштабировании и работать.

Проблема в том, что это добавляет единые точки отказа (SPOF) в построение проекта. Код будет жить в VCS, несмотря ни на что (и, вероятно, на GitHub), так что это один SPOF. На других языках централизованный репозиторий — это второй SPOF. Для Go каждый путь импорта является дополнительным SPOF (github.com, golang.org, honnef.co, rsc.io и т. д.), и увеличение числа SPOF снижает общую доступность.

Запуск зеркала, конечно, может сократить это число до двух, но я утверждаю, что это инфраструктура, которая не должна существовать. Продажа ваших отпечатков (или наличие локального зеркала на диске) сводит их к одному: к вашей системе контроля версий.

В любом случае, это может быть спорным моментом. Первоначально я не понял часть предложения о каталоге верхнего уровня vendor , который, казалось бы, решит мои основные проблемы — спасибо, что указали на это, @kardianos — хотя это полный разрыв со старым Система продаж может быть лучше.

Я рад, что «верхний уровень vendor » по-прежнему будет поддерживаемой конфигурацией, потому что я так люблю git grep .

Запуск зеркала, конечно, может сократить это число до двух, но я утверждаю, что это инфраструктура, которая не должна существовать.

Корпоративный разработчик здесь. Возможно, мы не являемся целевой аудиторией, но мы хотели бы использовать Go. Я не вижу, чтобы это произошло, если у нас нет зеркала внутри нашего предприятия, как мы делаем для java и javascript, чтобы гарантировать, что все, что мы создаем сегодня, может быть построено завтра.

Корпоративный разработчик здесь. Возможно, мы не являемся целевой аудиторией, но мы хотели бы использовать Go. Я не вижу, чтобы это произошло, если у нас нет зеркала внутри нашего предприятия, как мы делаем для java и javascript, чтобы гарантировать, что все, что мы создаем сегодня, может быть построено завтра.

@jamiethermo Разве вендор не решает эту проблему для вас сегодня?

Поддержка прокси или зеркал — это хорошо, и если это поможет внедрению Go, я только за. Меня беспокоили зеркала как замена локальным автономным деревьям исходного кода (то, что мы сегодня называем вендорством).

@джоешо

Разве вендор не решает эту проблему для вас сегодня?

Что ж, я должен признаться в невежестве и некотором разочаровании в том, «как мне организовать свой код». Под «автономным исходным деревом» вы имеете в виду, что у меня есть гигантский репозиторий git, который содержит весь мой код, а также весь код в дереве поставщиков? Значит, мне не нужно зеркало, потому что я проверил весь этот код в своем репозитории?

Что касается того, «как мне организовать свой код», на этой странице How to Write Go Code рассказывается о структуре каталогов, но не упоминается поставщик.

Используйте семантическое управление версиями импорта, при котором каждая основная версия имеет отдельный путь импорта. В частности, путь импорта содержит путь к модулю, номер версии и путь к определенному пакету внутри модуля. Если основной версией является v0 или v1 , то элемент номера версии должен быть опущен; в противном случае он должен быть включен.

Пакеты, импортированные как my/thing/sub/pkg , my/thing/v2/sub/pkg и my/thing/v3/sub/pkg, происходят из основных версий v1 , v2 и v3 модуля my/thing, но сборка рассматривает их просто как три разных пакета.

my/thing/sub/pkg также может быть v0.

Я следил за туром . Пример построен вне дерева GOPATH, и он работает, тогда как dep init в этой ситуации не работает. Сейчас я работаю, по-моему, с 80 командами, и было бы очень здорово не иметь одного гигантского дерева. (Пока я печатал это, кто-то подошел со своим ноутбуком и хмурым лицом и сказал: «У меня действительно странная ошибка...»)

@джоешо

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

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

Таким образом, ваше беспокойство будет рассмотрено в том, что я считаю наиболее вероятным сценарием: что финансируемая организация (в настоящее время Microsoft готовится стать таковой) занимается размещением zip-файлов.

хотя мне нравится элегантность одной Git-выборки — атомарного действия с точки зрения пользователя.

vgo get — это такое же атомарное действие, и оно выполняет меньше работы, той же природы (запросы HTTP), которые легче понять.

Проблема в том, что это добавляет единые точки отказа (SPOF) в построение проекта.

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

На других языках централизованный репозиторий — это второй SPOF. Для Go каждый путь импорта является дополнительным SPOF (github.com, golang.org, honnef.co, rsc.io и т. д.), и увеличение числа SPOF снижает общую доступность.

Я думаю, что это слишком упрощенно. Если вы размещаете свой код на зеркале, которое выходит из строя, вы все еще можете разрабатывать (github все еще работает), и пользователи могут по-прежнему иметь возможность устанавливать (используя другое зеркало). Хост одной из ваших зависимостей, которые выходят из строя, не имеет значения, поскольку вы отражаете свои зависимости. Если вы не доверяете «централизованному» управляемому сообществом зеркалу, вы можете запустить свое собственное или заплатить кому-то за это, без разницы для пользователей, что дает вам полный контроль над тем, насколько на вас влияет время простоя сервера. централизованное репо.

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

И FTR, прямо сейчас ваш git-хостинг является SPOF: если ваш git-хост не работает, пользователи не могут устанавливать, а вы не можете разрабатывать.

Запуск зеркала, конечно, может сократить это число до двух, но я утверждаю, что это инфраструктура, которая не должна существовать.

И моя (плохо сформулированная) точка зрения выше заключалась в том, что это уже происходит :) Вы просто а) игнорируете, что это происходит прямо сейчас, и б) предполагаете, что этого не произойдет в будущем :)

Чтобы дать другую точку зрения:

  • мы создаем много проектов Go с помощью нашего общесистемного менеджера программных компонентов для разных языков (rpm/dnf в Fedora, Centos и RHEL)
  • это позволяет нам использовать те же приемы, что и предложение vgo, играя с пространством имен компонентов слоя rpm (как правило, переименовывая проект на уровне пространства имен rpm из project в compat-project-x, чтобы можно было различать несовместимые версии тот же путь импорта, точно так же, как vgo).
  • эти приемы определенно полезны, помогая создавать сложные проекты Go.
  • хотя это не так полно и надежно, как на уровне языка
  • мы бы предпочли передать ограничения языка в rpm/dnf, чем добавить наложение ограничений rpm/dnf поверх исходного кода.
  • нам надоели все обходные пути файловой системы, необходимые в настоящее время, чтобы убедить инструменты Go смотреть на исходники проекта Go. Физический GOPATH вообще не будет упущен.

Поэтому мы в восторге от vgo и надеемся, что он скоро будет развернут (нам он был нужен много лет назад).

При этом наше использование vgo-подобных рабочих процессов выявило следующие трудности.

Предложение vgo поздравляет себя с тем, что сделало make-файлы ненужными. Это не совсем так.

  • многие Go-проекты влюбились в автоматически сгенерированные go-файлы, и в go нет стандартного способа потребовать их регенерации или выразить то, что нужно для успешной генерации.
  • это так плохо, что многие проекты должны поставляться с предварительно сгенерированными файлами (иногда составляя полные отдельные репозитории с предварительно сгенерированными файлами)
  • эти файлы являются огромным источником несовместимости версий. Люди заботятся о написании кода, который не нужно будет менять каждый день при появлении новых версий зависимостей. Автоматически сгенерированные файлы OTOH часто тесно связаны с точной средой генерации, поскольку авторы инструмента-генератора предполагают, что вы просто будете регенерировать их по мере необходимости.
  • для того, чтобы vgo был успешным, ему нужен способ идентифицировать эти файлы, отделить их от модулей .zip и рассказать, как их восстановить пользователям модулей .zip.

Это усугубляется текущим правилом «все должно быть в GOPATH».

  • все не может быть в GOPATH когда генерация зависит от proto файлов опубликованных вне GOPATH многоязычными проектами
  • набор инструментов Go должен научиться читать ресурсы за пределами своего GOPATH
  • набор инструментов Go должен научиться публиковать ресурсы вне GOPATH, когда они доступны для проектов, не обязательно написанных на Go.
  • текущий обходной путь дублирования ресурсов в копиях с помощью GOPATH является еще одним источником несовместимости версий.
  • все не будут копировать одни и те же файлы одновременно
  • иногда проекты копируют из нескольких источников, создавая уникальные миксы.
  • каждый проект будет проверять качество своей собственной копии, что делает композицию проекта Go опасной
  • решатель версий vgo не будет работать должным образом, если он вычисляет взаимосвязи между выпусками кода, но игнорирует взаимосвязи между выпусками ресурсов.
  • vgo необходимо сделать ненужными личные копии вещей, публикуемых вне GOPATH, чтобы избежать взрыва несовместимых версий модулей.

Многие проекты использовали правило «каждый каталог Go является отдельным пакетом» для публикации проектов с несовместимым или полностью неработающим кодом в отдельных подкаталогах.

  • многие другие проекты Go использовали то же правило для выбора конкретных подкаталогов и использования их в контексте, несовместимом с исходными модульными тестами проекта и QA.
  • который «работает» и создает «воспроизводимые сборки» до тех пор, пока никакие изменения в исходном проекте или в проекте-потребителе не используют какую-либо другую часть исходного проекта. Когда это происходит, весь замок из песка рушится под накопившимся техническим долгом,
  • вы видите, что проекты отказываются обновляться до более новых версий проектов, потому что это требует очистки их предыдущего неправильного использования других проектов.
  • у вас странная шизофрения, когда проекты Go считают себя не ответственными за ошибки в кодовых базах, которые они повторно используют, и в то же время отказываются применять исправления, опубликованные теми же самыми кодовыми базами (я думаю, мы все люди, и неприятное отрицание реальности запрограммировано в мозгу человека)
  • исправления не распространяются, и все «в порядке», пока вы не столкнетесь с ошибками, которые требовали исправлений в первую очередь, или модульными тестами, которые были признаны недействительными в результате выбора вишни.
  • автоматическая проверка безопасности, которая сравнивает состояние безопасности проектов с состоянием безопасности тех же проектов в каталогах поставщиков, имела бы полевой день
  • чем больше проект, тем больше вероятность того, что в его вендорах будут спрятаны такие бомбы замедленного действия.
  • четко определяя границы проекта внутри zip-модулей, vgo положит конец такой практике.
  • однако это также повлечет за собой серьезную очистку многих кодовых баз Go.
  • чтобы vgo был успешным, он должен предоставить инструменты, помогающие рефакторингу существующих проектов Go и разделению их кодовой базы на модули, которые имеют смысл с точки зрения совместимости программного обеспечения. В противном случае проекты, использующие vgo, либо создадут непримиримые ограничения, либо просто зафиксируют статус-кво (что работает для существующего кода, но ужасно с точки зрения эволюции кода).

Нынешняя практика представления всей кодовой базы Go в одном дереве GOPATH с небольшими ограничениями между проектами привела к пагубным побочным эффектам от POW разработки программного обеспечения.

  • код фиксируется не в проекте, где это технически целесообразно, а в наиболее удобном для автора кода репозитории (репозитории, к которому у него есть доступ)
  • Go-проекты накладываются друг на друга, части одного проекта зависят от частей других проектов, а часть этого другого проекта зависит от исходного проекта.
  • который эффективно создает заблокированные графы ограничения версии, где вы не можете переместить одну часть, не переместив все остальные
  • ни у кого нет ресурсов, чтобы изменить все остальные за одну операцию
  • проекты зашли в тупик и остановились
  • использование модулей с четкими границами и попытка сделать явными межмодульные ограничения версий выявят эти ситуации.
  • это будет массово непопулярным (хотя проблема существует сегодня, скрытая под завесой вендинга)
  • довольно часто дело не только в отделении подкаталога: зависимости проблемного проекта могут возникать в дереве каталогов A/B/C/D на уровне A и D, но не на уровне B и C.
  • чтобы vgo был успешным, он должен предоставлять инструменты, помогающие рефакторингу существующих проектов Go и разделению их кодовых баз на отдельные модули, которые следуют линиям графика зависимостей.

Testfing/fixtures, example и testdata — это совсем другие черви, со своими собственными зависимостями и потребностями в версиях зависимостей.

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

Я, наверное, еще много чего забыл, но это самое важное.

Наконец:

  • Проекты Go не живут изолированно
  • некоторые проекты Go публикуют коннекторы для других языков
  • некоторые проекты на других языках публикуют коннекторы Go
  • это делает проблему обращения с ними по-другому, чем с этими другими языками.
  • у вас не может быть ничего, кроме обновления части Go до последней второстепенной версии при выпуске многоязычного проекта.
  • это был бы ад от военнопленного оперативного управления.
  • автоматическое обновление до последнего подвыпуска играет огромную роль в упрощении графиков ограничений программного обеспечения, заставляя всех очищать старые версии (преимущество — техническое, механизм — социальный).
  • Высокоточные перестройки аналогичны пиксельным веб-сайтам. Они кажутся очевидно хорошей идеей, они вознаграждают оригинальное эго автора, но они являются PITA для всех, кто действительно пытается использовать результат, потому что они не поддаются развитию и адаптации к местному (не исходному) контексту.

На прокси-серверах:

для простоты отладки $GOPROXY может быть даже URL-адресом file:///, указывающим на локальное дерево.

Пожалуйста, заставьте его работать с файлом:/// https:///URL, указывающим на каталог, содержащий сторонние модули в формате zip (и исключите все остальное)

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

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

@Merovius Я не согласен, но я думаю, что мы отклоняемся от темы и не хотим увязнуть в обсуждении проблемы. Однако я с удовольствием продолжу в другой среде. (Моя электронная почта находится в моем профиле на github, и я joeshow в слаке Gophers.)

https://github.com/golang/go/issues/24301#issuecomment -374882685, @tpng :

Какой часовой пояс используется для отметки времени в псевдоверсии (v0.0.0-yyyymmddhhmmss-commit)?

Как вы отметили в своем редактировании, UTC. Но обратите внимание также, что вам никогда не придется вводить их. Вы можете просто ввести хэш (префикс) коммита git, и vgo вычислит и заменит правильную псевдоверсию.

https://github.com/golang/go/issues/24301#issuecomment -374907338, @AlexRouSg :

Будете ли вы решать C-зависимости?

https://github.com/golang/go/issues/24301#issuecomment -376606788, @stevvooe :

что произойдет с ресурсами, отличными от Go, такими как protobufs или c-файлы?

https://github.com/golang/go/issues/24301#issuecomment -377186949, @ним-ним:

Предложение vgo поздравляет себя с тем, что сделало make-файлы ненужными. Это не совсем так. [Обсуждение сгенерированного кода.]

Разработка, не связанная с Go, по-прежнему не является целью команды go , поэтому не будет поддержки управления библиотеками C и т. п., а также не будет явной поддержки протокольных буферов.

Тем не менее, мы, конечно же, понимаем, что использование буферов протоколов с Go слишком сложно, и мы хотели бы, чтобы это рассматривалось отдельно.

Что касается сгенерированного кода в более общем плане, то ответом является настоящая кросс-языковая система сборки, особенно потому, что мы не хотим, чтобы у каждого пользователя были установлены правильные генераторы. Автору лучше запустить генераторы и проверить результат.

https://github.com/golang/go/issues/24301#issuecomment -375248753, @mrkanister :

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

Как отметили @AlexRouSg и, возможно, другие, вы можете это сделать. Я просто хотел подтвердить их ответы. Я также добавлю это в FAQ.

https://github.com/golang/go/issues/24301#issuecomment -375989173, @aarondl :

Хотя это работает сейчас, это предназначено?

Абсолютно да.

@jamiethermo , большое спасибо за комментарий о Perforce и ветках в разных каталогах. Я забыл об этой функции, но, возможно, именно это убедило меня в том, что важно разрешить vgo.

На https://github.com/golang/go/issues/24301#issuecomment -376925845 началась приятная дискуссия о вендорстве и прокси. Здесь явно есть два разных набора проблем.

Как писал @joeshaw , разработчики с открытым исходным кодом стараются не полагаться на инфраструктуру, поэтому им нужен вендор. Чтобы подтвердить, мы сохраним эту работу в ограниченной форме (только каталог поставщика на верхнем уровне общего целевого модуля, где вы запускаете команды go).

Для корпоративных разработчиков не проблема полагаться на инфраструктуру — это просто еще одна статья расходов, особенно если это приводит к значительному сокращению затрат, например, отказу от дублирования всего кода поставщика в каждом репозитории и необходимости тратить время на синхронизацию всего этого. По сути, каждая компания, с которой мы разговаривали, хочет иметь прокси/зеркала, а не продавать, как просил @jamiethermo . Мы также позаботимся о том, чтобы это работало.

Мы также очень хотим создать общую зеркальную сеть, которой у разработчиков есть основания доверять и на которую можно положиться, чтобы все разработчики с открытым исходным кодом не чувствовали себя обязанными поставщиками. Но это позже. Сначала vgo должен стать go.

https://github.com/golang/go/issues/24301#issuecomment -377220411, @ним-ним:

Пожалуйста, заставьте его работать с файлом:/// https:///URL, указывающим на каталог, содержащий сторонние модули в формате zip (и исключите все остальное)

Я не совсем уверен, о чем вы просите, говоря «исключить все остальное». Если $GOPROXY установлен, vgo запрашивает этот прокси. Он никогда не возвращается ни к чему другому. Этот прокси может обслуживаться статическим файловым деревом, которое в основном представляет собой сторонние модули в формате zip. Дерево файлов также должно содержать некоторые другие файлы метаданных для навигации и поиска. Эти дополнительные файлы неизбежны, поскольку HTTP не дает нам стандартного способа делать такие вещи, как списки каталогов.

https://github.com/golang/go/issues/24301#issuecomment -377186949, @ним-ним:

Вау, это длинный комментарий. Я думаю, что согласен с большей частью того, что вы написали. Я хочу ответить на последний пункт в вашем посте:

  • Высокоточные перестройки аналогичны пиксельным веб-сайтам. Они кажутся очевидно хорошей идеей, они вознаграждают оригинальное эго автора, но они являются PITA для всех, кто действительно пытается использовать результат, потому что они не поддаются развитию и адаптации к местному (не исходному) контексту.

Думаю, я бы сказал, что файлы блокировки похожи на идеальные по пикселям веб-сайты. Напротив, сборки с высокой точностью изящно деградируют при изменении контекста. По умолчанию сборка будет использовать, скажем, B 1.2 и C 1.4. Но тогда, если это часть более крупной сборки, для которой требуется B 1.3, хорошо, она будет работать с B 1.3, но сохранит C 1.4 (даже если существуют более новые версии) при отсутствии конкретных требований для обновления. Таким образом, действительно высококачественные сборки — это лучшее из обоих миров: верность оригиналу, насколько это возможно, но не настаивание на идеальном пикселе, когда это невозможно.

https://github.com/golang/go/issues/24301#issuecomment-375415904 , @flibustenet :

@rsc Я хотел бы попросить вас быть более точным в отношении дорожной карты и того, что мы должны делать сейчас.
Будет ли он следовать политике Go и замораживать функции vgo через 3 месяца (сейчас 2)?

Vgo является прототипом и никогда не будет выпущен сам по себе. Он не подлежит заморозке или чему-либо еще. Но это предложение состоит в том, чтобы перенести идеи и большую часть кода в основной cmd/go. В рамках релиза cmd/go, безусловно, подлежит заморозке. Поскольку это опцион и поскольку код, специфичный для vgo, довольно хорошо изолирован от остальной части операции команды go, работа над частями, специфичными для vgo, сопряжена с довольно низким риском, и я мог предположить, что некоторые из них будут продолжаться в течение пары недель. в заморозку. Сейчас я сосредоточен на обсуждении предложения и корректировках. Как только предложение окажется в хорошей форме без существенных проблем, мы перейдем к перемещению кода в cmd/go.

Должны ли мы теперь следовать паломнической палочке, прося каждого сопровождающего libs добавить файл go.mod, или мы должны дождаться официального принятия предложения (чтобы быть уверенными, что имя и синтаксис не изменятся)?

Я думаю, что синтаксис go.mod, скорее всего, изменится (смотрите этот выпуск). Но, как я отметил в предложении, мы продолжим принимать старые синтаксисы навсегда, а vgo просто обновит существующие файлы, так что это не проблема. Тем не менее, я бы не стал пытаться отправлять PR во все библиотеки, которые вы можете найти, пока код не попадет в разрабатываемую копию cmd/go.

https://github.com/golang/go/issues/24301#issuecomment -376640804, @pbx0 :

Легко ли (сегодня) с vgo определить, есть ли у вас более 1 версии пакета в сборке?

Сегодня проще всего собрать бинарный файл, а затем запустить на нем goversion -m (см. https://research.swtch.com/vgo-repro). Когда у нас есть более общий список перехода с поддержкой модулей, он должен иметь возможность делать то же самое без предварительного создания двоичного файла.

https://github.com/golang/go/issues/24301#issuecomment -376236546, @buro9 :

[Могу ли я внести несовместимое с предыдущими версиями изменение безопасности, например, microcosm-cc/ bluemonday@a5d7ef6? ]

Как сказал @Merovius , если мы собираемся принять рекомендации по совместимости Go 1, тогда изменения безопасности явно разрешены без изменения основной версии.

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

Например, не удаляйте функцию. Вместо этого сделайте функцию panic или log.Fatal только в случае неправильного вызова.

В этом случае вместо удаления AllowDocType я бы сохранил его и, конечно же, продолжал принимать AllowDocType(false), так как это безопасный параметр. Если бы кто-то написал оболочку для вашей библиотеки, возможно, в виде программы командной строки с флагом -allowdoctype, то, по крайней мере, использование программы без этого флага продолжало бы работать.

Кроме того, похоже, проблема заключалась в том, что тип документа был полностью непроверен, но я бы, вероятно, провел минимальную проверку, чтобы поддерживать работу наиболее распространенных применений, а затем консервативно отклонил другие. Например, по крайней мере, я бы продолжал разрешать и, возможно, также удосужился разрешить ..> со строками в кавычках без символов &#<>\.

https://github.com/golang/go/issues/24301#issuecomment -375090551, @TocarIP :

[Опасения по поводу несвоевременного получения обновлений.]

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

То, что @Merovius написал в https://github.com/golang/go/issues/24301#issuecomment -375992900, звучит совершенно правильно для меня. Ключевым моментом является то, что вы получаете обновления только тогда, когда запрашиваете их, поэтому вещи (потенциально) ломаются только тогда, когда вы ожидаете этого и готовы к тестированию, отладке и т. д. Вы должны запрашивать их, но не намного чаще, чем в других системах с файлами блокировки. И мы также хотим упростить появление предупреждений типа «вы собираете устаревшую/небезопасную версию». Но важно не просто обновлять без вывода сообщений как побочный эффект операций без обновления.

Также добавлено в FAQ.

Спасибо всем за отличную дискуссию и за ответы на вопросы друг друга. Действительно отличные ответы от многих людей, но особая благодарность @Merovius и @kardianos. Я обновил FAQ https://github.com/golang/go/issues/24301#issuecomment -371228664 и резюме обсуждения https://github.com/golang/go/issues/24301#issuecomment -371228742. Есть три важных вопроса, на которые пока нет ответа (в резюме написано TODO), над которыми я буду работать дальше. :-)

@rsc #24057 обсуждает использование tar вместо zip.

https://github.com/golang/go/issues/24301#issuecomment -375106068, @leonklingele :

Если поддержка go get в том виде, в каком мы ее знаем сегодня, будет объявлена ​​устаревшей и в конечном итоге удалена, как тогда рекомендуется получать и устанавливать (без тегов) бинарные файлы Go?

Это все еще будет идти получить. Если репозиторий бинарника не помечен, go get будет использовать последнюю фиксацию. Но на самом деле людей, публикующих двоичные файлы, следует поощрять помечать содержащие репозитории так же, как репозитории, содержащие библиотеки (или смесь).

Если $GOPATH устарел, куда будут установлены эти двоичные файлы?

Вам больше не нужно работать в $GOPATH, но код по-прежнему записывается в первый каталог, указанный в $GOPATH — это исходный кеш, см. $GOPATH/src/v после использования vgo. Двоичные файлы устанавливаются в $GOPATH/bin. По состоянию на несколько выпусков назад вам не нужно устанавливать $GOPATH — по умолчанию используется $HOME/go. Итак, что должно произойти, так это то, что разработчики перестанут беспокоиться о настройке $GOPATH или даже о том, что это такое, и просто узнают, что их двоичные файлы находятся в $HOME/go/bin. Они могут использовать $GOBIN, чтобы переопределить это местоположение.

@dsnet , спасибо, я добавил ссылку в сводку обсуждения. Давайте продолжим это обсуждение там.

Если $GOPROXY установлен, vgo запрашивает этот прокси. Он никогда не возвращается ни к чему другому. Этот прокси может обслуживаться статическим файловым деревом, которое в основном представляет собой сторонние модули в формате zip. Дерево файлов также должно содержать некоторые другие файлы метаданных для навигации и поиска. Эти дополнительные файлы неизбежны, поскольку HTTP не дает нам стандартного способа делать такие вещи, как списки каталогов.

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

Хотя ограничения листинга не применяются к файлам, а такие утилиты, как lftp, уже давно могут отображать каталоги http (не имеет значения, если это нестандартно, если оно работает на основных http-серверах). Таким образом, операция без индекса, вероятно, возможна и предпочтительна для небольших организаций, которые не хотят инвестировать в инфраструктуру. yum/dnf/zipper также полагаются на настраиваемые индексы, и индексирование общего каталога не всегда так просто, как вы думаете в некоторых организациях.

Разработчики с открытым исходным кодом, как правило, не хотят полагаться на инфраструктуру, поэтому им нужен вендор, как написал @joeshaw.

Не совсем так, разработчики с открытым исходным кодом в основном хотят, чтобы весь процесс был открытым и прозрачным, и чтобы не приходилось полагаться на чьи-то добрые пожелания. Таким образом, инфра прекрасно работает, если она сама по себе имеет открытый исходный код и проста и дешева в локальном развертывании. Использование огромных проприетарных сайтов, таких как github, явно не попадает в эту категорию, но это не то же самое, что ниже. Люди с открытым исходным кодом сделали зеркала на десятилетия раньше всех остальных. Чего они не примут, так это закрытости и дороговизны настройки зеркал (в терминах open source дороговизна измеряется человеческим временем)

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

Разработчики предприятий могут без проблем полагаться на инфраструктуру — это просто дополнительные расходы

Должно быть, очень приятно работать в Google :(. За исключением нескольких предприятий с существующей крупной операцией Go, где инвестировать в инфраструктуру Go не составляет труда, всем остальным придется пройти долгий и утомительный процесс утверждения. , хотя бы для того, чтобы оправдать оплату того, кто проанализирует проблему. Таким образом, любые инфра-затраты уменьшат охват Go и предотвратят его принятие новыми структурами.

Entreprise похожи на разработчиков открытого кода, они заботятся о дешевизне и простоте. Раньше они вообще не заботились об открытости, но теперь это положение постепенно меняется, когда они понимают, что это коррелирует с дешевизной (к ужасу традиционных поставщиков Enterprise, которые раньше специализировались на дорогих решениях типа «черный ящик» с дорогостоящим консалтингом для помощи в развертывании).

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

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

Просто опубликуйте где-нибудь эталонную копию индексированного каталога, содержащего модули. Забудьте о любых прокси-подобных настройках, которые требуют определенной конфигурации веб-сервера. Это то, что делают разработчики с открытым исходным кодом, и у них нет проблем с зеркалированием. Поскольку зеркалирование — это просто копирование содержимого каталога и не требует конкретной конфигурации веб-сервера, существует множество организаций, готовых зеркалировать.

Что касается сгенерированного кода в более общем плане, то реальная система кросс-языковой сборки является ответом,

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

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

в частности, потому что мы не хотим, чтобы у каждого пользователя были установлены правильные генераторы. Автору лучше запустить генераторы и проверить результат.

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

Так что vgo рано или поздно придется заняться регенерацией. Позднее означает ожидание, пока проекты обнаружат, что обновления vgo опасны при наличии сгенерированного кода.

https://github.com/golang/go/issues/24301#issuecomment -374791885, @jimmyfrasche :

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

Да, проблема кода, который предполагает, что «в программе будет только один из них», реальна, и нам всем придется работать над этим, чтобы установить новые (лучшие) лучшие практики и соглашения. Я не думаю, что эта проблема привнесена vgo, и vgo, возможно, улучшает ситуацию, чем раньше.

Я понимаю, что некоторые люди утверждают, что vgo должен принять правило Депа о том, что не может быть даже 1.x и 2.x вместе, но это явно не масштабируется для больших кодовых баз, на которые мы ориентируемся с Go. Невозможно ожидать, что целые большие программы будут сразу переходить с одного API на другой, как показано в сообщении vgo-import . Я считаю, что практически все другие менеджеры пакетов позволяют использовать 1.x и 2.x вместе по той же причине. Конечно, у Cargo есть.

В целом vgo уменьшает дублирование по сравнению с вендорами. С вендором легко получить версии 1.2, 1.3 и 1.4 данного пакета в одном двоичном файле, даже не осознавая этого, или, может быть, даже три копии 1.2. По крайней мере, vgo урезает возможное дублирование до одного 1.x, одного 2.x и так далее.

Дело уже в том, что авторам разных пакетов нужно убедиться, что они не пытаются зарегистрировать одно и то же. Например, expvar делает http.Handle("/debug/vars") и, по сути, делает ставку на этот путь. Надеюсь, мы все согласны с тем, что сторонний пакет, такой как awesome.io/supervars, не должен пытаться зарегистрировать тот же путь. Это оставляет конфликты между несколькими версиями одного пакета.

Если мы добавим expvar/v2, то это будет второй, другой пакет, как и awesome.io/supervars, и он может конфликтовать с expvar в большой сборке. Однако, в отличие от суперваров, expvar/v2 принадлежит тому же человеку или команде, что и expvar, поэтому два пакета могут координировать свою регистрацию. Это будет работать следующим образом. Предположим, что expvar v1.5.0 является последним перед тем, как мы решим написать v2, поэтому в v1.5.0 есть http.Handle. Мы хотим, чтобы версия 2 заменила версию 1, поэтому мы переместим http.Handle в версию 2.0.0 и добавим в версию 2 API, который позволит версии 1 переадресовывать вызовы версии 2. Затем мы создадим версию 1.6.0, реализующую эту переадресацию. v1.6.0 не вызывает http.Handle; он делегирует это v2.0.0. Теперь expvar v1.6.0 и expvar/v2 могут сосуществовать, потому что мы так и планировали. Остается только одна проблема: что произойдет, если в сборке используется expvar v1.5.0 с expvar/v2? Мы должны убедиться, что этого не произойдет. Мы делаем это, заставляя expvar/v2 требовать expvar в версии 1.6.0 (или более поздней), хотя в этом направлении нет импорта, и, конечно, expvar версии 1.6.0 также требует expvar/v2 в версии 2.0.0 или более поздней для вызова своих API. . Этот цикл требований позволяет нам гарантировать, что версии 1.5.0 и версии 2 никогда не будут смешаны. Именно благодаря планированию такого рода координации между основными версиями выбор минимальной версии допускает циклы в графе требований.

Правило «только одна основная версия» в сочетании с разрешением циклов в графе требований дает авторам инструменты, необходимые им для управления надлежащей координацией синглетонов (и переносом прав собственности на синглтоны) между различными основными версиями своих модулей. Мы не можем устранить проблему, но мы можем дать авторам инструменты, необходимые для ее решения.

Я знаю, что протокольные буферы, в частности, имеют проблемы с регистрацией, и эти проблемы усугубляются тем, что файлы протоколов .pb.go передаются и копируются в проекты очень нестандартно. Это снова то, что в основном не зависит от vgo. Мы должны исправить это, но, возможно, изменив способ использования буферов протокола Go, а не vgo.

https://github.com/golang/go/issues/24301#issuecomment -374739116, @ChrisHines :

Я больше всего обеспокоен тем, что путь миграции между миром до vgo и миром vgo идет плохо. [Подробнее]

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

Переход от старой системы go get и бесчисленных инструментов для поставщиков к новой модульной системе должен пройти невероятно гладко. В последнее время я много думал о том, как именно это будет работать.

Первоначальное предложение позволяет разработчикам размещать версию 2 модуля в подкаталоге репозитория с именем v2/. Использование этого параметра позволит разработчикам создать репозиторий, который использует семантическое управление версиями импорта, совместим с модулями, а также обратно совместим со старым «иди и получай». В сообщении, описывающем эту опцию, признается, что подавляющее большинство проектов не захотят использовать эту опцию, и это нормально. Это необходимо только для совместимости, если проект уже находится на версии v2 или новее. В то же время я недооценил количество широко используемых крупных проектов версии 2 или более поздней. Например:

  • github.com/godbus/dbus версии 4.1.0 (импортировано 462 пакетами).
  • github.com/coreos/etcd/clientv3 имеет версию 3.3.3 (импортировано 799 пакетами).
  • k8s.io/client-go/kubernetes имеет версию 6.0.0 (импортирована пакетами 1928).

Чтобы избежать поломки своих клиентов, эти проекты должны были бы перемещаться в подкаталог до тех пор, пока не будет считаться, что все клиенты будут использовать модули, а затем вернуться в корень. Это много, чтобы спросить.

Еще один вариант подшутить над подмодулями git. Старая команда go get предпочитает тег или ветку с именем «go1», а не ветку репозитория по умолчанию, поэтому проект, который хотел обеспечить плавный переход, мог создать фиксацию в ветке «go1», в которой был настроен только подкаталог «v2». как подмодуль git, указывающий на реальный корень репо. Когда «go get» проверил эту ветку go1 и заполнил подмодули, он получил правильное расположение файлового дерева. Однако это ужасно, и указатели подмодулей нужно будет обновлять каждый раз, когда выпускается новый выпуск.

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

Но это единственные способы, которые я могу придумать, чтобы оставить немодифицированным, старым начать работать, когда мы переходим в мир модулей. Если это не так, то альтернативой является изменение старого go get, что на самом деле означает изменение старого go build.

По сути, существует два различных соглашения о путях импорта: старое, без основных версий, и новое, с основными версиями версии v2 или более поздней. Код в старом дереве, вероятно, использует старое соглашение, а код в новом дереве — в каталоге, содержащем файл go.mod — вероятно, использует новое соглашение. Нам нужен способ сделать так, чтобы два соглашения перекрывались во время перехода. Если мы немного научим старую часть работе с семантическим импортом версий, то сможем значительно увеличить количество перекрытий.


Предлагаемое изменение: определить «новый» код как код с файлом go.mod в том же каталоге или родительском каталоге. Старый go get должен продолжать загружать код точно так же, как и всегда. Я предлагаю, чтобы шаг «go build» отрегулировал обработку импорта в «новом» коде. В частности, если импорт в новом коде говорит x/y/v2/z, но x/y/v2/z не существует, а x/y/go.mod говорит «модуль x/y/v2», тогда go build будет читать вместо этого импортируйте как x/y/z. Мы хотели бы выпустить это обновление в качестве точечного выпуска для Go 1.9 и Go 1.10.

Обновление : скопировано в #25069.


Это изменение должно позволить пакетам, не поддерживающим модули, использовать более новые версии пакетов, поддерживающих модули, независимо от того, выбирают ли эти пакеты подход «основная ветвь» или «основной подкаталог» для структурирования своих репозиториев. Их больше не будут принуждать к подходу с подкаталогами, но это все равно будет рабочим вариантом. И разработчики, использующие более старые версии Go, по-прежнему смогут создавать код (по крайней мере, после обновления до версии Point).

@rsc Я пытался выяснить, как мы могли бы заставить работать переход на vgo, я пришел к тем же выводам, которые вы изложили в своем ответе, и ваше предложение соответствует лучшему подходу, который я придумал. самостоятельно. Мне нравится предложенное вами изменение.

https://github.com/golang/go/issues/24301#issuecomment -377527249, @rsc :

Затем мы создадим версию 1.6.0, реализующую эту переадресацию. v1.6.0 не вызывает http.Handle; он делегирует это v2.0.0. Теперь expvar v1.6.0 и expvar/v2 могут сосуществовать, потому что мы так и планировали.

Это звучит проще, чем есть на самом деле. В действительности, в большинстве случаев, это означает, что v1.6.0 должен быть полностью переписанным v1 в форме v2-обертки _ (перенаправленный вызов http.Handle приведет к регистрации другого обработчика — одного из v2 — что, в свою очередь, означает все связанные код тоже должен быть из v2, чтобы корректно взаимодействовать с зарегистрированным хэндером)_.

Скорее всего, это изменит тонкие детали поведения v1, особенно со временем, по мере развития v2. Даже если мы сможем компенсировать эти незначительные изменения в деталях и достаточно хорошо эмулировать v1 в v1.6.x - тем не менее, это требует много дополнительной работы и, скорее всего, сделает поддержку ветки v1 в будущем (я имею в виду преемников v1.5.0). здесь) бессмысленно.

@powerman , я абсолютно не говорю, что это тривиально. И вам нужно координировать свои действия только в том случае, если v1 и v2 борются за какой-то общий ресурс, такой как http-регистрация. Но разработчикам, участвующим в этой экосистеме пакетов, абсолютно необходимо понимать, что v1 и v2 их пакетов должны сосуществовать в больших программах. Многие пакеты не нуждаются в доработке — например, yaml и blackfriday находятся в версии 2 и полностью отличаются от версии 1, но в них нет общего состояния, за которое нужно бороться, поэтому нет необходимости в явной координации, но другие будут.

@силовик @rsc
Я разрабатываю пакет с графическим интерфейсом, что означает, что у меня не может быть даже 2+ экземпляров из-за использования «основного» потока. Итак, исходя из наихудшего сценария синглтона, это то, что я решил сделать.

  • Иметь только выпуск v0/v1, поэтому невозможно импортировать версии 2+.

  • Имейте общедоступный код в своей собственной папке версии API, например, v1/v2, предполагая, что vgo позволяет это, или, возможно, api1/api2.

  • Эти общедоступные пакеты API затем будут зависеть от внутреннего пакета, поэтому вместо того, чтобы переписывать v2, это переписывание по мере роста пакета, и с ним намного проще обращаться.

В https://github.com/golang/go/issues/24301#issuecomment -377529520 предлагаемое изменение определяет «новый» код как код с файлом go.mod в том же каталоге или родительском каталоге. Включает ли это «синтезированные» файлы go.mod, созданные, например, путем чтения зависимостей из Gopkg.toml?

@zeebo , да. Если у вас есть файл go.mod в вашем дереве, то предполагается, что ваш код на самом деле строится с помощью vgo. Если нет, то rm go.mod (или, по крайней мере, не проверяйте его в своем репозитории, где его могут найти другие).

@AlexRouSg , ваш план для вашего пакета графического интерфейса мне понятен.

@rsc хм .. Я не уверен, что понимаю, и извините, если я был неясен. Пакет, содержащий только Gopkg.toml в дереве файлов, считается «новым» для определения?

@rsc

Что касается сгенерированного кода в более общем плане, то ответом является настоящая кросс-языковая система сборки, особенно потому, что мы не хотим, чтобы у каждого пользователя были установлены правильные генераторы. Автору лучше запустить генераторы и проверить результат.

Нам удалось решить эту проблему, сопоставив protobuf с GOPATH. Да, у нас так, что обычным пользователям не нужны инструменты для обновления, но для тех, кто модифицирует и регенерирует protobufs, решение в protobuild работает очень хорошо.

Ответ здесь довольно разочаровывает. Найти новую систему сборки, которой не существует, — это просто не ответ. Реальность здесь такова, что мы не будем перестраивать эти системы сборки и будем продолжать использовать то, что работает, избегая внедрения новой системы vgo.

Неужели vgo объявляет о банкротстве тех, кто полюбил и принял GOPATH и работал над его проблемами?

@zeebo , нет, наличие Gopkg.toml не считается новым; здесь «новый» означает, что ожидается использование импорта в стиле vgo (семантическое управление версиями импорта).

@stevvooe :

Нам удалось решить эту проблему, сопоставив protobuf с GOPATH. ...
Объявляет ли vgo о банкротстве тех, кто полюбил и принял GOPATH и работал над его проблемами?

Я не смотрел ваш протобилд, но в целом да, мы переходим на модель без GOPATH, и некоторые приемы, которые мог бы включить GOPATH, останутся позади. Например, GOPATH позволил оригинальному godep имитировать вендоринга без поддержки вендоринга. Это будет невозможно больше. На первый взгляд кажется, что protobuild основан на предположении, что он может помещать файлы (pb.go) в другие пакеты, которыми вы не владеете. Такая глобальная операция больше не будет поддерживаться, нет. Я совершенно серьезно и искренне хочу убедиться, что protobufs хорошо поддерживаются, отдельно от vgo. @neild , вероятно, было бы интересно услышать предложения, но, возможно, не по этому вопросу.

@stevvooe дал комментарии @rsc в https://github.com/golang/go/issues/24301#issuecomment -377602765. Я сделал перекрестную ссылку на https://github.com/golang/protobuf/issues/526 на всякий случай. эта проблема в конечном итоге покрывает угол vgo . Если что-то в конечном итоге будет решаться в другом месте, я уверен, что @dsnet и другие укажут нам.

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

Просто идея.

Как насчет сделать так, чтобы vgo get знал о конкретном теге, таком как vgo-v1-lock?
Когда репозиторий имеет тег, он может игнорировать другие теги версии и прикрепляться к тегу.

Итак, когда репозиторий пометил v2.1.3 как последнюю версию,
но также владелец нажимает тег vgo-v1-lock на ту же фиксацию, которая помечена как v2.1.3.
он может написать go.mod

require (
    "github.com/owner/repo" vgo-v1-lock
)

Он не должен обновляться, даже если vgo get -u , пока владелец репозитория не изменит или не удалит тег.
Это могло бы облегчить подготовку больших хранилищ к их перемещению.

Когда автор библиотеки готов, автор может объявить пользователю
что они могут обновить вручную, поставив «/ v2» в путь импорта.

Как мы поступаем в случае, когда необходимо исправить глубокую зависимость (например, применить исправление CVE, которое первоначальный автор еще не выпустил в теге). Кажется, что стратегия поставщика может справиться с этим, поскольку вы можете применить исправление к исходному выпуску авторов. Не понимаю, как vgo может справиться с этим.

@chirino , вы можете использовать директиву replace в файле go.mod, чтобы указать на исправленный пакет.

@rsc

На первый взгляд кажется, что protobuild основан на предположении, что он может помещать файлы (pb.go) в другие пакеты, которыми вы не владеете.

Это совсем не то, чем занимается проект. Он создает путь импорта из каталога GOPATH и каталога поставщика. Все файлы protobuf в вашем проекте будут сгенерированы с этим путем импорта. Он также делает такие вещи, как импорт карт в определенные пакеты Go.

Преимущество этого заключается в том, что он позволяет генерировать протобуфы в листовом проекте, которые зависят от других протобуфов, определенных в зависимостях, без повторной генерации всего. GOPATH фактически становится путями импорта для файлов protobuf.

Большая проблема с этим предложением заключается в том, что мы полностью теряем возможность разрешать файлы в проектах относительно пакетов Go в файловой системе. Большинство упаковочных систем способны это сделать, хотя и усложняют задачу. GOPATH уникален тем, что сделать это очень просто.

@stevvooe Извините, но я все еще не понимаю, что делает protobuild. Можете ли вы зарегистрировать новую проблему «x/vgo: несовместимо с protobuild» и привести простой рабочий пример дерева файлов, которое существует сегодня, что protobuild добавляет в дерево и почему это не работает с vgo? Спасибо.

Что делать, если имя модуля должно измениться (потеря домена, смена владельца, спор о товарном знаке и т. д.)?

@джиммифраше

Как пользователь:
Затем в качестве временного исправления вы можете отредактировать файл go.mod, чтобы заменить старый модуль новым, сохранив при этом те же пути импорта. https://research.swtch.com/vgo-tour

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

Как сопровождающий пакета:
Просто обновите файл go.mod, чтобы изменить путь импорта модуля, и сообщите об этом своим пользователям.

@джиммифраше ,

Что делать, если имя модуля должно измениться (потеря домена, смена владельца, спор о товарном знаке и т. д.)?

Это реальные, ранее существовавшие проблемы, которые предложение vgo не пытается решить напрямую, но очевидно, что в конечном итоге мы должны их решить. Решение проблемы исчезновения кода — наличие кэширующих прокси-серверов (зеркал) и причины им доверять; это будущая работа. Ответом на перемещение кода является добавление явной концепции перенаправления модулей или пакетов, подобно тому, как псевдонимы типов являются перенаправлениями типов; это также работа на будущее.

Ответ на исчезновение кода — иметь кеширующие прокси (зеркала)

ИМО, что действительно для предприятий. Большинство небольших компаний и другие компании прекрасно справятся с продажей и размещением всех зависимостей в одном и том же репозитории.

Зарегистрировано # 24916 для совместимости, о которой я упоминал в комментарии выше.
Также подан # 24915, предлагающий вернуться к прямому использованию git и т. Д. Вместо того, чтобы настаивать на доступе по HTTPS. Кажется очевидным, что настройки хостинга кода еще не готовы для использования только API.

небольшое предложение по созданию согласованности в файлах модов с запланированной командой vgo get

В документе "vgo-tour" команда vgo get показана как:

vgo get rsc.io/[email protected]

Как насчет отражения этого формата в файле мода? Например:

module "github.com/you/hello"
require (
    "golang.org/x/text" v0.0.0-20180208041248-4e4a3210bb54
    "rsc.io/quote" v1.5.2
)

может быть просто:

module "github.com/you/hello"
require (
    "golang.org/x/[email protected]"
    "rsc.io/[email protected]"
)
  • улучшает согласованность с командной строкой
  • один идентификатор полностью определяет элемент
  • улучшенная структура для поддержки операций, определенных в файле мода, для которых требуется несколько идентификаторов пакетов с версиями

Требуется больше ясности относительно того, как это предложение относится к распространению пакетов "только в двоичном виде".

версия/распространение двоичной библиотеки, похоже, не отображается ни в одном из документов описания вокруг vgo. есть ли необходимость смотреть на это более внимательно?

Как это работает сегодня, если я могу использовать простой инструмент git , go get будет работать просто отлично. Неважно, частный ли это репозиторий Github или мой собственный Git-сервер. Мне действительно нравится это.

Насколько я понимаю, продолжать работать в таком режиме будет невозможно. Это правда? Если да, возможно ли сохранить возможность использования локально установленного двоичного файла git для проверки кода? (событие использует явный флаг CLI)

@korya Пожалуйста, ознакомьтесь с недавно зарегистрированной проблемой https://github.com/golang/go/issues/24915 .

@sdwarwick , re https://github.com/golang/go/issues/24301#issuecomment -382791513 (синтаксис go.mod), см. #24119.

re https://github.com/golang/go/issues/24301#issuecomment -382793364, возможно, я не понимаю, что вы имеете в виду, но go get никогда не поддерживал бинарные пакеты, и мы не планируем чтобы добавить поддержку. Слишком сложно перечислить все возможные различные двоичные файлы, которые могут понадобиться. Лучше требовать исходный код и иметь возможность перекомпилировать его при изменении зависимостей или компилятора.

@AlexRouSg Да. Они не поддерживаются «go get» (но «go build» поддерживает их как тип сборки), на что ссылается @rsc . Распространение этих типов пакетов должно выполняться извне по отношению к инструментам «иди и получай», и, таким образом, вероятно, то же самое для этого нового предложения.

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

Я снова обновил резюме обсуждения. Я также подал # 25069 за свое предложение ранее о минимальной осведомленности о модулях в старой cmd / go.

@kybin , re https://github.com/golang/go/issues/24301#issuecomment -377662150 и тег vgo-v1-lock , я вижу привлекательность, но добавление особого случая для этого означает добавление большего количества особых случаев повсюду остальная часть модуля поддержки. Я не думаю, что выгода пропорциональна затратам в этом случае. Люди уже могут использовать псевдоверсии для получения аналогичного эффекта. Я также беспокоюсь, что тег будет перемещен и/или люди не будут должным образом соблюдать обратную совместимость (например, перемещение vgo1-v1-lock с версии 2.3.4 на версию 3.0.0 только для того, чтобы избежать семантического импорта версий). Так что в целом я думаю, что мы, вероятно, не должны этого делать.

Я думаю, пришло время отметить это предложение принятым.

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

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

Резюме обсуждения и часто задаваемые вопросы актуальны на данный момент. Обсуждение здесь и вне выпуска привело к следующим важным изменениям:

  • минимальная осведомленность о модулях в старой cmd/go, #25069.
  • восстановление минимальной поддержки поставщиков, #25073.
  • восстановление поддержки прямого доступа к Git, #24915.
  • убрать кавычки в go.mod, #24641.
  • улучшена поддержка gopkg.in, #24099 и др.
  • поддержка именования коммитов по идентификаторам веток, #24045.

Это также вызвало дискуссии о возможном изменении имени и синтаксиса файла go.mod, но единственным результатом изменения стало удаление кавычек.

Обсуждение утихло, а также стало достаточно длинным, чтобы было довольно больно загружаться на GitHub (очевидно, 100 комментариев — это слишком много!). Отметив предложение как принятое, мы можем сосредоточиться на использовании vgo и подготовке его к включению в Go 1.11 в качестве «предварительного просмотра», а также перейти к проблемам, которые GitHub может загружать быстрее.

Конечно, предстоит найти и исправить еще больше ошибок, а также внести дополнительные коррективы в дизайн. Обсуждение этих деталей может быть проведено по новым вопросам, относящимся к этим деталям. Пожалуйста, используйте префикс "x/vgo:" и веху vgo .

Всем спасибо.

@rsc Как теперь попробовать vgo? Должны ли мы получить и собрать github.com/golang/vgo или github.com/golang/go?

@ngrilly продолжайте использовать go get -u golang.org/x/vgo .

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

Я думаю, пришло время отметить это предложение принятым.

Я не думаю, что это уместно для лица, подающего предложение, объявлять, когда оно готово для принятия. Я думаю, что те, кто представляет предложение, особенно такое большое и самоуверенное, не должны влиять на его принятие. Их представление предложения сообщает об их предубеждениях. С другой стороны, я думаю, что авторы определенно должны иметь право голоса при отклонении предложения, если они передумают после его внесения.

В настоящее время кажется, что внутри vgo существуют глубокие разногласия по поводу технических решений, которые, как я боюсь, будут фрагментировать экосистему _и_ сообщество. Имея это в виду, я считаю, что мы должны дать немного больше времени для завершения конкурирующих предложений и привлечения их внимания. Как только это произойдет, у нас должна быть _нейтральная_ сторона, состоящая из представителей нескольких компаний и сообщества, чтобы облегчить обсуждение и принятие окончательного решения.

Меня все больше беспокоит то, что значительная часть руководства Go стала слишком изолированной от сообщества, стоящего за Go (включая другие компании, которые его используют), и что в результате язык и экосистема начинают страдать. Вот почему я думаю, что нам нужна нейтральная группа, в которой будут представлены пользователи языка программирования Go, чтобы помочь ратифицировать такие предложения.

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

@theckman Похоже , ваш ход мыслей таков:

  1. Решения о Go принимаются небольшой командой, в основном состоящей из инженеров Google.
  2. Инженеры Google изолированы от остального сообщества, потому что потребности Google очень специфичны.
  3. Это приводит к решениям, которые благоприятствуют точке зрения Google и не адаптированы для других пользователей Go.
  4. Это может навредить и расколоть сообщество Go.
  5. Чтобы решить эту проблему, Go должен внедрить формальный процесс принятия решений, при котором решения принимаются коллегиально группой, отражающей разнообразие сообщества Go (что-то «демократическое»).

Теоретически я был бы склонен любить что-нибудь "демократичное", но на практике:

  • Я не думаю, что решения, принимаемые командой Go, предвзято относятся к потребностям Google за счет «маленьких» пользователей Go. Как разработчик в очень маленьком магазине (в отличие от Google), я чувствую, что Go очень хорошо адаптирован к нашим потребностям, и я знаю другие небольшие команды вокруг меня, которые с удовольствием используют Go. Лично у меня есть единственные претензии к языку Go, которые были признаны командой Go (управление зависимостями, отсутствие дженериков, подробная обработка ошибок), и я уверен, что они работают над этим. Не могли бы вы привести примеры решений, принятых командой Go, которые были бы другими и лучше служили бы «остальной части сообщества», если бы у нас был «демократический» процесс?

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

@theckman , пока @ngrilly пытался быть вежливым, я буду конкретен: если вы обнаружите какие-либо технические проблемы, почему предложение vgo не готово к принятию - сообщите нам как можно скорее и прямо здесь! Если вы считаете, что некоторые известные проблемы не были должным образом решены, сообщите нам об этом. Если таких случаев нет - какая разница, кто скажет "пора принимать предложение"? У нас было два месяца, чтобы обсудить это, если вы считаете, что этого недостаточно по технической причине - сообщите нам.

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

Всем извините за очередной оффтопик!

@powerman Извините за хромоту и процитируйте мой предыдущий комментарий:

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

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

Я не уверен, что это легко сформулировать в этом выпуске, просто потому, что формат немного ограничен. Даже в этом случае я бы колебался, потому что, по сути, я дублировал бы части предложений WIP. Я не хотел бы фрагментировать идеи или красть гром у авторов.

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

Редактировать: Чтобы уточнить, под краткосрочным пребыванием я не подразумеваю два месяца или что-то в этом роде. Я имею в виду несколько недель.

@ngrilly Извините, я не хотел игнорировать ваш комментарий. Я планировал обратиться к предыдущему, но в итоге получился более многословным, чем хотел.

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

Я знаю, что поступают альтернативные предложения, и моя просьба заключалась в том, чтобы положить конец принятию этого до тех пор, пока у них не найдется время. ... [K] теперь, когда эти предложения находятся в стадии разработки и кто работает над ними, казалось, что заявление о готовности было активной попыткой задушить эти конкурирующие мнения.

Уверяю вас, что это не так. Здесь я достаточно ясно выразился по поводу временной шкалы. В моем первом сообщении от середины февраля говорится, что цель состоит в том, чтобы интегрировать предложение vgo в Go 1.11; приближается заморозка разработки. Я ничего не знаю о каких-либо других предложениях или о том, кто над ними работает. Это новость для меня. Если люди хотят принять участие в этом предложении или сделать встречные предложения, это предложение было открыто уже полтора месяца, так что уже немного поздно.

Чтобы было ясно, я не помечал предложение как принятое, несмотря на то, что сообщали Golang Weekly и, возможно, другие. Я лишь сказал, что считаю, что пора это сделать. То есть я не применил метку «Предложение принято» именно потому, что хотел сначала проверить, существует ли общий консенсус для этого. И общий консенсус, кажется, в пользу принятия, по крайней мере, судя по общему обсуждению здесь, а также счетчикам смайликов на https://github.com/golang/go/issues/24301#issuecomment -384349642.

Я знаю, что есть альтернативные предложения

@theckman , если ты знаешь о чем-то подобном, ты, вероятно, единственный, кто это знает. На сегодняшний день я не видел, чтобы кто-то поднимал этот вопрос до сих пор. Я думаю, что заявления Расса о желании попробовать это для Go 1.11 были очень четкими с самого начала, поэтому, если кто-то работает над альтернативными предложениями, у них было около 2 месяцев, чтобы выдвинуть их, даже в качестве предупреждения.

Я также думаю, что мы можем принять тот факт, что команда Go имеет хороший опыт принятия решений по прихоти, и если мы посмотрим, как они вытащили Alias ​​в последний момент из Go 1.8, так как это было неправильно. то, что нужно сделать в то время, то мы, вероятно, должны оказать им любезность, по крайней мере, позволив им построить свой собственный эксперимент/решение.

В конце концов, предложение содержит гораздо больше, чем просто алгоритм выбора используемой версии зависимости. Если кто-то найдет способ улучшить его, то есть два варианта: отправить его через обычный процесс CL ИЛИ создать свой собственный инструмент и позволить сообществу использовать его, если они того пожелают. Команда Go все еще может предоставить свою собственную версию инструмента imho, поэтому я не вижу, чтобы у этой проблемы была закрытая проблема.

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

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

Редактировать: в исходном сообщении было очень досадное упущение record of *not* making decisions on a whim должно было быть текстом, к сожалению, часть «не» отсутствовала. Мои извинения за это.

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

Хотя я упоминал об этой записи в Slack, а также обсуждал ее части непосредственно с @rsc , я решил не упоминать об этом здесь до сих пор. Мне казалось, что реклама этой рецензии до того, как я буду готов ее полностью выпустить, будет не очень конструктивной. Но, как уже было сказано, прошло уже два месяца, так что я собираюсь приложить большие усилия, чтобы серия вышла на следующей неделе.

(изменить: это «альтернативы», о которых говорил @theckman )

@sdboyer Вы упомянули, что у вас есть несколько проблем. Не могли бы вы хотя бы опубликовать их список прямо сейчас?
Я работаю с несколькими системами, которые выводят ад зависимостей на новый уровень (chef, go, npm, composer), и по опыту это предложение является решением для всех из них в отношении go.

@theckman , можете ли вы подтвердить, что имели в виду только отзыв @sdboyer ? Это не секрет. Сэм упомянул об этом буквально в первый же день выпуска vgo («я пишу более подробные документы о своих опасениях» — https://sdboyer.io/blog/vgo-and-dep/). Но это обратная связь, а не предложение, и вы несколько раз упомянули «другие предложения» во множественном числе. Есть ли что-то еще, о чем вы знаете?

Каковы последствия vgo для пользователей API go/types? Каков текущий статус поддержки go/types?

Я получил PR mdempsky/gocode#26, чтобы добавить реализацию go/types.Importer с поддержкой vgo, но мне непонятно, нужно ли это и зачем это нужно.

Предполагая, что это необходимо, можем ли мы добавить канонический vgo-aware go/types.Importer где-нибудь еще (например, в репозитории x/vgo или x/tools), чтобы инструменты на основе go/types не нуждались в повторной реализации этой поддержки. ?

Я действительно не следил за деталями vgo, так что, возможно, это просто «не влияет», но я не вижу никакого упоминания о go/types выше. Поиск в Google по запросу «vgo go/types golang» также неинформативен.

Спасибо.

@mdempsky , план состоит в том, чтобы иметь загрузчик пакетов с поддержкой vgo (и, если уж на то пошло, постройте с поддержкой кеша), вероятно, golang.org/x/tools/go/packages, но он еще не существует. Люди должны ждать этого пакета вместо того, чтобы писать код, который нужно будет выбросить. Не объединяйте PR. Я это прокомментировал.

@mdempsky собирался ответить на https://github.com/mdempsky/gocode/pull/26 , но пока отвечу здесь.

https://github.com/mdempsky/gocode/pull/26 полностью одноразовый; просто доказательство концепции, в котором используется ныне заброшенный CL против vgo .

Я только что видел ответ @rsc , поэтому я просто укажу, что обсуждение также продолжается в https://github.com/golang/go/issues/14120#issuecomment -383994980.

Резюме: после нескольких лет опыта работы с версиями последней лучшей попыткой был очень сложный алгоритм, спутниковый решатель. Но если вы сделаете несколько простых изменений во входных данных, NP-полная проблема решения станет чем-то не только управляемым, но и очень быстрым.

Мне, как пользователю небольшой команды Go с большим опытом использования NPM, очень нравится предложение vgo. FWIW, я с нетерпением жду, когда vgo будет реализован в go , и чем раньше это произойдет, тем лучше для моей команды и для меня.

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

Вот мой обзор.

На первый взгляд, раздел _Proposal_ последней версии документа с предложением кажется хорошим, хотя и не очень конкретным (например, неясно, в какой степени может поддерживаться Subversion ). Единственным исключением является то, что «Запретить использование каталогов поставщиков, за исключением одного ограниченного использования», по-видимому, говорит о том, что каталоги поставщиков вообще не будут поддерживаться в немодульных пакетах; это так?

С другой стороны, предложение подразумевает определенные решения по дизайну и реализации, которые подрывают различные преимущества текущего go get . Потери могут быть приемлемыми, некоторые из них могут быть предотвращены, но если vgo get заменит go get , их следует рассматривать как проектные соображения и обсуждать, потому что в противном случае мы можем получить инструмент, который не работает. не является адекватной заменой, и либо vgo не будет объединен в go , либо go get придется воскресить в качестве стороннего инструмента.

В разделе _Implementation_ говорится: «В более позднем выпуске (скажем, Go 1.13) мы прекратим поддержку go get немодулей. Поддержка работы в GOPATH будет продолжаться бесконечно». Это хлопотно. Во-первых, есть много хороших проектов, которые годами не обновлялись. Они все еще работают благодаря обещанию совместимости с Go 1, но многие не будут добавлять файлы go.mod . Во-вторых, это заставляет разработчиков проектов без зависимостей или тех, кому не важны версии, добавлять файлы модулей или воздерживаться от новой экосистемы go get . Возможно, у вас есть основания хотеть этого, но, пожалуйста, объясните, почему. (Для меня это кажется излишне громоздким; я бы предпочел использовать форк старого go get . Я согласен, что менеджеры пакетов для других языков еще более громоздки, и я уверен, что vgo лучше, чем они, но он не справляется с моими вариантами использования лучше, чем текущий go get , с периодической помощью от govendor ).

Меня больше всего беспокоит vgo по сравнению с go, связанный с рабочим процессом, который они поддерживают. Я выразил это в посте vgo-intro. Это может в целом относиться к разделу _Совместимость_ предложения или может выходить за его рамки, но соответствует другим вопросам и проблемам, поднятым здесь.

Для справки, вот копия моего комментария vgo-intro.

В некоторых более поздних версиях мы удалим поддержку старого, неверсионного go get.

В то время как другие аспекты предложения звучат хорошо, этот вызывает сожаление. (Настолько много, что если бы мне пришлось выбирать между включением управления версиями в цепочку инструментов go и продолжением работы с инструментами контроля версий, я бы выбрал последнее.) Преимущество vgo заключается в том, что он облегчает воспроизводимые сборки и задерживает поломку вашего проекта. из-за несовместимости обновлений, пока вы как автор проекта (с файлом go.mod) не захотите с этим столкнуться; но преимущество go get заключается в том, что он привносит преимущества монорепозитория в мир с несколькими репозиториями: благодаря полным клонам зависимостей вы можете работать с ними так же легко, как и со своим собственным проектом (просматривать историю, редактировать, различать изменения; перейти к определению чего угодно и обвинить его), облегчает сотрудничество (вы просто нажимаете и предлагаете свои изменения) и вообще навязывает мнение, что в любой момент времени есть только одно текущее состояние мира — вершина каждого проекта — и все остальное - история. Я думаю, что этот уникальный подход (за пределами реальных монорепозиториев) является отличительным преимуществом экосистемы Go, которая принесла больше пользы, чем зла, и от нее не следует отказываться.

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

В целом я хочу подчеркнуть, что текущий подход Go к управлению зависимостями в целом превосходит управление версиями. Он лучше согласуется с современным, динамичным и совместным открытым исходным кодом, который предполагает, что все коммиты видны, а публикации только исходников релизов (или «интеграции внутренних изменений» в огромные неописательные коммиты) недостаточно (поскольку это сильно снижает видимость, совместную работу). и динамичность). Как в монорепозиториях, так и в текущей экосистеме Go видно, что большинству проектов не нужны версии. Конечно этот подход не окончательный, у него есть минусы, и важно также поддерживать версионные проекты, но это не должно делаться в ущерб безверсионным.

Подводя итог, текущий go get (с вспомогательными инструментами, например, godef ) поддерживает рабочий процесс, который включает:

  • редактируемый исходный код зависимостей
  • исходный код зависимостей под их VCS
  • последние версии зависимостей

Думаю, я могу предположить, что исходный код зависимостей останется редактируемым, т.е. godef будет ссылаться на _файлы_, которые _не защищены от записи_ и _используются при сборке_. Однако vgo собирается отказаться от двух других пунктов. Что касается второго пункта, #24915 продлил поддержку инструментов VCS, но по-прежнему декларирует цель отказаться от нее; и рабочий процесс требует не только извлечения зависимостей из VCS, но и того, чтобы проверка была полезна для разработчиков (например, не поверхностная проверка git, не проверка git с удаленным .git ) и использовалась во время сборки , но vgo может не удовлетворять этому требованию. Что касается третьего пункта, я обосновал его ценность в комментарии vgo-intro, но vgo , похоже, вообще отказывается от него.

Инструмент управления версиями Go не должен отказываться от поддержки текущего рабочего процесса, и он не должен отказываться от нее, чтобы сохранить уникальные преимущества работы в экосистеме Go и быть адекватной заменой go get . Дизайн vgo делает это сложным, но не очевидным. Раздел _Proposal_ предложения, с другой стороны, кажется почти совместимым с текущим рабочим процессом. Единственная проблема, связанная с поддержкой третьего пункта (проверка последней версии) — и она большая — заключается в том, что для модулей ≥v2.0.0 трудно решить, могут ли они быть проверены в master , или они должны быть извлечены, как указано, потому что master находится в другой основной версии. Это не проблема для текущего go get с gopkg.in, потому что по умолчанию все извлекается в master , а содержимое в gopkg.in извлекается в соответствующем теге или ветке; но vgo стирает это различие и распространяет модель gopkg.in на все пакеты. (Более того, он перестает сопоставлять ветки.) По сути, становится невозможно сказать наверняка, и необходимо угадать, как получить последнюю ревизию указанной основной версии.

Возможно, я пропустил это, но как vgo будет работать в этом сценарии?

  • Я работаю над сервисом A и сервисом B в зависимости от lib X (над которым я также работаю)
  • Мне нужно серьезное изменение в lib X

С текущими способами я просто делаю свои изменения, компилирую службу A и службу B, они подбирают все, что находится в моем $ GOPATH для lib X, я исправляю вещи, затем я нажимаю lib X с большим ударом semver, затем нажимаю обе службы A и B говорят им использовать новый мажор библиотеки X в их Gopkg.toml .

Теперь, когда vgo вступит во владение, go build на моих сервисах попытается найти несуществующую новую версию lib X на github, и я могу предвидеть всевозможные проблемы.

Итак, я упускаю что-то очевидное?

Вы можете использовать директиву replace для этого типа вещей.

В понедельник, 30 апреля 2018 г., 12:15 Антуан уведомления@github.com написал:

Возможно, я пропустил это, но как vgo будет работать в этом сценарии?

  • Я работаю над сервисом A и сервисом B в зависимости от библиотеки X (которую я
    тоже работаю)
  • Мне нужно серьезное изменение в lib X

С текущими способами я просто делаю свои изменения, компилирую службу A и
служба B, они берут все, что находится в моем $GOPATH для библиотеки X, я исправляю вещи,
затем я нажимаю lib X с большим ударом semver, затем нажимаю обе службы A и B
предлагая им использовать новый мажор lib X в своем Gopkg.toml.

Теперь, когда vgo вступит во владение, начните использовать мои услуги, чтобы попытаться найти не
существующая новая версия lib X от github, и я могу предвидеть все виды
неприятности.

Итак, я упускаю что-то очевидное?


Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/golang/go/issues/24301#issuecomment-385499702 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAuFsfnD8_kbUj8fSXvGgeN77ki6KYM6ks5tt2LLgaJpZM4Sg3bp
.

@kardianos да, но это все равно означает, что мне нужно внести изменения в свою библиотеку, чтобы попробовать?

РЕДАКТИРОВАТЬ: кажется, вы можете использовать пути для замены (https://github.com/golang/go/issues/24110), что хорошо. Но я также могу предсказать, что это в конечном итоге будет совершено много раз.

Есть ли планы создать дополнительный файл, например, go.mod.replace или что-то в этом роде, чтобы мы могли определить переопределения в средах разработки и игнорировать их?

@primalmotion Чтобы предотвратить плохие коммиты, вам, вероятно, следует использовать git-хук.

Но я полагаю, что правильный ответ - просто не делайте этого (заменяйте локальный путь) слишком часто. Если ваша библиотека так тесно связана, то она не должна находиться в отдельном репо (и, таким образом, притворяться, что она слабо связана). В общем случае вы должны иметь возможность исправлять, тестировать и выпускать эту библиотеку, не принимая во внимание текущую реализацию этих сервисов. Особенно с vgo, который гарантирует, что обе службы будут продолжать использовать более старую версию библиотеки (которую они использовали раньше), пока вы вручную не обновите их до более новой версии этой библиотеки. Если вы время от времени будете заменять локальные пути один раз в год — это не имеет большого значения, CI поможет вам заметить и исправить это за считанные минуты.

@primalmotion с go.mod.replace без версии, вы можете зафиксировать проект, который не будет воспроизводим. Вместо этого с заменой в go.mod вы уверены, что фиксируете именно то, что используете и тестируете в настоящее время.
Коммит с заменой может быть ошибкой, но вы это заметите и исправите.
Или это может быть добровольно, я делаю это с подмодулями, это нормально, когда вы работаете над проектом и библиотекой вместе, и это воспроизводимо, если вы фиксируете подмодуль. Я часто делал это на Python и пропустил это с Go. С vgo я счастлив, что снова могу так работать. _(надеюсь быть ясным с моим плохим английским, извините)._

Ну, проблема в том, что мы не заботимся о воспроизводимых сборках, пока не решим, что нам это нужно (т.е. когда мы готовим релизы). У нас очень гибкая среда разработки, в которой обновление библиотеки — это просто проверка, пересборка, запуск тестов. Мы не фиксируем Gopkg.lock в основных ветках наших сервисов, только toml с фиксированными версиями для внешних библиотек и основными ограничениями для наших. Как только мы создаем релизную ветку, мы фиксируем Gopkg.lock, и только после этого мы получаем воспроизводимые сборки (это делает наш ci).

Vgo в основном ломает все рабочие процессы, которые мы создавали годами. Теперь, чтобы попробовать что-то столь же глупое, как небольшая отладка печати в библиотеке (потому что мы все это делаем, не врите :)), или небольшая оптимизация, нам придется пройтись по десяткам сервисов, добавить replace Директивы

Что может заставить vgo работать на нас:

  • система переопределения, как я уже упоминал
  • способ вообще не использовать его и вернуться к старому доброму GOPATH для разработки.

И мы действительно хотим, чтобы это работало на нас, потому что это потрясающе.

Можем ли мы что-то протестировать в go 1.11 (сейчас оно заморожено) или, может быть, в go 1.12?
Он уже помечен как экспериментальный. И я думаю, что чем больше людей протестируют его в реальной разработке, тем ценнее будут отзывы.

Я читал о проблеме с версиями пакетов. Для одного простого сценария, если я пишу библиотеку, которая говорит, что используйте dep для разбора plist с именем foo-plist . В результате синтаксического анализа эта библиотека plist предоставляет определенные собственные типы. Теперь эта библиотека обновляется до версии 2, и моя библиотека вынуждена обновляться до версии 2, если я возвращаю какие-либо объекты этих типов plist.

Это кажется довольно сложным для решения, например, если я хочу, чтобы моя библиотека поддерживала как v1, так и v2 указанной библиотеки plist под впечатлением от этого предложения.

Например, в npm моя библиотека может просто указать одноранговую зависимость, например, >=1.0.0|>=2.0.0 , и пользователь моей библиотеки должен решить, какую версию plist использовать. Итак, если пользователь моей библиотеки foo-plist также использует другую библиотеку, которая зависит от plist , тогда, если обе библиотеки довольны v1 и v2 plist, пользователь может выбрать, какие из них использовать. фактически импорт. Что еще более важно, если обе библиотеки экспортируют типы plist, эти типы будут фактически совместимы.

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

@itsnotvalid foo-plist.2 может импортировать foo-plist и повторно экспортировать его типы, используя псевдонимы типов. Хорошее описание этой техники можно найти здесь https://github.com/dtolnay/semver-trick .

Арам упомянул здесь о сложности обратного переноса изменений в ветки (или каталоги) предыдущих выпусков. Поскольку «самостоятельные» ссылки на источники в том же модуле также включают версию в пути импорта, либо исправления не будут импортированы корректно, либо можно непреднамеренно ввести импорт между версиями.

Мысли?

Чтобы было ясно, я полностью доволен импортом между модулями, используя версии в пути импорта; Я думаю, аргументы Расса были очень убедительны. Я менее понимаю их для импорта внутри модуля. Я понимаю цель иметь единый путь импорта для данного пакета в сборке (независимо от того, импортируется ли он между модулями или в своем собственном модуле), но если бы мне пришлось выбирать, я бы предпочел иметь решение для Проблема Арама, чем сохранить это имущество. (Кроме того, я предполагаю, что система сборки может внедрить версию из файла мода при сборке модуля верхнего уровня и буквально внедрить ее в исходный код после загрузки зависимости модуля)

@rsc есть ли шанс, что мы продвинем это вперед? Я не вижу ничего серьезного, сдерживающего это.

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

@sdboyer планирует опубликовать свои статьи на этой неделе. Я бы сказал, что справедливо ждать их.

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

И если мы в дальнейшем решим улучшить/изменить алгоритм загрузки этих зависимостей, то мы можем это сделать, не затрагивая ничего остального.

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

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

Кратко: в vgo есть много замечательных вещей, многие из которых мы, как сообщество, давно хотели. Однако я считаю, что MVS непригоден для этой цели и не должен использоваться в производстве. Жаль, что так много вещей, которые мы хотим, связаны с MVS, особенно когда так мало из них специфичны для него. я работаю над альтернативным подходом, на который ссылаются в целях сравнения на протяжении всей серии блогов и который будет сформулирован в последнем посте.

Альтернативный базовый алгоритм, над которым я работаю, вероятно, будет довольно просто перенести на go.mod , поэтому я не ожидаю, что у нас возникнут проблемы, которые, вероятно, можно было бы оставить как есть, если был добавлен отдельный файл блокировки, который содержит транзитивное закрытие зависимостей, и _это_ будет то, из чего читает компилятор, а не алгоритм списка сборки. (Есть и другие причины для файла блокировки, хотя это будет в посте 5.) По крайней мере, это дает нам выпускной клапан.

Однако, если мы говорим, что MVS в порядке, даже в качестве временной меры, тогда он входит и получает преимущество инерции. В этот момент мы должны доказать, что это не соответствует @rsc (хотя на самом деле он установил это в качестве стандарта еще до слияния), и он считает, что это верное утверждение о go get прямо сейчас:

Сегодня многие программисты по большей части не обращают внимания на управление версиями, и в основном все работает нормально.

Учитывая все вышеизложенное, я опасаюсь, что если мы позволим этому продолжаться сейчас, это создаст «генерики, второй раунд» — за исключением того, что на этот раз речь идет о правилах, которые управляют тем, как мы взаимодействуем друг с другом, а не с машинами.

Однако, если мы говорим, что MVS в порядке, даже в качестве временной меры, тогда он входит и получает преимущество инерции.

Обратите внимание, что прямо сейчас у dep есть преимущество инерции (как за счет того, что он построен на тех же предпосылках, что и менеджеры версий других языков, так и за счет более длительного существования при широкой поддержке сообщества). По крайней мере, для меня предложение vgo все же сумело преодолеть эту инерцию, будучи хорошим дизайном, подкрепленным хорошими аргументами.

Я лично не возражаю, если создание версий в Go задерживается, я полностью за то, чтобы делать что-то правильно, а не быстро. Но, по крайней мере, на данный момент vgo все еще кажется мне правильным решением (и многие люди в сообществе AIUI воспринимают это как неотложную проблему).

@mvdan Это изменение не обошлось без последствий. Мы все хотим этого, но я думаю, что также разумно потратить дополнительное время на то, чтобы подавить сомнения, особенно когда человек, вызвавший эти сомнения, явно много думал о проблеме.

Я постоянно слышу упоминания о замораживании и его влиянии на получение предварительного просмотра vgo в 1.11 . Какова официальная линия на данный момент о том, будет ли это интегрировано для 1.11 ? Эта проблема кажется мне удивительно тихой, учитывая потенциальное влияние.

@sdboyer , какова ваша позиция по поводу того, следует ли объединить это в 1.11 , учитывая, что вы только _только_ официально заявили публично о своей позиции по MVS?

Если это не войдет в 1.11 , то мы не будем официально доступны для предварительного просмотра до 1.12 в феврале 2019 года и официально выпущены как минимум до 1.13 в августе. 2019. Это означает, что самый ранний потенциальный выпуск будет через 18 месяцев после того, как @rsc впервые начал его обсуждать. Конечно, нам не следует торопиться с этим без необходимости, но, как сказал @Merovius выше, многие люди, включая меня, считают официальный ответ на управление зависимостями «срочным» вопросом. Ожидание 18 месяцев кажется чрезмерным.

Конечно, казалось, что dep будет официальным ответом, и мы преобразовали наши репозитории в него (и были довольны его результатами). С этим предложением фактически осуждается dep для долгосрочного использования, но нет официального способа начать интеграцию vgo (по крайней мере, пока #25069 не будет объединено), мы остаемся в неудовлетворительном положении, когда вынуждены использовать инструмент (с dep ), который, как мы знаем, имеет очень ограниченный срок годности.

FWIW, я абсолютно уверен, что мы должны продвинуться вперед, интегрировав vgo в качестве предложения в 1.11 и включив #25069 в 1.11 (и в качестве исправлений для 1.9 ). 1.10 после выпуска 1.11 ).

Честно говоря, я не понимаю всех последствий беспокойства MVS и @sdboyer по этому поводу. Однако, учитывая его опыт в этой области, я думаю, что эти опасения заслуживают серьезного рассмотрения. Тем не менее, если он готов интегрировать vgo с MVS в 1.11 (при этом понимая, что его [все еще развивающееся] предложение, если оно будет принято [за 1.12 ], не должно нарушать работу модулей разработана изначально для МВС), то не вижу причин не двигаться дальше.

Я также хотел бы поблагодарить @rsc за это предложение. Я ценю, что Go не просто скопировал подход другого инструмента и пытается решить эту проблему способом, который кажется идиоматическим. Хотя управление зависимостями никогда не бывает забавным, кажется, что с этим предложением Go может продвинуть отрасль вперед и, возможно, даже обойти системы, которые в настоящее время считаются лучшими в своем классе.

Просто добавлю свои 0,02 доллара: по моему мнению, MVS — это момент «ах-ха» для управления зависимостями. Я ценю количество мыслей, которые люди приложили к этому, но по-прежнему убежден, что MVS — это то, к чему нужно идти.

Я особенно согласен с мнением других: «автоматические исправления безопасности» — это в лучшем случае несбыточная мечта, а в худшем — огромная банка червей.

Кроме того, я с @joshuarubin : официальный ответ на управление зависимостями является срочным вопросом. Другие отметили, что мы могли бы перейти к MVS сейчас, а позже при необходимости перейти на другие решения; если это действительно возможно, я думаю, что это лучший путь.

Я предлагаю отделить основные версии от путей импорта следующим образом. (Я считаю, что я учел аргументацию в vgo-import и что я не принижаю заявленные там достижения vgo.) Это вдохновлено идеей из # 25069 о том, что go build в Go 1.9 и 1.10 должны научиться творчески интерпретировать пути импорта (отбрасывая часть версии); в моем предложении старый go build не меняется, а vgo учится аналогичному трюку.


Синтаксически единственные изменения заключаются в следующем:

  1. В файлах .go import "repo/v2/pkg" остается import "repo/v2/pkg" , если v2 является каталогом, но в противном случае становится import "repo/pkg" . Это сохраняет совместимость с текущим go get .
  2. В файлах go.mod module "repo/v2" остается прежним, если он находится в подкаталоге v2 , но становится module "repo" , если находится на верхнем уровне. (Это канонический префикс импорта.)
  3. В файлах go.mod вы также можете написать require repo v2.3.4 as repo2 . Затем в файлах .go вы будете использовать import "repo2/pkg" (или import "repo2/v2/pkg" , если v2 — это каталог). Это не будет импортироваться текущим go get (если вы не используете что-то вроде require github.com/owner/project v2.3.4 as gopkg.in/owner/project.v2 ), но это необходимо только в том случае, если вы хотите использовать несколько основных версий в одном модуле, а зависимость не хранить основные версии в подкаталогах, которые в любом случае не могут поддерживаться текущим go get .

Технически это позволяет вам написать go.mod с помощью:

require repo v1.0.0
require repo v1.1.1 as repo1
require repo v2.2.2 as repo2
require repo v2.3.3 as repo3

но выбор минимальной версии разрешит это таким образом, что и repo , и repo1 ссылаются на репо в v1.1.1 , и repo2 и repo3 в v2.3.3 . Я не знаю, следует ли разрешить или запретить это псевдоним.


Преимущества:

  • код с поддержкой модулей будет совместим с текущими версиями go get даже с более ранними версиями 2.0.0; следовательно:

    • нет необходимости делать go get минимальным модулем (#25069)

    • проекты прошлого v2.0.0 не должны будут нарушать совместимость с модулем-незнанием go get

  • проектам не придется ждать, пока их зависимости станут модулями, прежде чем они сами станут модулями [1]
  • нет необходимости осуждать проекты, не поддерживающие модули, или отговаривать авторов от запуска новых проектов, не поддерживающих модули.
  • проще сохранить поддержку рабочего процесса без версий текущего go get (объяснено здесь и выше )

Недостатки:

  • может быть неудобно выполнять обещание, что уже написанные файлы go.mod будут продолжать работать (если только новый файл модуля не будет называться иначе, go.mod )

Амбивалентность:

  • один и тот же путь импорта в разных модулях может относиться к разным основным версиям

    • хорошо: легче поддерживать прошлую версию 2.0.0 и при изменении основной версии

    • плохо: вы не знаете, какую основную версию вы используете, не глядя на go.mod

  • модули могут определять произвольные префиксы импорта для использования в своем коде

    • некоторые пользователи предпочитают импортировать все по короткому имени (например, import "yaml" с require gopkg.in/yaml.v2 v2.2.1 as yaml )

[1] В настоящее время vgo может должным образом поддерживать немодульные зависимости только в том случае, если ни одна немодульная транзитивная зависимость модуля не старше версии 2.0.0. В противном случае проекту придется ждать, пока все зависимости, косвенно зависящие от проекта, выпущенного после версии 2.0.0, не станут модулями.

Я проанализировал файлы Gopkg.toml, которые смог найти в пакетах на https://github.com/rsc/corpus , и составил сводку на https://github.com/zeebo/dep-analysis. Судя по имеющимся данным, не так много доказательств того, что vgo не сможет справиться почти со всеми выявленными вариантами использования.

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

Если я процитирую вас:

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

Вероятно, это связано с тем, что существует только мастер, а не теги или «именованные ветки, такие как v2, v3». Если это так, то сравнение некорректно, потому что у вас нет выбора!

@mvrhov Я не уверен, что ты имеешь в виду под «нечестным». Мне кажется, что vgo и dep прекрасно справятся с этим случаем. Или, скорее, любая реалистичная альтернатива должна прекрасно справляться с этим случаем. В частности: если еще нет выпущенной версии, в мире vgo они могут быть просто помечены как v1.0/v0.x, и никаких изменений в каких-либо путях импорта (основная особенность vgo) не потребуется.

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

Это предложение активно обсуждалось более двух месяцев: @rsc и @spf13 провели сеансы обратной связи и получили ценный вклад от сообщества, что привело к пересмотру предложения. @rsc также проводил еженедельные встречи с @sdboyer , чтобы получить дополнительную обратную связь. По предложению были получены ценные отзывы, в результате которых были внесены дополнительные изменения. Все чаще эта обратная связь относится к сопутствующей реализации, а не к предложению. После тщательного рассмотрения мы считаем, что пришло время принять это предложение и позволить широкой экосистеме разработчиков инструментов Go начать вносить критические корректировки, чтобы наша пользовательская база могла получить наилучший возможный опыт.

Было два возражения против этого предложения, с которыми, как нам кажется, нам следует поговорить:

  1. Предложение потребует от людей изменить некоторые методы использования и выпуска библиотек.
  2. В предложении не предусмотрено техническое решение для всех возможных сценариев, связанных с несовместимостью.

Они точны в своих наблюдениях, но работают по назначению. Авторы и пользователи кода _должны_ изменить некоторые свои методы использования и выпуска библиотек, точно так же, как разработчики адаптировались к другим деталям Go, таким как запуск gofmt. Изменение лучших практик иногда является правильным решением. Точно так же vgo не нужно обрабатывать все возможные ситуации, связанные с несовместимостью. Как отметил Расс в своем недавнем выступлении на Gophercon Singapore , единственное постоянное решение проблемы несовместимости — это совместная работа над исправлением несовместимости и поддержанием экосистемы пакетов Go. Временные обходные пути в таких инструментах, как vgo или dep, должны работать достаточно долго, чтобы дать разработчикам время для решения реальной проблемы, и vgo достаточно хорошо справляется с этой задачей.

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

- Комитет по рассмотрению предложений Go

Чтобы добавить немного красок в отчет, еженедельные встречи с @sdboyer не должны рассматриваться как одобрение. Недавно Сэм начал писать о проблемах с MVS, а также о том, что ему нравится в vgo . Я добавляю это, чтобы убедиться, что нет недопонимания с кем-либо еще. Если вам интересно его мнение, прочтите его слова. Я считаю, что они содержат значительное количество разногласий с текущим предполагаемым подходом.

@mattfarina FWIW, я прочитал это предложение больше как «мы знаем о его критике (как он выразил ее в частном порядке), и это не изменило нашего мнения». Прискорбно, однако, что его мнения и аргументы до сих пор не оглашены.

Кажется безответственным принимать предложение, в то время как в подходе все еще остаются нерешенными фундаментальные проблемы. Консенсус между автором и экспертом в области сообщества @sdboyer кажется разумным минимальным стандартом, которого необходимо достичь, прежде чем предложение будет считаться принятым.

@merovius Некоторые из нас поделились своим мнением публично и в частном порядке. Некоторые люди считают, что поднятые проблемы были пущены в ход (иногда грубо), а не дано достаточное решение. Я начинаю публично делиться практическими проблемами, чтобы мы могли попытаться их решить. Например, как раз сегодня я осколки некоторых подробностей по практической задаче здесь . Забавное примечание: это было на первой полосе хакерских новостей, в то же время это было помечено как принятое.

@peterbourgon Как человек, который участвовал в опросе Go Dependency Management и работал над Glide, где я выслушивал потребности людей и пытался заставить их работать, я могу показать практические проблемы (а не просто мнения). То есть я могу сопоставить желания, потребности и ожидания пользователей с решениями этих проблем. Меня беспокоит несоответствие этого для текущего пути vgo. Существуют неудовлетворенные потребности и прагматические проблемы из-за различий в том, как люди управляют зависимостями.

Простой способ развеять мои опасения — заставить vgo работать на Kubernetes к удовлетворению Тима Хокинса.

Простой способ развеять мои опасения — заставить vgo работать на Kubernetes к удовлетворению Тима Хокинса.

Заставить vgo работать на Kubernetes сегодня или заставить vgo работать на Kubernetes в ближайшие годы? Насколько я понимаю, одно из фундаментальных разногласий в дизайне между vgo и dep заключается в том, нужно ли нам работать с экосистемой в том виде, в каком она существует сегодня (предположение dep), или мы можем переключить сообщество на выпуск тегированных релизов и поддержание совместимости (предположение vgo). .

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

@mattfarina Конечно. Лично мне очень неприятно изображать это как «паровую катушку». @sdboyer в течение нескольких месяцев в значительной степени воздерживался от публичного обсуждения, и от него до сих пор нет реальных, конкретных аргументов. У него были свои причины, и это справедливо. Но консенсус по-прежнему требует обсуждения, и, по крайней мере, что касается публичного отчета, я лично не знаю о каких-либо проблемах, которые были подняты и просто проигнорированы (хотя я еще не читал ваш пост).

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

@bradfitz SemVer сегодня используется пакетами Go, как правило, в PHP, в node.js, в Rust и во многих других языках. Это довольно распространенная вещь. Я сталкивался с проблемами на этих и других языках, когда пакеты ломались из-за проблем совместимости с SemVer. Иногда намеренно, а иногда случайно. Что Go будет делать по-другому, чтобы избежать проблемы, присутствующей во всех этих других языках, потому что люди могут ошибаться?

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

Думаю, все согласятся: текущая ситуация с управлением зависимостями ужасна на любом языке/платформе. Я считаю, что @bradfitz правильно объяснил суть конфликта. Возможно, vgo не будет иметь успеха, но для меня очевидно, что мы должны что-то изменить (я имею в виду не только в Go, но и вообще), и vgo выглядит очень многообещающе, чтобы попробовать.

@mattfarina Мы планируем попытаться реализовать сервис, который будет автоматически контролировать фактическую совместимость. Интеграция его с godoc.org, предоставление значков для README, использование его в качестве прокси для go get — есть много способов, как мы можем попытаться заставить его работать достаточно хорошо. Конечно, @sdboyer прав в том, что совместимость API не гарантирует реальной совместимости, но это хорошее начало, и в большинстве случаев оно должно работать достаточно хорошо.

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

Надежда — это не стратегия, особенно когда существующее поведение и ожидания уже устоялись. У Go могли бы быть жетоны инноваций, которые можно было бы потратить здесь, если бы мы обсуждали это пять лет назад, и на вещи можно было повлиять. Но в результате столь долгого игнорирования проблемы мне кажется ясным, что любой инструментарий, предлагаемый сейчас, должен соответствовать пользователям там, где они есть.

Что Go будет делать по-другому, чтобы избежать проблемы, присутствующей во всех этих других языках, потому что люди могут ошибаться?

Мы обсуждали какую-то команду go release , которая не только упрощает релизы/тегирование, но и проверяет совместимость API (например, внутреннее средство проверки Go go tool api , которое я написал для релизов Go). Он также может запрашивать godoc.org и находить вызывающих ваш пакет и запускать их тесты для вашей новой версии также во время предварительного выпуска, до того, как какой-либо тег будет отправлен. и Т. Д.

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

Это не очень практично для тех, кто не является Google.

Это не очень практично для тех, кто не является Google.

Поскольку все облачные провайдеры начинают предлагать контейнеры как услугу с посекундной оплатой, я не вижу причин, по которым мы не могли бы предоставить это как инструмент с открытым исходным кодом, который любой может запустить и заплатить 0,57 или 1,34 доллара, которые им нужны. чтобы запустить миллион тестов на нескольких хостах за несколько минут.

Когда дело доходит до проведения тестов, у Google не так много секретов.

Поскольку все облачные провайдеры начинают предлагать контейнеры как услугу с посекундной оплатой, я не вижу причин, по которым мы не могли бы предоставить это как инструмент с открытым исходным кодом, который любой может запустить и заплатить 0,57 или 1,34 доллара, которые им нужны. чтобы запустить миллион тестов на нескольких хостах за несколько минут.

Для этого требуется учетная запись у определенного облачного провайдера, требуется, чтобы вы приняли условия обслуживания определенного облачного провайдера (что вы можете или не можете сделать по юридическим причинам, даже если большая часть мира относится к этому так, как будто это не так). имеет значение), требует, чтобы вы жили в районе, который обслуживает облачный провайдер (например, если вы находитесь в Иране, а облачный провайдер находится в Соединенных Штатах, вы не сможете использовать его из-за законов об экспорте), и требует, чтобы у вас есть деньги, чтобы заплатить облачному провайдеру (предположительно, каждый раз, когда вы делаете релиз). Деньги могут быть невелики, но это не значит, что каждый сможет их заплатить. Если мы хотим, чтобы Go был инклюзивным и удобным для использования разнообразной аудиторией, это не кажется хорошим решением.

/ два цента

@SamWhited MeteorJS работал с галактикой, встроенной командой meteor publish для запуска вашего проекта в облачном провайдере. Может быть, я неправильно понимаю поставленную задачу, но их подход к ней казался прекрасным.

@bradfitz Что, если API не изменится, а поведение, стоящее за ним, изменится? Это случай, который выходит за рамки SemVer и влияет на тех, кто его импортирует. Как вы определяете эту ситуацию? Я спрашиваю, потому что я испытал это более чем один раз.

инструмент с открытым исходным кодом, который любой может запустить и заплатить 0,57 или 1,34 доллара, необходимые для запуска огромного количества тестов на нескольких хостах в течение нескольких минут.

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

А как насчет всех случаев отказа от работы с общедоступным облаком? Локальные (многие так делают) или проприетарные и имеющие проблемы с доверием. Как этот материал будет работать для них? Если у вас есть собственный инструмент, вы можете не захотеть сообщать государственным службам, какой импорт вы используете. Допустим, вы получаете импорт из GitHub, но этот сервис работает в Google. Чувствуют ли люди себя нормально, передавая свое дерево зависимостей Google? Куча не будет.

Он также может запросить godoc.org и найти вызывающих ваш пакет и запустить их тесты для вашей новой версии также во время предварительного выпуска, до того, как будет добавлен какой-либо тег. и Т. Д.

Давайте возьмем Kubernetes в качестве примера. Кто-то пишет пакет, который импортируется в Kubernetes. Так что инструмент должен получить это и запустить все тесты. Некоторые его части предназначены для работы в Windows и POSIX. Можем ли мы протестировать мульти-ОС/мультиархив (поскольку Go справляется с этим). Как это будет выглядеть (и стоить)?

--

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

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

Процитирую @technosophos ранее сегодня:

«Менеджеры версий на самом деле не являются инструментами для компиляторов, компоновщиков или чего-то еще ... менеджеры версий предназначены для совместной работы людей».

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

Кажется безответственным принимать предложение, в то время как в подходе все еще остаются нерешенными фундаментальные проблемы. Консенсус между автором и экспертом в области сообщества @sdboyer кажется разумным минимальным стандартом, которого необходимо достичь, прежде чем предложение будет считаться принятым.

Просто напомню: у нас есть история упаковки, которая одновременно нестандартна и неоптимальна (экосистема go get ). Было бы лучше просто отказаться от стандартного менеджера пакетов, чем выпускать еще один go get , который подталкивает людей к плохим практикам во имя совместимости со «стандартным» инструментом. Как человек, который использует Go с момента его публичного выпуска, я нахожу этот разговор разочаровывающим и обескураживающим, поскольку кажется, что руководство команды Go не извлекло уроков из ошибок, допущенных с go get (в девичестве goinstall ).

Есть разумные и практические проблемы, которые озвучены по поводу этого предложения. Мы должны изменить предложение, чтобы в их адрес не было просто сказано: «Работает, как задумано». Если мы не можем сделать это правильно для 1.11, 1.12 или 1.13, тогда нам следует подождать, пока это не будет сделано правильно. В этом предложении предлагается система, которая ведет себя значительно иначе, чем большинство других систем, и не лучшим образом.

Мотивирующей причиной использования MVS, по-видимому, является то, что традиционный подход является NP-полным. Я считаю, что это очень плохая мотивация. При работе с NP-полными задачами главный вопрос звучит так: «Как часто возникают сложные экземпляры». Что касается управления пакетами, то ответ будет «очень редко». Мы не должны соглашаться на неполную и бесполезную формулировку проблемы только для того, чтобы избежать ярлыка NP-HARD на проблеме.

Большинство конкретных моментов было озвучено другими людьми, более близкими к проблеме ( @sdboyer @peterbourgon @mattfarina и т. д.). Моя главная претензия заключается в том, что мы принимаем это предложение, когда эти конкретные моменты не были должным образом рассмотрены.

@SamWhited , вы не согласны с дополнительной функцией гипотетического дизайна. Гипотетический пользователь, который не доверяет ни одному облачному провайдеру, или не может использовать ни одного облачного провайдера внутри брандмауэра своей страны, или не хочет платить, всегда может провести тесты (или их часть) на своей собственной машине за ночь. Или просто используйте проверку подписи go release , которая дает вам 95% пути туда бесплатно.

@mattfarina , @SamWhited , давайте перенесем обсуждение на https://github.com/golang/go/issues/25483.

@матфарина

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

Мне до сих пор непонятно, почему предполагается, что vgo в этих случаях работает хуже, чем dep. Напротив, мне кажется, что vgo работает строго лучше . В своем блоге вы упоминаете конкретную проблему с helm, как свидетельство неудачи модели vgo. Однако в мире vgo есть два сценария, по которым vgo выбрала бы версию 1.4.0 для grpc:

  1. Разработчики helm решили указать grpc >= v1.4.0 в go.mod в качестве требования. В этом случае они могут просто отменить это требование и, таким образом, вернуться к предыдущей версии grpc , которая им подходит.
  2. Разработчики зависимости helm решили указать grpc >= v1.4.0 . В этом случае dep также установил бы это, и если бы helm попытался откатиться, ограничив grpc < v1.4.0 , dep пришлось бы хрипеть из-за противоречивых требований.

Так что мне кажется, что vgo решает эту проблему не хуже, чем dep. Между тем, в деп-мире есть и другой вариант:

  1. Для транзитивных зависимостей helm требовался grpc >= v1.x.0 , с некоторым количеством x < 4 , затем grpc выпустил v1.4.0 , и отдел решил использовать более новую версию при установке, не спрашивая об этом. . В этом случае руль будет сломан, и нужно будет ютиться, чтобы сделать выпуск исправления (как описано в вашем посте), создавая труд. Между тем, vgo просто проигнорировал бы новую версию, и все продолжало бы работать нормально.

Я, видимо, упускаю из виду что-то основное. Но в прошлый раз, когда я попросил разъяснений по этому поводу в slack, меня отложили до гипотетического будущего поста в блоге. Отсюда мое разочарование, потому что я действительно не понимаю, откуда взялась идея, что у vgo почему-то больше проблем с людьми, нарушающими семантику их версий, чем у dep.

Чтобы уточнить, речь идет не о dep . Это анализ того, как MVS (vgo) ведет себя по сравнению с другими решениями для управления пакетами на основе SAT-решателя (включая dep).

Другой пример Мэтта гласит следующее:

Вы являетесь разработчиком модуля app и у вас есть две зависимости:

  • grpc [>= 1.8 ]
  • helm , которые имеют следующую зависимость:

    • grpc [>= 1.0, < 1.4] (поскольку grpc внес критическое изменение в 1.4).

Большинство людей не знают о требованиях к транзитивной зависимости ( helm -> grpc [>= 1.0, < 1.4]), потому что для этого нужно знать, что helm ломается, когда используя grpc >= 1.4. Я предполагаю, что это не то, что большинство людей будет заботиться об этом или тратить время и энергию на его расследование.

Если вы используете vgo (в частности, полагаясь на MVS), вы получите:

  • helm
  • grpc [>= 1.8 ]

Это должно быть недопустимой комбинацией (поскольку требования helm не удовлетворены), и большинство менеджеров отдела выдаст сообщение об ошибке, сообщающее вам о конфликте (учитывая, что helm изложил свои требования в некоторых формат).

Это важный пункт критики MVS и vgo. Он не хочет позволять зависимостям заявлять, когда у них есть проблема с конкретной версией , чтобы избежать необходимости полного решения SAT . Вы можете обратиться к разделам Theory и Excluding Modules в статье MVS для получения дополнительных пояснений.

MVS не хочет признавать эту возможность (или, по крайней мере, хочет ограничить возможность диктовать ее текущим модулем) в предположении, что SemVer всегда соблюдается и поэтому в этом нет необходимости, что практически не всегда так. Я бы сослался на вашу статью об обратной совместимости , чтобы показать, почему придерживаться обратной совместимости сложно и нецелесообразно, когда вас вынуждают идти по пути vgo.

Решение MVS состоит в том, чтобы попросить разработчика модуля указать, какие версии следует исключить, игнорируя знания, которыми могут поделиться авторы зависимостей об этих несовместимостях. Таким образом, на разработчика возлагается обязанность знать и выполнять запутанную логику, через которую проходит большинство менеджеров отдела, чтобы выяснить, какие версии каких зависимостей совместимы друг с другом (т. е. решение SAT).

Если люди волшебным образом не начнут соответствовать SemVer, я могу представить себе установку зависимости при использовании vgo для преобразования в эксцентричное упражнение, где после импорта модуля вам нужно будет проверить файл README, чтобы скопировать список несовместимых версий, чтобы включить их в вашем файле go.mod . Имейте в виду, что оператор exclude настоящее время принимает только одну версию.

@Меровиус

В сообщении в блоге @mattfarina они преднамеренно описывают обновление Helm до grpc v1.4.0, что эквивалентно обновлению go.mod . Вопрос не в том, как dep или vgo избегают этой проблемы, а в том, как они позволяют автору библиотеки справиться с ней. В случае dep они могут выпустить патч, который добавляет ограничение grpc<v1.4.0 . Для пользователей, у которых нет другой зависимости от grpc, это просто сработает. Если пользователь уже обновился до последней версии helm и имеет другую зависимость от grpc>=v1.4.0 , это ограничение приведет к сбою сборки; не идеально, но лучше, чем слегка нарушенное поведение во время выполнения.

Имея vgo , есть ли у сопровождающих Helm какие-либо эквивалентные варианты? Если пользователь по какой-либо причине обновил grpc до версии 1.4.0, MVS всегда будет выбирать [email protected] , Helm будет сломан, и сопровождающие Helm ничего не смогут с этим поделать (за исключением корректировки изменившегося поведения, что часто кропотливый). Я не могу говорить за @mattfarina , но именно так я прочитал высказанную озабоченность и разделяю ее. С dep и подобными системами промежуточные библиотеки могут защищаться (или чаще восстанавливаться) от нарушений совместимости с верхними ограничениями.

@ibrasho @mattfarina

Похоже, что один из примеров Расса в докладе GopherconSG охватывает очень похожий (может быть, идентичный?) сценарий.

В сообщении выше вы говорите, что helm зависит от "grpc [>= 1.0, < 1.4]". Но это не совсем точно. Я думаю, вы имеете в виду, что какая-то конкретная версия helm зависит от «grpc [> = 1.0, < 1.4]». Допустим, версия helm 2.1.3; предположительно эта версия helm была выпущена после grpc 1.4 (иначе он не знал бы, что помечен как несовместимый с grpc 1.4). Смысл Расса в этом выступлении заключается в том, что предыдущая версия helm (скажем, 2.1.2) предположительно (пока) не помечала себя как несовместимую с grpc 1.4.

Другими словами, удовлетворительным заданием (согласно dep) было бы helm = 2.1.2, grpc = 1.8. Деп мог правильно выбрать это назначение версии без ошибки, так как оно удовлетворяет всем ограничениям для заданных версий.

@balasanjay

Версия Хельма принципиально не меняет пример. [email protected] может объявить зависимость от [email protected], а пользователь helm может иметь зависимость от [email protected] напрямую или через какой-либо другой пакет. В этом сценарии MVS дает сбой и устанавливает [email protected] и [email protected]. Кроме того, в этом примере предполагается, что пользователь намеренно обновляет до [email protected] (и, следовательно, [email protected]) и, возможно, даже до [email protected] , [email protected] и т. д. до того, как проблема будет обнаружена.

MVS намеренно запрещает исключения из промежуточных зависимостей для достижения своих теоретических целей:

Отрицательные последствия (X → ¬ Y, что эквивалентно ¬ X ∨ ¬ Y: если X установлен, то Y не должен быть установлен) не могут быть добавлены...

Для этого примера нам нужно выразить, если X= helm>= 2.1.3 установлен, то Y= grpc>=1.4.0 не должен быть установлен, что мы не можем сделать по дизайну.

По сути, только пакет верхнего уровня (путем исправления поломки) и пользователи нижнего уровня (путем добавления исключений вручную) имеют какое-либо обращение в случае нарушения правил совместимости. Промежуточные продукты, такие как Helm, должны работать со всеми будущими версиями любых зависимостей, что, на мой взгляд, значительно снижает ценность таких библиотек.

Возможно, это будет способствовать лучшему поведению в интенсивно используемых библиотеках, таких как grpc и aws-sdk-go, потому что все стороны почувствуют всю тяжесть любого сбоя, и его будет сложнее обойти. Однако это не всегда так просто. Что, если «поломка» на самом деле не поломка, а допустимое изменение поведения, имеющее непредвиденные последствия для одних пользователей, но полезное для других? Подобные вещи не являются чем-то необычным, и авторы основной ветки по праву не решались бы отменить изменение в этом сценарии.

Я не думаю, что я был почти так же ясен, как Расс. Дай мне попробовать снова.

Изначально состояние deps выглядит так.
Шлем 2.1.2: grpc >= 1.0

Затем выпускается grpc 1.4. Разработчики Helm понимают, что существует несовместимость, и выпускают новую версию Helm:
Шлем 2.1.3: grpc >= 1.0, < 1.4

Я запускаю новое приложение, которое зависит от Helm и какой-то новой функции grpc (ради аргумента). Я перечисляю следующие deps:
Шлем >= 2.0.0
грпс >= 1,4

Вышеупомянутое утверждение заключалось в том, что dep заметит неотъемлемый конфликт и сообщит об ошибке.

Но Расс указал, что это неправда, потому что существует присвоение версий без конфликтов. В частности, dep может использовать helm 2.1.2 и grpc 1.4. По словам депа, это правильное назначение, потому что helm 2.1. 3 несовместим с grpc 1.4, тогда как 2.1. 2 совместим со всеми grpc >= 1.0.

Другими словами, dep мог _правомерно_ решить "исправить" конфликт, понизив версию до версии, которая еще не зафиксировала конфликт. Если у вас есть неизменяемые версии, то это кажется неизбежным. Поэтому кажется, что деп тоже неправильно обработает https://codeengineered.com/blog/2018/golang-vgo-broken-dep-tree/.

@balasanjay Конечно, но в конце концов Helm выпускает 2.2.0 с удобной новой функцией, которую вы хотите, и вы пытаетесь обновить, и тогда возникает проблема.

(Я с осторожным оптимизмом смотрю на то, что это сработает, если у vgo будет хорошо спроектированный UX, чтобы люди знали , что их результат MVS имеет «конфликт» такой формы. Под «хорошо спроектированным» я имею в виду, что он побуждает людей иметь дело с проблема вместо того, чтобы просто быть в порядке с большим количеством предупреждений все время.)

Я, конечно, согласен с тем, что бывают ситуации, когда dep обнаружит конфликт, но просто хотел прояснить, что это _не_ тот, который представлен в этом сообщении в блоге (или, по крайней мере, не с текущими требованиями к версии).

И FWIW, я думаю, разумно поставить под сомнение эффективность защиты, если она сломается на относительно простом примере конфликта.

Для справки, я отследил пример Расса (он во многом идентичен этому, во впечатляющей степени): https://youtu.be/F8nrpe0XWRg?t=31m28s

Re: выбор минимальной версии, не могу понять, как разрешить следующую ситуацию:

Представьте себе популярную библиотеку в режиме ожидания, например, версия 1.2.3 существует уже больше года без каких-либо изменений. Многие другие библиотеки зависят от него.
Появляется разработчик и реализует оптимизацию скорости для версии 1.2.3. Это ускоряет работу ядра библиотеки в 10 раз без изменения API! Это выпущено как v1.3.0. Больше ошибок в этом пакете на следующий год не обнаружено.

Как зависимые лица получают это обновление? Они могут работать с v1.2.3, но v1.3.0 явно лучше.

@даурниматор

Как зависимые лица получают это обновление?

Для каждого приложения необходимо установить 1.3.0 в качестве минимальной версии для использования.

Ну что за глупый сегодня день! 😄

Это предложение активно обсуждалось более двух месяцев.

Эта проблема была открыта в течение многих лет, и сроки, установленные для всего этого, были искусственно короткими, учитывая все обстоятельства.

Было два возражения против этого предложения, с которыми, как нам кажется, нам следует поговорить:

  1. В предложении не предусмотрено техническое решение для всех возможных сценариев, связанных с несовместимостью.

Если это намек на позиции, которые я изложил Рассу, то это вводящая в заблуждение карикатура. Одна из причин, по которой я так долго собирал свои мысли по этой теме, заключается в том, что постоянное использование вводящих в заблуждение аргументов и утверждений... откровенно говоря, дестабилизирует ситуацию.

Буквально никто не думает, что можно охватить ВСЕ возможные сценарии. Проблема в том, и всегда была в том, что MVS решает только _иллюзорную_ проблему (избегая SAT), вместо нее создает _новые_ проблемы, которые имеют гораздо большее значение на практике, и не может эффективно функционировать как промежуточный уровень, на котором мы можем разумно работать.

Они точны в своих наблюдениях, но работают по назначению. Авторам и пользователям кода придется изменить некоторые методы использования и выпуска библиотек, точно так же, как разработчики адаптировались к другим деталям Go, таким как запуск gofmt.

Ничего не помогает упрощение степени предлагаемых здесь изменений путем сравнения их с запуском gofmt — возможно, самой бессмысленной деятельностью, которую мы выполняем как разработчики Go.

Как отметил Расс в своем недавнем выступлении на Gophercon Singapore, единственное постоянное решение проблемы несовместимости — это совместная работа над устранением несовместимости и поддержанием экосистемы пакетов Go. Временные обходные пути в таких инструментах, как vgo или dep, должны работать достаточно долго, чтобы дать разработчикам время для решения реальной проблемы, и vgo достаточно хорошо справляется с этой задачей.

Давайте внесем ясность: важно _сообщество_. Нас. Люди, которые создают экосистему программного обеспечения. Мы улучшаем экосистему, создавая инструменты, которые помогают нам тратить наши ограниченные токены на полезное сотрудничество, а не создавая хрупкие инструменты, которые в первую очередь наказывают нас за участие.

@Меровиус :

Меня отложили до гипотетического будущего поста в блоге. Отсюда мое разочарование, потому что я действительно не понимаю, откуда взялась идея, что у vgo почему-то больше проблем с людьми, нарушающими семантику их версий, чем у dep.

Сбор всех этих аргументов требует времени, и это не моя повседневная работа. Я собирался закончить сегодня вечером, но я все еще на последнем этапе редактирования. 😢Завтра утром...? Ничто не установлено в камне!

Проблема в том, и всегда была в том, что MVS решает только иллюзорную проблему (избегая SAT),...

С уважением, ИМХО решение SAT - это не решение, поэтому для меня MVS решает вполне реальную проблему.

ИМХО решение SAT - это не решение, поэтому для меня MVS решает вполне реальную проблему.

Хотелось бы понять причину этого, если это возможно?

Эта проблема была открыта в течение многих лет, и сроки, установленные для всего этого, были искусственно короткими, учитывая все обстоятельства.

Я вижу здесь две явно противоречащие друг другу идеи. Опросы неоднократно показывали, что управление зависимостями нуждается в решении раньше, чем позже. Однако шестимесячного срока недостаточно для рассмотрения и утверждения предложения.

Я понимаю, что мы не должны выбирать первое решение для реализации. Но время — один из факторов. Контрпредложение vgo еще не определено четко, и, скорее всего, на его воплощение в жизнь уйдут годы. В любой день я бы предпочел vgo в Go 1.11 превосходному решению на основе SAT в Go 1.14.

Это также предполагает, что то, что реализует vgo, высечено в камне. Насколько нам известно, vgo мог значительно измениться в окнах 1.12 и 1.13.

Хотелось бы понять причину этого, если это возможно?

Это та же самая причина, по которой регулярное выражение Go предпочитается PCRE, т.е. не позволяя программе зависеть от алгоритма, имеющего квадратичную/экспоненциальную сложность в худшем случае.

Мы должны иметь в виду, что vgo просто заменит go get больше ничего. Мы должны сравнивать vgo с go get , а не vgo с чем-то несуществующим. "Чем хуже, тем лучше"! Теперь сосредоточимся на деталях реализации.

FWIW, ИМО вполне возможно ввести верхние границы без полного решателя SAT - просто невозможно сделать сгенерированное решение оптимальным или гарантировать, что существующее решение будет найдено. Если нужно, можно

  1. Сделать возможным указать верхние границы
  2. Игнорировать их при решении через MVS
  3. Проверяйте найденное решение на соответствие всем ограничениям и квакайте, если оно не подходит (это ключевое отличие: традиционные подходы вместо этого попытаются найти другое решение)

Это будет означать, что вы получаете преимущества MVS (простой алгоритм без патологического времени выполнения), сохраняя возможность помечать несовместимости и обнаруживать их статически, но вы отказываетесь от гарантии всегда находить решение, если оно существует. Хотя можно возразить, что решение, которое вы найдете, на самом деле таковым не является, потому что несовместимость все еще существует, просто неизвестная алгоритму.

Так что, по крайней мере, мне кажется, что вполне возможно модифицировать какой -то способ, чтобы получить верхние границы для MVS. Я все еще не уверен, что это действительно необходимо, но если это окажется так, его всегда можно добавить позже. Сделать утверждение «МВС принципиально непригодным» проблематичным. Но я все еще могу неправильно понять проблему. А может быть есть сценарий отказа, лучше иллюстрирующий это?

@sdboyer Не беспокойтесь. Как я уже сказал, я полностью понимаю, что это не ваша повседневная работа, и я ценю время, которое вы тратите на участие. Это все еще практический вопрос «если мы не знаем аргументов, мы не можем о них говорить». Могу себе представить, что вы так же расстроены всей этой ситуацией, как и я :)

Это та же самая причина, по которой регулярное выражение Go предпочитается PCRE, т.е. не позволяя программе зависеть от алгоритма, имеющего квадратичную/экспоненциальную сложность в худшем случае.

@cznic Я считаю, что управление зависимостями - это не только техническая проблема, оно переплетено с социальными ограничениями и соображениями. Поэтому я не уверен, что сравнение его с регулярными выражениями (чисто техническая проблема реализации) и предпочтение алгоритма, в основном основанного на временной сложности, является справедливым подходом.

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

Мне интересно, есть ли у людей другие причины предпочесть его алгоритму на основе SAT.

Мне было интересно, есть ли у людей другие причины предпочесть его алгоритму на основе SAT.

@ibrasho MVS не нужен файл блокировки.

Мне интересно, есть ли у людей другие причины предпочесть его алгоритму на основе SAT.

Лично мои причины

  1. Он объединяет файл блокировки и манифест в один файл, который в значительной степени можно редактировать на компьютере. В общем случае это означает меньше шума, но при этом получать воспроизводимые (или «высокоточные») сборки. AFAICT это что-то уникальное для MVS. Поскольку одним из моих главных разочарований в других менеджерах пакетов является трудоемкость редактирования файлов манифеста, для меня это огромно.
  2. Постепенный ремонт станет проще/сделается возможным. Поскольку я твердо верю в этот подход к решению проблемы распределенной разработки, это также важно для меня.
  3. Это может помочь экосистеме коллективно оставаться близкой к HEAD для большинства библиотек. Это в значительной степени предположение и в некоторой степени зависит от доступного инструментария. Но если «вытащить все до последней версии» достаточно просто, это может увеличить частоту, с которой новые версии библиотек тестируются друг против друга в производстве.
  4. Он достигает всего этого, сохраняя или превосходя желаемые качества других подходов, AFAICT. Обновления происходят только при желании. И бинарные пакеты будут продолжать собираться, даже если сборка некоторых из их зависимостей будет нарушена в новой версии, что даст автору время для работы над исправлением.

Особенно эта последняя часть немного иронична. Потому что именно это качество было обозначено как чрезвычайно важное в последнем посте @sdboyer , но на данный момент я все еще считаю, что vgo в этом отношении строго лучше, чем традиционные подходы.

@Меровиус
«Он объединяет файл блокировки и манифест в один файл»

  • это не совсем так, поскольку манифесты фактически разбросаны по всем вашим файлам. Операторы импорта фактически действуют как манифесты.

@docmerlin Когда я сказал «манифест», я имел в виду файл со списком всех модулей, от которых вы зависите, с их соответствующими версиями (в частности, он содержит строго больше информации, чем операторы импорта, иначе он вам не понадобится). В случае vgo это будет go.mod , в случае dep это Gopkg.toml . Вы также можете назвать это файлом конфигурации для решателя зависимостей. Если вы считаете более подходящим другой термин, не стесняйтесь заменять им манифест, когда читаете мой комментарий.

Обратите внимание, что вполне нормально иметь как файл со списком всех зависимостей, так и список явных импортов (которые являются потенциально строгим подмножеством зависимостей) для каждого файла. В частности, все менеджеры зависимостей Go, о которых я знаю, делают это. В других подходах также используется файл блокировки, который описывает конкретные точные версии, используемые для обеспечения воспроизводимых сборок. И отличительная особенность MVS, о которой я говорил, заключается в том, что этот файл не нужен, потому что он может быть однозначно получен из файла manifest/dependency-solver-config/go.mod.

(удалено+репостировано из личного кабинета)

@cznic акцент на классах сложности MVC по сравнению с подходом на основе SAT в отдельности не имеет смысла (как я думаю, @sdboyer где-то пишет - мы увлеклись разговором об этом, потому что это одна из немногих вещей, которые мы можем имя/идентификация).

Предложение @bradfitz в # 25483 для решения некоторых проблем с vgo (которое я считаю изначально сумасшедшим, но, возможно, отличным практичным решением) включает в себя запуск тестов от произвольных пользователей вашего API перед выпуском. В целом это NP-полная проблема, но на практике она может быть отличным решением (как и gps2).

Итак, с одной стороны, у нас есть алгоритмы управления пакетами на основе SAT, а с другой стороны, у нас есть алгоритм в NL, который заставляет нас выполнять NP-полную работу позже (или тайм-аут, что сделал бы любой практический SAT-решатель). для враждебных файлов блокировки).

сосредоточение внимания на классах сложности MVC по сравнению с подходом на основе SAT в отдельности не имеет смысла...

Я не уверен, откуда взялся термин «фокус». Просто если есть два доступных алгоритма, один из которых в худшем случае является квадратичным или хуже, а другой — линейным или лучше, я выбираю последний и избегаю первого. Я бы назвал это принципом, а не фокусом.

... предложение в # 25483 решить некоторые проблемы с vgo ...

Похоже, проблема № 25483 не связана с vgo. Опечатка?

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

@cznic конечно, обычно, если два алгоритма дают одинаковые результаты, вам нужен алгоритм с меньшей сложностью (хотя это даже не всегда так просто и сухо - Python использует сортировку вставками для небольших входных данных, потому что, несмотря на худшие границы сложности, он лучше константы + время выполнения до определенного момента).

В этом случае (MVS против алгоритмов на основе SAT) результаты намеренно различаются и имеют широкие последствия. Я предполагаю, что из-за этого вы не можете просто сравнивать алгоритмическую сложность, вам нужно учитывать их более широкое влияние.

Похоже, проблема № 25483 не связана с vgo.

Первая строка в этом выпуске — это ссылка на комментарий Брэда в этом выпуске: https://github.com/golang/go/issues/24301#issuecomment -390788506. Хотя этот инструмент будет полезен за пределами vgo, похоже, что он в основном рассматривается для смягчения некоторых недостатков MVS (на мой взгляд/понимание).

Ой, сколько комментариев. Я постараюсь добавить некоторые детали и историю, чтобы помочь.

Пару лет назад было несколько различных решений для управления зависимостями (например, godep, glide и т. д.). Чтобы выяснить путь вперед, произошло несколько вещей:

  1. Группа вложенных и знающих людей объединилась в комитет . Обратите внимание, что в эту группу входил член рабочей группы Google.
  2. Вторая группа людей, создавших менеджеры зависимостей или располагавшая информацией о них, поддержала первую группу.
  3. Был проведен опрос сообщества о потребностях и мыслях о существующих инструментах (в Go и вне Go) . Обратите внимание, что некоторые результаты были закрыты только для глаз комитета.
  4. Компании, использующие Go для производства, были опрошены, чтобы получить подробную информацию об их потребностях. Подробности этого не разглашаются, поэтому люди могут говорить свободно.

Все данные опроса и интервью были отправлены обратно в комитет. Изучив данные и обсудив их, они решили, что нам нужно решение с определенными функциями, и создали спецификацию . После этого разработка на dep стала удовлетворять эти потребности.

В прошлом году на Gophercon состоялся саммит участников , на котором об этом говорили люди, инвестировавшие в управление зависимостями. Ближе к концу этих разговоров Расс подошел к столу и сказал что-то вроде: «У меня получится лучше, если я пойду сам и что-нибудь построю». Он сделал это и придумал vgo. Это было сделано отдельно от сообщества.

Отвечает ли vgo потребностям людей, выраженным в опросах и интервью? Из того, что я узнал от Расса, он не читал результатов, но раскритиковал процесс. Возможно, кому-то стоит сделать картографию.

О, на саммите Расс поделился одной из причин, в то время ему не нравился SAT-решатель. Ему нужно было решение с меньшим количеством строк кода, потому что он не хотел, чтобы команда Go в Google была на крючке за поддержку такого большого количества кода. Я помню это именно потому, что после этого я провел несколько сравнений LOC между dep, glide и другими инструментами, чтобы лучше понять различия.

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

Нет, #25483 не имеет отношения к vgo. Я просто перечислил это навскидку как еще одну вещь, которую может сделать гипотетическая вспомогательная команда go release . Но это было бы полезно в любое время.

Моя главная мысль заключалась в том, что Go никогда не упрощал выпуск пакетов Go. В прошлой жизни я написал http://search.cpan.org/dist/ShipIt/ для автоматизации выпусков пакетов Perl CPAN, и это имело огромное значение, когда у вас есть инструменты для таких вещей, а не вручную.

Я вообще упомянул гипотетический go release только потому, что меня спросили , что Go может сделать по-другому, чтобы помочь людям не совершать ошибок.

Единственная актуальная проблема, которую я вижу с vgo, кажется тривиальной для решения... проблема с максимальной версией. Если одна библиотека выходит из строя с v1.7 dep, нет другого способа указать это, кроме исключения... который помогает только до тех пор, пока не выйдет v1.8, который, вероятно, все еще не работает точно так же.

Кажется, было бы тривиально добавить максимальную версию в vgo просто как способ помочь vgo определить, когда две библиотеки несовместимы. Если одна библиотека говорит, что ей нужна как минимум версия 1.7, а другая говорит, что ей нужно

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

Ограничения максимальной версии @natefinch выталкивают MVS с его очень умной территории, позволяющей избежать SMT-решателя.

Я думаю, что @natefinch означает максимальное количество версий в качестве окончательной проверки/фильтра. Как только MVS выполнит свою работу, vgo выдаст ошибку, если какое-либо из этих ограничений максимальной версии не будет выполнено. Это все еще не приводит нас на территорию решателя SAT.

Точно. Нет решения. Просто «vgo говорит, что 1.7 — это то, что нужно использовать, но модуль X заявляет, что он не работает с этой версией». Это уже то, что может произойти сегодня с vgo, если у вас есть что-то, что говорит require foo 1.7 и что-то еще говорит exclude foo 1.7 , если нет более высокой версии foo.

И что тогда ты должен делать?

Вы используете свой человеческий мозг, чтобы найти решение, потому что механического решения не существует. Вы пытаетесь использовать две библиотеки, которые категорически заявляют, что им требуются несовместимые версии библиотеки. A сломается с 1,6, B сломается с 1,7. Конец.

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

Нет хорошего ответа. Но в мире нет инструментов, которые могли бы исправить это за вас.

@sdboyer

Проблема в том, и всегда была в том, что MVS решает только иллюзорную проблему (избегая SAT),

Я не могу говорить о ваших личных беседах с Рассом, но «избегание SAT» кажется мне пустым аргументом. «Избегание SAT» является не большей целью, чем «использование SAT»: ни то, ни другое не оказывает никакого конкретного влияния на пользователей.

На мой взгляд, конкретные проблемы, которые решает MVS, таковы:

  • создание воспроизводимых сборок по умолчанию,
  • создание как можно более близкого к протестированным версиям, и
  • избегая ложных отказов.

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

Я согласен. Но я хочу подробнее рассмотреть ваши предположения: какие инструменты «наказывают» участие и почему?

Один из примеров, который вы привели в своем посте, звучал так: «Сейчас наш проект зависит от [email protected] , но он не работает с [email protected] или новее. Мы хотим быть хорошими гражданами и адаптироваться, но сейчас у нас просто нет пропускной способности».


Первое (неявное) предположение, которое вы делаете, заключается в том, что у вас (или ваших пользователей) есть время и пропускная способность для исчерпывающего тестирования вашего проекта на соответствие всем выпускам его зависимостей.¹ Для некоторых проектов это предположение само по себе может не выполняться. : устанавливая ожидание, что все отмечают верхние границы при обнаружении несовместимости, вы в конечном итоге «наказываете» сопровождающих, у которых нет пропускной способности для тестирования регрессий и обновления границ потенциально для всех своих выпусков.

Напротив, в MVS сопровождающие обязаны заявить только одно: «Мы тщательно протестировали [email protected] , и это сработало». Если ваши пользователи ничего не делают, чтобы нарушить это, они строятся против [email protected] , и все продолжает работать, как и раньше.

В MVS _обрыв происходит только во время явного обновления._ Это существенное преимущество: если ваш пользователь обновляет какую-то другую зависимость, так что она втягивает [email protected] и прерывает использование вашего пакета, то они могут просто отмените это обновление до тех пор, пока у вас не будет времени исправить его, _или пока у сопровождающего X не будет времени исправить несовместимость._ И при правильных ожиданиях последнее может быть гораздо более вероятным, чем первое: вырезание [email protected] может оказаться ненужной работой, если [email protected] восстановит совместимость.


Второе предположение, которое вы делаете, заключается в том, что каждая несовместимость, затрагивающая _любую часть_ вашего модуля, затрагивает _всех пользователей_ вашего модуля. Если часть вашего пакета, которая выходит из строя под [email protected] , является малоиспользуемой функцией, зачем удерживать ваших пользователей от обновления X в их программе, которая даже не вызывает ее?

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


¹ В общем, для обнаружения несовместимости с зависимостями требуется, чтобы вы проверили _перекрестное произведение всех выпусков_ этих зависимостей: возможно, ваше конкретное использование [email protected] нормально, но оно не работает в сочетании с каким-то другим пакетом, от которого вы зависите. на. Например, возможно, вам и вашей зависимости требуются несовместимые параметры в глобальной конфигурации.

они могут просто отказаться от этого обновления

Это предполагает, что это ошибка компилятора или что-то подобное. Скорее всего, это тонкая поведенческая ошибка, которая не сразу бросается в глаза. Вы обновляете, запускаете тесты, и все выглядит хорошо. Возможно, тайм-аут, который был 10 секунд, теперь равен 30, и это сбрасывает тайм-ауты в остальной части вашего стека при нагрузке. Вы не заметите, пока он не будет запущен в производство (что-то подобное произошло с нами с изменением mgo несколько лет назад).

Если часть вашего пакета, которая ломается в [email protected] , является малоиспользуемой функцией, зачем удерживать ваших пользователей от обновления X в их программах, которые даже не вызывают его?

Потому что они, вероятно, не будут знать, используют ли они эту функцию или нет, если это транзитивная зависимость, и кто может сказать, что какой-то неиспользуемый кодовый путь не будет внезапно активирован в будущем, когда вы измените свой код? Итак, эта сломанная функция теперь вызывается. Гораздо лучше доверять специалисту по сопровождению библиотеки, который является экспертом в понимании своей собственной библиотеки, и если он скажет, что она не работает с 1.7, не стройте с 1.7.

Это предполагает, что это ошибка компилятора или что-то подобное. Скорее всего, это тонкая поведенческая ошибка, которая не сразу бросается в глаза.

Почти в каждой версии почти каждого программного пакета есть незаметные ошибки. Обычно мы не помечаем выпуски как полностью непригодные только потому, что нашли одну такую ​​ошибку; вместо этого мы исправим это в более позднем выпуске.

Что делает этот конкретный класс ошибок особенным?

кто сказал, что какой-то неиспользуемый кодовый путь не будет внезапно активирован в будущем, когда вы измените свой код?

Это в точности аргумент MVS: если вы измените свой код, вы обнаружите поломку _в этой версии_, и вы также можете обновить ограничение версии в этой версии.

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

Что делает этот конкретный класс ошибок особенным?

Это не просто ошибка. Это больше, чем это. Автор библиотеки, который является главным специалистом по их коду, сказал миру: «Эй, версия 1.7 X ломает мои вещи настолько плохо, что даже не стройте с ней».

Ясно, что если это не ошибка компилятора, то это суждение. Если 99 ваших функций паникуют, а одна нет... это просто ошибка? Или это полная несовместимость? Что, если паникует только одна функция?

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

Это не просто ошибка. Это больше, чем это. Автор библиотеки, который является главным специалистом по их коду, сказал миру: «Эй, версия 1.7 X ломает мои вещи настолько плохо, что даже не стройте с ней».

У автора библиотеки есть еще один способ выразить это: написать тест, который дает сбой при использовании с несовместимой версией X. Преимущество этого заключается в том, что не требуется никаких изменений в библиотеке, если X выпускает исправленную версию, а также отлавливаются любые будущие регрессии.

Напишите тест, который не работает при использовании с несовместимой версией X.

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

Есть причина, по которой go test ./... не запускает тесты в каталоге поставщика.

Подводя итог (вероятно, плохо), кажется, что главный технический аргумент против vgo заключается в том, что у библиотек должен быть способ объявлять глобально соблюдаемые ограничения для своих собственных зависимостей.

Почему бы обеим сторонам не согласиться санкционировать конкурирующее предложение, в котором исследуется, как GPS2 может вписаться в части vgo, которые нравятся обеим сторонам. Затем тем временем объединить эксперимент vgo и пересмотреть предложение GPS2 до того, как vgo объединит основную ветку?

Как человек, который в прошлом боролся со многими инструментами зависимостей, я в восторге от vgo. FWIW, как член «сообщества», я чувствую себя хорошо представленным решением vgo far. Тем не менее, я по-прежнему открыт для рассмотрения аргументов в пользу добавления ограничений глобальной версии и с нетерпением жду дальнейшего развития этого аргумента.

Просто бросаю это туда:

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

Это проблема программного обеспечения в целом. NPM (другой инструмент управления версиями, с которым я лично знаком больше всего) использует решатель SAT в сочетании с сообществом, которое активно поддерживает semver, и эта проблема все еще существует.

Что касается обсуждения транзитивных зависимостей, реальность такова, что волшебной палочки не существует: в какой-то момент разработчик должен знать о зависимостях, которые он использует, и тратить время на надлежащее тестирование кода, за который он в конечном итоге отвечает. Мой работодатель не может быть единственным, где мы обязаны оправдывать каждую библиотеку, которую мы используем, включая транзитивные библиотеки, по юридическим и другим причинам.

Честно говоря, на мой взгляд, многие жалобы на vgo кажутся «он не идеален, поэтому не будет работать». Давайте не преминем реализовать хорошее решение из-за отсутствия идеального решения.

Мне кажется, что это очень согласуется с общей философией Go, когда основная команда предоставляет инструмент, который хорош в большинстве ситуаций, оставляя на усмотрение сообщества предоставление более продвинутых и/или специфических инструментов.

@malexdev Может быть проблема с вашими актерами в аргументе, что:

Давайте не преминем реализовать хорошее решение из-за отсутствия идеального решения.

dep сегодня является хорошим решением. Тот, который был создан сообществом, работающим вместе. vgo, как и было сказано ранее, делает несколько предположений:

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

vgo больше основан на «идеальном решении» в «идеальном мире», в то время как dep сегодня работает, следуя тому, что уже работает в экосистеме других языков программирования, сохраняя при этом отказоустойчивость.

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

Подводя итог (вероятно, плохо), кажется, что главный технический аргумент против vgo заключается в том, что у библиотек должен быть способ объявлять глобально соблюдаемые ограничения для своих собственных зависимостей.

Я согласен с этим резюме.

Почему бы обеим сторонам не согласиться санкционировать конкурирующее предложение, в котором исследуется, как GPS2 может вписаться в части vgo, которые нравятся обеим сторонам.

На данный момент я не убежден, что GPS2 является необходимостью или даже хорошей идеей. Способность, которую вы описали выше, может быть модифицирована для vgo поверх MVS (например, так или так ). Лично я надеюсь, что следующий пост в блоге @sdboyer будет содержать веские аргументы против самого MVS, но сейчас я действительно не вижу причин для другого алгоритма, особенно такого, который стоил бы существенных преимуществ UX от vgo.

Хотя, честно говоря, я тоже не вижу причин против экспериментов с этим.

dep сегодня является хорошим решением.

Я не уверен, что согласен. Сам я им не пользовался, но там было несколько человек, жалующихся на проблемы, которые, по-видимому, напрямую связаны с его подходом к решению SAT. И я знаю, что я очень недоволен общим дизайном отдела (не говоря уже о самом решателе зависимостей, общем рабочем процессе и UX).

  1. Что никто и никогда не сорвется с семвера, даже случайно

Извините, но я неоднократно просил обоснования этого заявления и не получил. Почему vgo предполагал это каким-либо образом, формировал или формировал больше, чем dep? Я в корне не согласен с этим утверждением. Это предположение сделано для объяснения алгоритма. Точно так же, как если бы вы объяснили алгоритм dep, вы бы объяснили предположения, встроенные в семантические версии. В худшем случае они показывают те же поломки, если вы не соблюдаете эту семантику.


Я думаю, что в целом имеет смысл различать разные части того, о чем мы говорим. Некоторые жалобы относятся к SIV, некоторые к MVS и некоторые к общей оболочке vgo. Например, верно то, что MVS не может обрабатывать верхние границы версий, но это не означает, что vgo не может обрабатывать верхние границы версий. SIV требует изменения большого количества кода (путем переписывания операторов импорта), но опять же, это даже не обязательно означает, что vgo потребует этого. Хотя, чтобы быть ясным, я также не думаю, что это так уж важно, пока мы можем мигрировать. Какой AFAICT мы можем.

Я только что посмотрел вступительный доклад @rsc GopherConSG о версиях. Он рассмотрел сценарий, в котором зависимость вносит критическое изменение, и сравнил, как vgo и dep справятся с этим, что, по-видимому, является здесь главной проблемой. (Это отличные часы.)

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

@willfaught Для нас удаление сборки, когда используется максимальное ограничение версии, чтобы избежать плохой версии, считается успехом! Это то, что мы хотим , чтобы произошло. Расс правильно отмечает, что эта проблема не решается автоматически. Ограничение на Helm>2.0.0 не будет автоматически обновлять пользователя до " [email protected] ", но оно будет работать успешно (понизить версию grpc или вызвать сбой сборки, если это невозможно), если пользователь явно зависел от "Helm". == 2.1.4". Лично я обычно первым делом, когда сталкиваюсь с проблемой в библиотеке, принудительно обновляюсь до последней версии. С Dep это информировало бы меня о сбое, вызванном GRPC 1.4.0. С vgo Helm может сообщить мне об этом только через документацию.

Повторю мысль, потому что она по-прежнему непонятна: ни dep , ни vgo не могут предотвратить возникновение этой проблемы или обеспечить надежное решение. Скорее, dep позволяет Helm сообщить , что проблема существует, а vgo — нет.

Подводя итог (вероятно, плохо), кажется, что главный технический аргумент против vgo заключается в том, что у библиотек должен быть способ объявлять глобально соблюдаемые ограничения для своих собственных зависимостей.

Я бы добавил немного красок в это резюме, поскольку эти ограничения необходимы, чтобы иметь дело с несчастливым путем, когда правила совместимости нарушаются. vgo устанавливает правило совместимости импорта, а затем приступает к разработке решения, предполагая, что это правило всегда соблюдается. В этом идеализированном мире потребность в верхних границах ограничена или даже отсутствует. В реальном мире этого не произойдет: разработчики будут выпускать обновления, нарушающие совместимость, намеренно или нет.

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

Это восстанавливает путь для промежуточных библиотек, чтобы сообщать конечным пользователям о несовместимости. Чтобы повторить пример helm еще раз:

Пользователь @ 1.1 : Шлем @2.1.2
Шлем@2.1.2 : GRPC @1.3.5

==> Пользователь намеренно обновляется до [email protected] .

Пользователь: Helm @2.1.3, [email protected] ("Helm обновлен, теперь я наконец-то могу использовать grpc 1.4!")
Шлем: GRPC @1.4.0

==> Обнаружена ошибка! Пользователь наблюдает некоторые проблемы с Helm, поэтому проверьте наличие новой версии.

Пользователь: [email protected] , [email protected]
Шлем: GRPC @1.3.5, слабый GRPC <1.4.0

Пользователь видит предупреждение о том, что GRPC 1.4.0 отклоняется при установке [email protected]. Поскольку у меня Helm не работает, и я пытаюсь это исправить, я удаляю свою зависимость от GRPC 1.4.0 (к сожалению, теряя некоторые полезные функции) и перезапускаю MVS. На этот раз MVS разрешает GRPC в 1.3.5 и Helm в 2.1.4, перепроверяет все слабые ограничения, обнаруживает, что они выполняются, и все готово.

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

@willfaught Для нас удаление сборки, когда используется максимальное ограничение версии, чтобы избежать плохой версии, считается успехом! Это то, что мы хотим, чтобы произошло.

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

Вы действительно должны увидеть видео, в котором показан отличный пример, но вот суть, как я ее понял/запомнил:

  • Версии пакетов (включая их требования к зависимостям) неизменяемы.
  • Чтобы добавить максимальное ограничение версии к существующей зависимости для вашего пакета, вы должны опубликовать новую версию вашего пакета.
  • Возможно, что dep выберет предыдущую версию вашего пакета, чтобы удовлетворить все требования, и в этом случае ваше новое максимальное ограничение версии не будет присутствовать. Это позволяет в конце концов использовать плохую версию.

Я в основном согласен с предложением добавить максимальное количество исключений версий, но у меня есть одно беспокойство: предположим, я добавлю в свою библиотеку «использовать gRPC > 1.4, <1.8», а затем в gRPC 1.9 авторы решают: «Знаете что, Helm был правильно, мы внесли критическое изменение в 1.8, мы возвращаемся к нашему предыдущему поведению в 1.9.0». Теперь люди, пытающиеся импортировать Helm+gRPC, не смогут использовать 1.9, пока Helm не выпустит версию, в которой говорится: «используйте gRPC > 1.4, кроме 1.8.0, 1.8.1, 1.8.2, но 1.9+ — это круто».

Другими словами, может быть достаточно exclude grpc 1.8 , потому что мы не узнаем, будет ли gRPC 1.9 несовместимым или нет, пока он не будет опубликован, после чего Helm может либо добавить его в список исключений, либо нет.

Я практически ничего не знаю об этом пространстве. Но, читая обсуждение здесь, кажется, что самые большие разногласия сводятся к тому, как обнаруживать ошибочные случаи. То есть и MVS (vgo), и SAT (dep) более или менее хорошо справляются с обычными ситуациями, возможно, не одинаково, но достаточно хорошо.

SAT предоставляет возможность, которой нет у MVS: с помощью SAT автор пакета библиотеки P1 может объявить: «P1 требует P2 и работает с P2Version > 1.1 и P2Version < 1.4». MVS может только объявить «P1 требует P2 и работает с P2Version > 1.1» и не может выразить ограничение «P2Version < 1.4». В обычном случае это не имеет значения. Это имеет значение только в том случае, если какая-то операция пытается обновить P2 до версии 1.4. В этом случае SAT сообщит об ошибке, а MVS — нет. При использовании MVS, если несовместимость не является ошибкой компиляции, она может привести к сбою спустя долгое время.

Несомненно, сторонники SAT видят и другие серьезные проблемы с MVS, но пока это то, что я понимаю.

Я думаю, стоит отметить, что если сами выражения ограничения версионированы — если они являются частью определенного выпуска P1 — то при обычном ходе событий, до выпуска P2 версии 1.4, P1 версии 2.2 с радостью скажет «P2Version». > 1,1". Только когда будет выпущена версия 1.4 P2, авторы P1 заметят несовместимость и выпустят версию 2.3 P1 с "P2Version > 1.1 и P2Version < 1.4". Таким образом, если вы используете P1 версии 2.2, ни SAT, ни MVS не сообщат о каких-либо проблемах с обновлением P2 до версии 1.4, хотя это, возможно, приведет к неявному сбою.

Другими словами, несмотря на то, что в выпуске P1 имеет смысл перечислять минимальные совместимые версии P2, если выпуск корректно работает с самой последней версией P2, то в выпуске не имеет смысла указывать максимально совместимые версии. . Максимальная совместимая версия будет либо консервативной, и, следовательно, все более неправильной по мере появления новых и лучших версий P2, либо, если P2 изменится каким-либо несовместимым образом в будущем, не сможет указать это требование, поскольку на момент выпуска оно не указано. т существует.

Поэтому, если мы хотим иметь систему, определяющую что-либо помимо минимальных требований к версии, то эти требования не должны быть частью конкретного выпуска, а вместо этого должны быть частью какого-то рода метаданных, связанных с пакетом, метаданных, которые можно получить в в любое время без обновления самого пакета. А это значит, что операция «обновить этот пакет» должна быть отделена от операции «проверить, совместимы ли мои текущие версии пакетов».

Я бы сказал далее — и это определенно более неубедительно, чем вышесказанное — что если «проверить, совместимы ли мои текущие версии пакетов» не удается, то в целом неразумно доверять какому-либо инструменту для решения проблемы. Если проблема совместимости не может быть решена простой операцией «обновить каждый соответствующий пакет до текущей версии», то она требует размышлений. Инструмент может направлять эту мысль, но в целом не может ее заменить. В частности, кажется очень неразумным, чтобы инструмент автоматически запускал понижение версии пакетов.

Итак, если мы думаем о

  1. способ определения метаданных пакета, описывающих несовместимость пакетов
  2. на основе этого инструмент, который сообщает, совместимы ли ваши текущие пакеты

тогда, возможно, некоторые из основных различий между MVS и SAT станут менее важными.

Спасибо, что так хорошо сказал, Ян. В дополнение, после того, как мы установили версии и vgo, мы обязательно хотим иметь новый godoc.org (возможно, с другим именем), который записывает дополнительную информацию о пакетах, информацию, к которой может обращаться команда go. И часть этой информации будет парной несовместимостью, о которой команда go может сообщать в виде предупреждений или ошибок в любой конкретной сборке (то есть сообщать о повреждении, а не пытаться скрыть его, обходя его). Но наличие версий в основной цепочке инструментов — это первый шаг, и это, наряду с минимальными требованиями к версиям и семантическим импортом версий, — это то, что было принято в этом выпуске.


Мы стремимся сделать это как можно более плавным. Для этого потребуются дополнительные инструменты, больше образовательных программ и PR для устранения проблем в существующих пакетах. Все это было заблокировано на принятии этого предложения, поскольку казалось самонадеянным продвигаться вперед без принятия общего подхода. Но предложение принято, и теперь, когда неопределенность миновала, работа пойдет более активно.

У меня была такая же мысль о внешней информации для совместимости версий ... поскольку совместимость версий должна быть постоянной для всех , она не должна находиться в системе управления версиями (и на самом деле наличие системы управления версиями является определенным недостатком, как указано выше). Было бы неплохо, если бы для этого было предложено решение, так как это определенно кажется одной из основных проблем с MVS, как было предложено.

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

@ianlancetaylor , я думаю, вы правильно поняли это замечание о необходимости иметь возможность вносить изменения в информацию об ограничениях в уже выпущенных версиях. Как указал @rsc , такую ​​услугу мы обсуждали/предлагали на наших встречах. Мы могли бы сделать это с помощью godoc.org или чего-то еще, конечно. Но я на самом деле не думаю, что это влечет за собой отдельную услугу, и было бы лучше без нее. Я кратко упомянул об этом в статье, которую я опубликовал в пятницу (прямо с этого якоря). По крайней мере, в службе есть вопросы, на которые затем нужно ответить о том, чье объявление о несовместимости должно отображаться в предупреждениях, что означает обработку удостоверений и как мы применим объявления к конкретным ситуациям в depgraph. Сохранение объявлений внутри файлов метаданных означает, что нам не нужно ни о чем беспокоиться. Но об этом через секунду.

Что действительно важно здесь, так это этот момент, хотя, возможно, не так, как вы это хотели:

возможно, некоторые из основных различий между MVS и SAT становятся менее важными.

Предложение мета-инструмента, который выполняет этот поиск — да, это поиск SAT — в качестве решения проблем, которые люди идентифицируют, говорит о многом. Это именно то, во что нам придется превратить dep, если MVS пойдет дальше, как описано. И первое, что нужно отметить, это то, что если мы настолько обеспокоены этими несовместимостями, что говорим об инструменте поиска, то на самом деле мы говорим, что MVS становится просто шагом в более крупном алгоритме, а Преимущества Grokkability сразу бросаются в глаза.

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

Вот почему я утверждал, что MVS — это неподходящий промежуточный слой, на котором можно построить инструмент более высокого порядка, подобный этому — «не соответствующий цели». Понятно, что люди верят, что эти несовместимости будут возникать, поэтому MVS просто берет сложную проблему и усложняет ее.

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

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

(обратите внимание, я буду в отпуске на этой неделе, поэтому не буду отвечать до следующих выходных)

@sdboyer

Предложение мета-инструмента, который выполняет этот поиск - да, это поиск SAT

Можете быть более конкретными? Предложение, которое вы цитируете, следует сразу после того, как Ян предлагает инструмент для сообщения о совместимости выбранных версий - и, насколько мне известно, это основная альтернатива, предложенная здесь (это, безусловно, то, что я имел в виду выше). Эта проблема определенно не является поиском, она тривиальна и не требует решения SAT (это просто оценка булевой формулы для заданного набора значений, а не попытка найти значения, которые ему удовлетворяют).

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

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

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

28 мая 2018 г., 16:02:13 по восточноевропейскому времени, Аксель Вагнер, [email protected] , написал:

@sdboyer

Предложение мета-инструмента, который выполняет этот поиск - да, это
спутниковый поиск

Можете быть более конкретными? Предложение, которое вы цитируете, идет сразу после Иэна.
предлагая инструмент, чтобы сообщить , являются ли выбранные версиисовместимы - и, насколько мне известно, это главное
альтернатива, предложенная здесь (это, безусловно, то, что я имел в виду выше).
Эта проблема определенно не является поиском, она тривиальна и
не требует решения SAT (это просто оценка булевой формулы
для данного набора значений, не пытаясь найти значения, которые ему удовлетворяют).

--
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую или просмотрите его на GitHub:
https://github.com/golang/go/issues/24301#issuecomment-392595150

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

Для ясности: предложение модифицировать верхние границы таким образом является чистой реакцией на высказанные опасения и показывает, что это можно сделать (чтобы подвергнуть критическому сомнению утверждение о том, что MVS принципиально непригоден для этой цели). Кажется немного несправедливым воспринимать эту уступку и готовность идти на компромисс как доказательство того, что мы все время думали, что вы были правы.

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

Однако, хотя я считаю эти опасения обоснованными и справедливыми, я не думаю, что они превышают планку доказательства того, что MVS принципиально непригоден. Я по-прежнему считаю, что MVS в качестве отправной точки привносит в таблицу хорошие и важные функции. И что, если эти опасения окажутся причинить существенную боль на практике, есть еще много способов, которыми мы можем это исправить — от добавления верхних границ (будь то часть go.mod или как отдельная служба) до чистых сбоев вплоть до добавления полного SAT-решателя и блокировки файлов в какой-то момент. Т.е. я согласен с вами, что эти вещи произойдут, но а) я (возможно, наивно) настроен оптимистично, что они не причинят столько боли, как вы ожидаете, и б) что это решаемые проблемы, даже если мы начнем с MVS.

Мне приходит в голову, что что-то за пределами контроля версий, определяющее совместимость, может изменить детерминизм системы MVS. Если у вас есть foo >= 1.5.0 в качестве ограничения в одной библиотеке, а в другой lib есть foo >= 1.6.0. Затем поместите эти два файла в двоичный файл, и они выберут 1.6.0. В MVS это все, что вам нужно для воспроизводимой сборки. он всегда будет выбирать 1.6

Но если вы добавите в смесь внешнюю совместимость, то вы можете обновить эту первую библиотеку, чтобы сказать, что она несовместима с 1.6, а затем алгоритм выберет 1.7, даже если код не изменился... Это означает, что вам понадобится файл блокировки снова.

Для справки: я не думаю, что файл блокировки — это плохо. Приятно иметь четкий список того, что именно вам нужно построить. И это должно сделать его быстрым. Не нужно магической логики.

@natefinch Если файл go.mod приложения был обновлен для требования версии 1.7.0, поскольку внешний инструмент совместимости указал, что версия 1.6.0 несовместима, вам не понадобится файл блокировки. Поскольку указание версии 1.7.0 находится в файле go.mod, автор может также добавить комментарий о том, почему используется версия 1.7.0, и эта информация будет полезна читателям.

@leighmcculloch , если какие-либо файлы в приложении обновлены, то это другая сборка, которая полностью выходит за рамки проблемы «воспроизводимой сборки без файла блокировки».

предлагается внеплановая информация о совместимости, чтобы отразить развитие знаний: о несовместимостях не было известно во время выпуска, но затем это стало очевидным, и публикуется дополнительная информация об уже выпущенных версиях. ИМХО по определению такой подход приводит к изменению того, как вытягиваются зависимости, иначе зачем вообще извлекать информацию о несовместимости?

@redbaron @natefinch

Смысл информации о несовместимости заключается в том, чтобы авторы библиотек сообщали информацию о несовместимости своим пользователям. Другой вопрос, используется ли эта информация при сборке или во время выпуска.

В случае с vgo текущая идея состоит в том, чтобы отображать только предупреждения (или, возможно, каркать). Но, в частности, не позволять этому влиять на выбор используемых версий (поскольку это потребует решения SAT). Так что на самом деле это не имеет значения, вы можете использовать его в любом из них или в обоих, и он будет отлично выполнять свои обязанности, сохраняя при этом свойство повторяемости¹.

В свою очередь, эта информация используется только во время выпуска, а затем записывается в файл блокировки, который используется во время сборки. Таким образом, кажется, что мы в любом случае рассматриваем использование во время выпуска как «достаточно хорошее», по крайней мере, когда речь идет о проблемах vgo и dep.

Я все еще не думаю, что мы должны на самом деле отвечать на эти вопросы прямо сейчас.


[1] Лично я бы сказал, что лучше использовать его во время выпуска и только в том случае, если -v используется во время сборки, потому что пользователю не нужно решать, является ли предупреждение действенным или нет.

@rsc написал:

В дополнение, после того, как мы установили версии и vgo, мы обязательно хотим иметь новый godoc.org (возможно, с другим именем), который записывает дополнительную информацию о пакетах, информацию, к которой может обращаться команда go. И часть этой информации будет парной несовместимостью, о которой команда go может сообщать в виде предупреждений или ошибок в любой конкретной сборке (то есть сообщать о повреждении, а не пытаться скрыть его, обходя его).

Меня интересует, нужно ли записывать попарную несовместимость. В настоящее время я вижу это так: любая несовместимость между модулем A@vN и модулем B@vM на самом деле связана с тем, что B сделал несовместимое изменение из некоторой версии vL, где L < M.

Если модуль B не вносил несовместимых изменений, то модуль A просто содержит ошибку. Если да, то проблема в самом Б, а не в паре А и Б.

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

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

Набора кортежей вида ( module , oldVersion , newVersion , description ) может быть достаточно.

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

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

Я беспокоюсь, что go release становится «достаточно умным компилятором» в этом обсуждении. Что конкретно могут ожидать пользователи от go release в Go 1.11/12? Я думаю, что это имеет значение для разумных ожиданий в отношении MVS/SIV.

Спасибо за энергию, которую многие из вас вложили в Go и, в частности, в это предложение.

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

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

Теперь, когда предложение принято, этот вопрос больше не является подходящим местом для обсуждения, и мы больше не обновляем сводку. Вместо этого, пожалуйста, отправляйте новые, целенаправленные вопросы о проблемах, с которыми вы сталкиваетесь, или конкретные предложения по изменениям, чтобы мы могли целенаправленно обсуждать каждую конкретную тему. Пожалуйста, добавляйте к этим новым проблемам префикс «x/vgo:». Если вы упомянете № 24301 в тексте нового выпуска, то здесь будут даны перекрестные ссылки, чтобы другие могли их найти.

И последний момент: принятие предложения означает принятие идеи, а не ошибок реализации прототипа и всего остального. Есть еще детали, которые нужно проработать, и ошибки, которые нужно исправить, и мы продолжим делать это вместе.

Еще раз спасибо за вашу помощь.

Предстоит проделать еще много работы (см. метку модулей ), но первоначальная реализация модуля, предложенная в этом выпуске, была зафиксирована в главном дереве, поэтому я закрываю этот выпуск.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги