Go mod init не работает

Приступить к инициализации модуля без VCS/Git с невозможностью определить путь к модулю

Я пытаюсь инициализировать новый проект go с модулем go (с помощью go 1.11). Я не планирую публиковать его в github или в другом месте, это всего лишь временный/тестовый проект с основным пакетом.

Всякий раз, когда я пытаюсь запустить go mod init в каталоге (вне моего $GOPATH ), я получаю эту ошибку:

go: cannot determine module path for source directory/Users/. (outside GOPATH, no import comments)

Невозможно ли запустить модуль без использования git (или другого VCS)? Или есть обходное решение?

ОТВЕТЫ

Ответ 1

Разве невозможно инициализировать модуль без использования git (или другого VCS)? Или же есть ли обходной путь?

Да, можно запускать модули без использования VSC, при инициализации модуля не нужно ничего делать с git или любым другим VCS.

Эта ошибка возникает, когда имя модуля не введено, пока init модуль, поэтому для генерации модуля modulename напишите эту команду.

Читайте также:  Как настроить фов рук

Содержание go.mod будет

EDIT:

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

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

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

Теперь, когда вы сделаете go build , он будет искать этот локальный модуль в том месте, которое вы указали в файле мода основного проекта.

Источник

Go: go.mod file not found in current directory or any parent directory; see ‘go help modules’

Помощь в написании контрольных, курсовых и дипломных работ здесь.

QtCreator returns error “Cannot change to working directory”: file or directory not found
В Options->Environment->Terminal указываю «qterminal -e»; Если убирать запуск в терминале, то пишет.

Could not search modules: No such file or directory
Добрый день. Подскажите пожалуйста, как решить эту ошибку: could not search modules: No such file.

Ошибка 29: File .MYD not found (Errcode: 2 — No such file or directory)
Всем вечера! Проблема прилетела откуда не ждали, и когда не ждали Суть: на сервере крутится.

Silverlight онлайн соединение с БД и ошибка «404 — File or directory not found»
Привет. Помогите пожалуйста, я уже неделю голову ломаю, скоро нервы уже не выдержат. Перечитал.

Сначала (с этой версии так пошло) нужно дать команду в каталоге проекта: go mod init (если проект не планируется никуда выкладывать). Потом в получившийся файл модуля (go.mod) нужно прописать зависимости командой: go mod tidy.

И вот только потом собирать и/или отлаживать из IDE.

ЗЫЖ Мне лично такой процесс очень неудобен, но для кровавого энтерпрайза, говорят, очень надо 🙂

Источник

Управление пакетами с помощью модулей Go: Прагматическое руководство

Всем привет. В преддверии старта курса «Разработчик Golang» подготовили для вас еще один интересный перевод.

Модули — это способ борьбы с зависимостями в Go. Изначально представленные в качестве эксперимента, модули предполагают вывести на поле в качестве нового стандарта для управления пакетами с версии 1.13.

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

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

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

Быстрый запуск

Если в ваш проект уже интегрировано управление версиями, вы можете просто запустить

Или указать путь к модулю вручную. Это что-то вроде имени, URL и пути импорта для вашего пакета:

Эта команда создаст файл go.mod , который одновременно определяет требования проекта и лочит зависимости на их правильные версии (в качестве аналогии для вас, это как package.json и package-lock.json , объединенные в один файл):

Запустите go get , чтобы добавить новую зависимость в ваш проект:

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

Теперь наш файл go.mod выглядит следующим образом:

Суффикс +incompatible добавляется ко всем пакетам, которые еще не настроены под модули Go или нарушают их правила управления версиями.

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

В зависимости от текущего состояния вашего репозитория, она либо удалит неиспользуемый модуль, либо удалит комментарий // indirect .

Если какая-либо зависимость сама по себе не имеет go.mod (например, она еще не настроена под модули), тогда все ее зависимости будут записаны в родительский файл go.mod (как вариант, ваш файл go.mod) вместе с комментарием // indirect , чтобы указать, что они там не от прямого импорта в ваш модуль.

В глобальном плане цель go mod tidy состоит также в добавлении любых зависимостей, необходимых для других комбинаций ОС, архитектур и тегов сборки. Обязательно запускайте ее перед каждым релизом.

Следите также за тем, чтобы после добавления зависимости был создан файл go.sum . Вам может показаться, что это lock-файл. Но на самом деле go.mod уже предоставляет достаточно информации для на 100% воспроизводимых сборок. Файл go.sum создается в проверочных целях: он содержит ожидаемые криптографические контрольные суммы содержимого отдельных версий модуля.

Отчасти потому, что go.sum не является lock-файлом, он сохраняет записанные контрольные суммы для версии модуля даже после того, как вы перестанете использовать этот модуль. Это позволяет проверять контрольные суммы, если вы позже возобновите его использование, что обеспечивает дополнительную безопасность.

