Подтвердить что ты не робот

Автоматическое определение GOPATH на основе каждого проекта

Для каждого проекта, который я создаю, я должен делать export GOPATH={path_to_project} каждый раз, когда я cd в директорию проекта. Должен быть более простой способ. Не могу ли я создать файл .bashrc или .bash_profile для данного каталога, чтобы определить GOPATH для этого проекта?

Например, у меня есть два проекта перехода A и B. Если у меня есть единственный GOPATH, который не переопределяется при переходе между проектами, тогда двоичные файлы для обоих проектов будут храниться в одном месте. Что еще более важно, двоичные файлы для сторонних библиотек будут храниться в одном и том же месте, поэтому я не могу поддерживать несколько версий одной и той же библиотеки для каждого проекта.

Однако, если я могу определить GOPATH для каждого проекта, тогда все двоичные файлы и библиотеки сторонних разработчиков зависят от проекта. Это, по-видимому, общий способ управления пакетами в большинстве других языковых сред (ruby rbenv, python vertiualenv и т.д.).

4b9b3361

Ответ 1

У вас есть аналогичная идея, выраженная в Управлять несколькими дисками GOPATH с легкостью, Герберт Фишер (hgfischer), для среды Linux/Unix (база вопроса уже упоминается в комментариях выше):

Просто включите следующий фрагмент в ~/.bashrc (или ~/.bash_profile) и перезагрузите среду оболочки с помощью источника ~/.bashrc.
Этот фрагмент создаст функцию оболочки, которая переопределит встроенную команду cd с настраиваемой версией, которая сканирует введенный каталог и все остальные выше для файла с именем .gopath.

cd () {
    builtin cd "[email protected]"
    cdir=$PWD
    while [ "$cdir" != "/" ]; do
        if [ -e "$cdir/.gopath" ]; then
            export GOPATH=$cdir
            break
        fi
        cdir=$(dirname "$cdir")
    done
}

Теперь вам просто нужно создать файл .gopath в каждом каталоге, который вам нужен, как ваш GOPATH, и каждый раз, когда вы входите в этот каталог, переопределенная cd функция установит GOPATH вашей текущей среды на этот каталог.


Обновление 2017: если вы не хотите изменять свою среду, вы все равно можете использовать один GOPATH для каждого проекта, открыв папку src этого проекта в коде Visual Studio (vscode, который является многоплатформенной средой IDE), в сочетании с расширением " Перейти для кода Visual Studio".

В этой среде IDE вы можете:

  • сохраните свой глобальный уникальный GOPATH в настройке с именем go.toolsGopath.
  • выведите текущий GOPATH с помощью параметра go.inferGopath

Настройки пользователя vscode

Таким образом, VSCode установит набор инструментов в вашем глобальном GOPATH (для вас также использовать внешний VSCode).
См. " Инструменты Go, которые зависят от расширения Go: godep, golint, guru, godoc,...

И все же ваш GOPATH для вашего проекта будет родительской папкой src:

local GOPATH

Это работает, когда вы компилируете/устанавливаете свой проект из среды IDE.
Если вы хотите сделать это из командной строки, исходный ответ выше будет применяться.

Ответ 2

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

В ваших целях пример файла /happy/go/path/yay/.env может выглядеть так:

export GOPATH="/happy/go/path/yay"
export PATH="$GOPATH/bin:$PATH"

Ответ 3

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

#!/bin/bash
# infer-gopath.sh

pwd

И затем, в .bash_aliases (или где бы вы не сохранили свои псевдонимы):

alias go='GOPATH=$(infer-gopath.sh) go'

Это устанавливает GOPATH для всех infer-gopath.sh выходов только для вызова команды go, поэтому он не будет иметь долговременного эффекта для вашей оболочки.

Ответ 4

Мое впечатление, что инструмент go активно препятствует "поддерживать несколько версий одной и той же библиотеки на основе каждого проекта" по той причине, что опыт показал, что эта стратегия не работает на больших кодовых базах (например, в Google). Было довольно много обсуждений о версиях пакетов на golang-nuts: (искать в списке), и кажется, что обсуждение все еще открыто, как указал Ян Лэнс Тейлор в этом интервью 6 июня 2013 г. (поиск слова "управление версиями" ).

Система упаковки go предназначена для того, чтобы каждый проект имел свою собственную структуру каталогов; единственным ограничением является то, что все они должны быть дочерними (некоторым) каталогом в GOPATH. Это имеет то преимущество, что он хорошо взаимодействует с системами управления версиями, если только мастер VCS всегда строит. В интервью в блоге, упомянутом выше, ILT предлагает:

Что мы делаем внутренне, это сделать снимок импортированного кода и время от времени обновлять этот снимок. Таким образом, наша база кода не будет неожиданно ломаться, если API изменится.

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

Если вы действительно хотите иметь отдельный GOPATH для каждого проекта, я бы предложил следующее:

1) Сделайте каждый проект GOPATH завершенным в каталоге с именем go (или некоторых таких)

2) Выделите GOPATH с помощью чего-то вроде следующей функции оболочки (почти полностью непроверенной):

gopath() {
  GOPATH="$(
    ( while [[ $PWD != / && $(basename $PWD) != go ]]; do
        cd ..
      done
      if [[ $PWD == / ]]; then
        echo $GOPATH
      else
        echo $PWD
      fi
    ))" go "[email protected]"
}

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

Ответ 5

Я не могу комментировать, но для того, чтобы построить ответ от @joshlf:

alias go, добавив GOPATH - мой метод не требует, чтобы вы занимались/создавали дополнительный файл:

alias go='GOPATH=$(echo $(pwd)) go'

веселит

Ответ 6

Мне нравится кишок ответа gopath() выше, но мне не нравится (a) наличие GOPATH, установленного только для go (я использую его в vim-плагинах и т.д.), и мне не нравится (b) не запоминать тип GOPATH вместо go:)

Вот что я в конечном итоге добавил в свой ~/.bash_profile:

export GOPATH="... a default path ..."
function cd() {
  builtin cd [email protected] &&
  export GOPATH="$(
    ( while [[ $PWD != / && $(basename $PWD) != go ]]; do
        cd ..
      done
      if [[ $PWD == / ]]; then
        echo $GOPATH
      else
        echo $PWD
      fi
    ))"
}

(Я также написал выше с небольшим дополнительным обсуждением требований в этом сообщении в блоге)

Ответ 7

Я новичок Golang, но лучший способ сделать это - это, вероятно, создать оболочку script в каждом из ваших проектов, построить/запустить проект и поместить этот script в свой проект root:)

#!/usr/bin/env bash

// get absolute path to the directory which contains this script
PROJECT_DIR=$(cd $(dirname $0) && pwd)

// set GOPATH as you wish, then run go build
GOPATH=${GOPATH}:${PROJECT_DIR} && cd ${PROJECT_DIR} && go build

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