Pour chaque projet que je crée, je dois faire export GOPATH={path_to_project}
chaque fois que je cd dans le répertoire du projet. Il doit y avoir un moyen plus facile. N'y a-t-il pas moyen de créer un fichier .bashrc ou .bash_profile pour un répertoire donné afin de définir GOPATH pour ce projet?
Par exemple, j'ai deux projets A et B. Si j'ai un GOPATH singulier qui n'est pas redéfini lorsque je passe d'un projet à un autre, les fichiers binaires des deux projets seront stockés au même endroit. Plus important encore, les fichiers binaires des bibliothèques tierces seront stockés au même endroit. Par conséquent, je n'ai aucun moyen de gérer plusieurs versions de la même bibliothèque pour chaque projet.
Cependant, si je suis en mesure de définir GOPATH pour chaque projet, tous les binaires et toutes les bibliothèques tierces dépendent du projet. Cela semble être la manière habituelle de gérer la gestion des paquets dans la plupart des autres environnements de langage (Ruby rbenv, python vertiualenv, etc.)
(T2 2018: Notez qu'avec le projet vgo (maintenant "module"), le projet , GOPATH
pourrait finir par être obsolète au profit d'un flux de travail basé sur un projet. Cela éviterait la GOPATH
basée sur un projet manuel Je proposais ci-dessous, il y a deux ans)
Avec Go 1.11 (août 2018), GOPATH
peut être facultatif, avec les modules .
Vous avez une idée similaire exprimée dans Gérer plusieurs répertoires GOPATH avec facilité , par Herbert Fischer (hgfischer
) , pour un environnement Linux/Unix (base sur la question mentionne déjà dans les commentaires ci-dessus):
Incluez simplement l'extrait de code suivant dans votre
~/.bashrc
(ou~/.bash_profile
) et rechargez votre environnement Shell avecsource ~/.bashrc
.
Cet extrait créera une fonction Shell qui remplacera la commande intégréecd
par une commande personnalisée qui analysera le répertoire entré, ainsi que tous les autres, pour un fichier nommé.gopath
.
cd () {
builtin cd "$@"
cdir=$PWD
while [ "$cdir" != "/" ]; do
if [ -e "$cdir/.gopath" ]; then
export GOPATH=$cdir
break
fi
cdir=$(dirname "$cdir")
done
}
Maintenant, il vous suffit de créer un fichier
.gopath
dans chaque répertoire de votre choix commeGOPATH
et chaque fois que vous entrez dans ce répertoire, la fonction redéfiniecd
définira laGOPATH
de votre environnement actuel sur ce répertoire.
Mise à jour 2017: si vous ne souhaitez pas modifier votre environnement, vous pouvez toujours utiliser une GOPATH
par projet, en ouvrant le dossier src
de ce projet dans le code Visual Studio ( vscode , qui est un IDE multi-plateforme). , combiné avec l’extension " Go for Visual Studio Code ".
Dans cet IDE, vous pouvez:
GOPATH
globale unique dans un paramètre appelé go.toolsGopath
.GOPATH
actuelle avec un paramètre appelé go.inferGopath
De cette façon, VSCode installera une collection d’outils dans votre GOPATH
globale (que vous pourrez également utiliser en dehors de VSCode).
Voir " Outils Go dont dépend l’extension Go ": godep
, golint
, guru
, godoc
, ...
Et pourtant, votre GOPATH
pour votre projet sera le dossier parent de src:
Cela fonctionne lorsque vous compilez/installez votre projet à partir de l'EDI.
Si vous voulez le faire depuis la ligne de commande, la réponse originale ci-dessus s'appliquerait toujours.
Vous pouvez utiliser un outil tel que autoenv pour configurer un script qui s’exécute automatiquement lorsque vous cd
dans un répertoire particulier.
Pour vos besoins, un exemple de fichier /happy/go/path/yay/.env
pourrait ressembler à ceci:
export GOPATH="/happy/go/path/yay"
export PATH="$GOPATH/bin:$PATH"
Je voudrais écrire un script qui peut déduire le bon GOPATH du répertoire actuel, puis aliaser la commande go
pour appeler d’abord ce script. Par exemple, une implémentation très simple:
#!/bin/bash
# infer-gopath.sh
pwd
Et ensuite, dans .bash_aliases (ou où que vous gardiez vos alias):
alias go='GOPATH=$(infer-gopath.sh) go'
Ceci définit GOPATH
sur les sorties infer-gopath.sh
uniquement pour l'invocation de la commande go
, de sorte que cela n'aura aucun effet durable sur votre shell.
Mon impression est que l'outil go
décourage activement le "maintien de plusieurs versions de la même bibliothèque sur une base par projet" pour la raison précise que l'expérience a montré que cette stratégie ne fonctionne pas sur des bases de code volumineuses (telles que celles de Google). Il y a eu beaucoup de discussions sur la gestion des versions de paquets sur les golang-nuts: ( recherchez dans la liste ), et il semble que la discussion soit toujours ouverte, comme indiqué par Ian Lance Taylor Le 6 juin 2013 interview (recherche du mot "versioning").
Le système de packaging go
est conçu pour permettre à chaque projet d’avoir sa propre structure de répertoires; la seule restriction est qu'ils doivent tous être enfants de (certains) répertoires dans GOPATH
. Cela présente l'avantage de bien interagir avec les systèmes de contrôle de version, tant que le maître VCS est toujours construit. Dans l'interview de blog référencée ci-dessus, ILT suggère:
Ce que nous faisons en interne est de prendre un instantané du code importé et de le mettre à jour de temps à autre. De cette façon, notre base de code ne sera pas interrompue de manière inattendue si l'API change.
Substituer "le code importé" à "mes autres bibliothèques", cela semble être une possibilité; vous pouvez avoir deux répertoires go
, production et développement; pour le développement, vous pouvez placer le répertoire de développement en premier dans le chemin afin que les fichiers binaires et les bibliothèques de développement ne polluent pas les répertoires de production. Je ne sais pas si cela suffit.
Si vous voulez vraiment avoir une GOPATH
distincte pour chaque projet, je vous suggère ce qui suit:
1) Faites en sorte que la GOPATH
de chaque projet se termine dans un répertoire nommé go
(ou quelque chose du genre)
2) Déduisez la GOPATH
en utilisant quelque chose comme la fonction Shell suivante (presque totalement non testée):
gopath() {
GOPATH="$(
( while [[ $PWD != / && $(basename $PWD) != go ]]; do
cd ..
done
if [[ $PWD == / ]]; then
echo $GOPATH
else
echo $PWD
fi
))" go "$@"
}
Ensuite, vous pouvez utiliser gopath
au lieu de go
tant que votre répertoire de travail actuel se trouve quelque part dans le référentiel du projet. (Des possibilités plus sophistiquées peuvent inclure l’utilisation du chemin de projet explicitement fourni, le cas échéant, pour déduire GOPATH
.)
Je sais que ce n’est pas très intelligent, mais je trouve que si je vais simplement dans le répertoire de base du projet go où j’ai les dossiers src, pkg et bin, je peux simplement taper:
export GOPATH=$(pwd)
et c'est tout bon!
Je ne peux pas commenter, mais pour reprendre la réponse de @joshlf :::
alias go
en préfixant la GOPATH
- ma méthode n'exige pas que vous traitiez/créiez un fichier supplémentaire:
alias go='GOPATH=$(echo $(pwd)) go'
à votre santé
Je suis un newb Golang, mais la meilleure façon de le faire serait probablement de créer un script Shell dans chacun de vos projets, de construire/exécuter votre projet et de placer ce script à la racine de votre projet :)
#!/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
ce script devrait fonctionner même si vous l'exécutez à partir d'un répertoire qui n'est pas la racine du projet.
J'aime les tripes de la réponse de gopath () ci-dessus , mais je n'aime pas (a) le fait que GOPATH
soit défini uniquement pour la commande go
(je l'utilise dans les plugins vim, etc.), et je n'aime pas non plus ( b) ne pas oublier de taper gopath
au lieu de go
:)
C'est ce que j'ai finalement ajouté à mon ~/.bash_profile
:
export GOPATH="... a default path ..."
function cd() {
builtin cd $@ &&
export GOPATH="$(
( while [[ $PWD != / && $(basename $PWD) != go ]]; do
cd ..
done
if [[ $PWD == / ]]; then
echo $GOPATH
else
echo $PWD
fi
))"
}
(J'ai aussi écrit ce qui précède avec une petite discussion supplémentaire sur les exigences dans cet article de blog )