FAQ: Должен ли я коммитить go.sum в git?
A: Определенно да. С ним обладателям ваших источников не нужно доверять другим репозиториям GitHub и владельцам пользовательских путей импорта. Уже на пути к нам нечто получше, ну а пока это та же модель, что и хэши в lock-файлах.

Команды go build и go test , автоматически загрузят все отсутствующие зависимости, хотя вы можете сделать это явно с помощью go mod download , чтобы предварительно заполнить локальные кэши, которые могут оказаться полезными для CI.

По умолчанию все наши пакеты из всех проектов загружаются в каталог $GOPATH/pkg/mod . Мы обсудим это подробнее позже.

Обновление версий пакетов

Вы можете использовать go get -u или go get -u=patch для обновления зависимостей до последней минорной версии или патча соответственно.

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

  • Соответствовать semver (пример тега VCS v1.2.3).
  • Если модуль версии v2 или выше, мажорная версия модуля должна быть включена как /vN в конце пути модуля, используемого в файле go.mod , и в пути импорта пакета:

По-видимому, это сделано для того, чтобы разные версии пакетов могли быть импортированы в одной сборке (см. diamond dependency problem).

В двух словах, Go ожидает, что вы будете очень осмотрительны при внесении мажорных версий.

Замена импортированных модулей

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

Вы можете удалить строку вручную или запустить:

Попроектное управление зависимостями

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

Модули Go — это своего рода отступление от этого подхода. Вам больше не нужно хранить все свои проекты в $GOPATH .

Тем не менее, технически все ваши загруженные зависимости все еще помещаются в $GOPATH/pkg/mod . Если вы используете Docker-контейнеры при локальной разработке, это может стать проблемой, поскольку зависимости хранятся вне проекта. По умолчанию они просто не видны в вашей IDE.

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

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

Вариант 1. Установите GOPATH внутри каталога вашего проекта.

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

Популярные IDE должны иметь возможность установить GOPATH на уровне проекта (рабочей области):

Единственный недостаток этого подхода — отсутствие взаимодействия со средой выполнения Go на хост-компьютере. Вы должны выполнять все команды Go внутри контейнера.

Вариант 2: Вендоринг ваших зависимостей

Еще один способ — скопировать зависимости вашего проекта в папку vendor :

Следует сразу отметить: мы НЕ разрешаем Go прямую загрузку материалов в папку vendor: с модулями это невозможно. Мы просто копируем уже загруженные пакеты.

К тому же, если вы отвендорите свои зависимости, как в примере выше, затем очистите $GOPATH/pkg/mod , а затем попробуйте добавить несколько новых зависимостей в ваш проект, вы увидите следующее:

  1. Go перестроит кэш загрузки для всех пакетов по $GOPATH/pkg/mod/cache .
  2. Все загруженные модули будут скопированы в $GOPATH/pkg/mod .
  3. И, наконец, Go скопирует эти модули в vendor папку, удаляя примеры, тесты и некоторые другие файлы, от которых вы напрямую не зависите.

Более того, в этой недавно созданной vendor-папке отсутствует много вещей:

Типичный файл Docker Compose выглядит следующим образом (обратите внимание на привязки томов):

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

Однако, когда я читаю комментарии от некоторых мейнтейнеров Go и некотроые предложения, связанные с частичным вендорингом (ЧЕ?), у меня складывается впечатление, что изначально эта фича предназначалась не для этого юзкейса.

Один из комментаторов на reddit помог мне пролить свет на это:

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

Да, не похоже на что-либо из того, что может меня заинтересовать.

Согласно команде Go, вы можете запросто подключить вендоринг, установив переменную среды GOFLAGS=-mod=vendor . Я не рекомендую так делать. Использование флагов просто сломает go get без предоставления каких-либо других преимуществ для вашего ежедневного рабочего процесса:

На самом деле, единственное место где вам нужно подключить вендоринг — это ваше IDE:

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

Шаг 1. Требование

Вы можете потребовать зависимость с помощью go get :

Шаг 2. Импорт

Затем импортируйте его куда-нибудь в своем коде:

Шаг 3. Вендоринг

Наконец, отвендорите ваши зависимости заново:

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

go mod vendor уже автоматически требует пропущенные импорты, поэтому шаг 1 является необязательным в этом рабочем процессе (если вы не хотите указывать ограничения версии). Однако, без шага 2 она не подхватит загруженный пакет.

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

Лично я думаю, что переопределение GOPATH является более чистым подходом, поскольку он не жертвует функциональность go get . Тем не менее, я хотел показать обе стратегии, потому что папка vendor может быть привычнее для людей, пришедших с других языков, таких как PHP, Ruby, Javascript и т. д. Как вы можете увидеть из махинаций, описанных в этой статье, это не особенно хороший выбор для Go.

Зависимости инструментов

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

Источник

Введение в систему модулей Go

Грядущий релиз версии 1.11 языка программирования Go принесет экспериментальную поддержку модулей — новую систему управления зависимостями для Go. (прим.перев.: релиз состоялся)

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

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

Создание модуля

Первым делом создадим наш пакет. Назовём его «testmod». Важная деталь: каталог пакета следует разместить за пределами вашего $GOPATH , потому что, внутри него по умолчанию отключена поддержка модулей. Модули Go — это первый шаг к полному отказу в будущем от $GOPATH .

Наш пакет весьма прост:

Пакет готов, но он ещё пока не является модулем. Давайте исправим это.

У нас появился новый файл с именем go.mod в каталоге пакета со следующим содержимым:

Немного, но именно это и превращает наш пакет в модуль.

Теперь мы можем запушить этот код в репозиторий:

До сих пор, любой желающий использовать наш пакет применил бы go get :

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

Небольшое отступление о версионировании модулей

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

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

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

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

Давайте это и сделаем.

Делаем свой первый релиз

Наш пакет готов и мы можем «зарелизить» его на весь мир. Сделаем это с помощью версионных меток. Пусть номер версии будет 1.0.0:

Эти команды создают метку в моём Github-репозитории, помечающую текущий коммит как релиз 1.0.0.

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

Теперь мы можем работать в ветке master не беспокоясь, что можем сломать наш релиз.

Использование нашего модуля

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

До сих пор, вы запускали бы go get github.com/robteix/testmod , чтобы скачать пакет, но с модулями становится интереснее. Для начала нам надо включить поддержку модулей в нашей новой программе.

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

Ситуация становится ещё интереснее, когда мы попытаемся собрать нашу программу:

Как видно, команда go автоматически нашла и загрузила пакет, импортируемый нашей программой.
Если мы проверим наш файл go.mod , мы увидим, что кое-что изменилось:

И у нас появился ещё один новый файл с именем go.sum , который содержит хэши пакетов, чтобы проверять правильность версии и файлов.

Делаем релиз релиз с исправлением ошибки

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

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

Обновление модулей

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

А сделаем мы это с помощью нашего старого друга — go get :

запускаем go get -u , чтобы использовать последний минорный или патч- релиз (т.е. команда обновит с 1.0.0 до, скажем, 1.0.1 или до 1.1.0, если такая версия доступна)

запускаем go get -u=patch чтобы использовать последнюю патч-версию (т.е. пакет обновится до 1.0.1, но не до 1.1.0)

запускаем go get package@version , чтобы обновиться до конкретной версии (например, github.com/robteix/testmod@v1.0.1 )

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

Поскольку наша программа использовала версию 1.0.0 нашего пакета и мы только что создали версию 1.0.1, любая из следующих команд обновит нас до 1.0.1:

После запуска (допустим, go get -u ), наш go.mod изменился:

Мажорные версии

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

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

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

Существующие программы, использующие наш API, сломаются, потому что они а) не передают язык в качестве параметра и б) не ожидают возврата ошибки. Наш новый API более не совместим с версией 1.x, так что встречайте версию 2.0.0.

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

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

Всё остальное то же самое: пушим, ставим метку, что это v2.0.0 (и опционально содаём ветку v2)

Обновление мажорной версии

Даже при том, что мы зарелизили новую несовместимую версию нашей библиотеки, существующие программы не сломались, потому что они продолжают исполользовать версию 1.0.1.
go get -u не будет загружать версию 2.0.0.

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

Чтобы обновиться, надо соответствующим образом изменить мою программу:

Теперь, когда я запущу go build , он «сходит» и загрузит для меня версию 2.0.0. Обратите внимание, хотя путь импорта теперь заканчивается на «v2», Go всё ещё ссылается на модуль по его настоящему имени («testmod»).

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

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

Вернёмся к предыдущей версии, которая использует только testmod 2.0.0 — если мы сейчас проверим содержимое go.mod , мы кое-что заметим:

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

Теперь у нас остались только те зависимости, которые мы реально используем.

Вендоринг

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

Команда создаст каталог vendor/ в корне нашего проекта, содержащий исходный код всех зависимостей.

Однако, go build по умолчанию все ещё игнорирует содержимое этого каталога. Если вы хотите собрать зависимости из каталога vendor/ , надо об этом явно попросить.

Я предполагаю, что многие разработчики, желающие использовать вендоринг, будут запускать go build , как обычно, на своих машинах и использовать -mod vendor на своих CI.

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

Есть способы гарантировать, что go будет недоступна сеть (например, с помощью GOPROXY=off ), но это уже тема следующей статьи.

Заключение

Статья кому-то может показаться сложноватой, но это из-за того, что я попытался объяснить многое разом. Реальность же такова, что модули Go сегодня в целом просты — мы, как обычно, импортируем пакет в наш код, а остальное за нас делает команда go . Зависимости при сборке загружаются автоматически.

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

Вендоринг (неофициально) объявлен устаревшим в пользу использования прокси. 1
Я могу сделать отдельную статью про прокси для Go модулей.

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

Источник

Оцените статью