Apakah buruk memiliki direktori virtualenv di dalam repositori git saya?

285

Saya berpikir untuk meletakkan virtualenv untuk aplikasi web Django yang saya buat di dalam repositori git saya untuk aplikasi tersebut. Sepertinya ini cara mudah untuk menjaga penyebaran tetap sederhana dan mudah. Apakah ada alasan mengapa saya tidak melakukan ini?

Lyle Pratt
sumber

Jawaban:

302

Saya menggunakan pip freezeuntuk mendapatkan paket yang saya butuhkan ke dalam requirements.txtfile dan menambahkannya ke repositori saya. Saya mencoba memikirkan cara mengapa Anda ingin menyimpan seluruh virtualenv, tetapi saya tidak bisa.

RyanBrady
sumber
81
Anda dapat menghemat ruang yang tidak perlu di repo Anda dan masih menyebarkan ke server baru dalam satu perintah: virtualenv --tidak-situs-paket --distribusi .env && sumber .env / bin / aktifkan &&pasang install -r requirement.txt
RyanBrady
2
Saya memberi Anda jawaban untuk pertanyaan ini, karena mungkin itu adalah "praktik terbaik" dan Anda menawarkannya terlebih dahulu. Saya pasti menemui beberapa masalah yang disebutkan semua orang. Saya memperkirakan saya memberi diri saya hari lain mengacaukannya sebelum saya hanya melakukan apa yang kalian sarankan selama ini dan menggunakan pip dan file persyaratan. Terima kasih atas bantuan Anda!
Lyle Pratt
11
Jika Anda, katakanlah pip install mysql-python, pada mesin 64 bit, dan kemudian seseorang dengan mesin 32 bit mencoba menggunakannya, itu tidak akan berfungsi. Menggunakan modul C, seperti banyak modul Python lakukan, untuk meningkatkan kinerja. Saya membayangkan Windows-> Linux juga tidak akan berfungsi.
Matt Williamson
7
hanya sebuah komentar: kami mendapat sedikit di masa lalu karena entah bagaimana perpustakaan menjadi tidak tersedia dari pip (versi terlalu lama), memaksa upgrade ketika situs sedang down. jadi ... Saya sekarang tidak akan pernah bergantung pip freezelagi untuk melakukan ini. masalahnya adalah bahwa selama pemindahan kerja paksa Anda yang terpaksa, tidak ada yang membayar untuk itu, dan untuk pemutakhiran menengah (pemeliharaan "praktik terbaik") tidak ada yang melakukan keduanya.
KONTRAK MENGATAKAN AKU BENAR
5
Catatan pada komentar @RayanBrady: Opsi --distributedan --setuptoolssekarang no-op. (distribusikan, itu adalah garpu setuptools telah bergabung sejak lama). --no-site-packagesDIPERLUKAN, sekarang perilaku standar
JackNova
49

Menyimpan direktori virtualenv di dalam git akan, seperti yang Anda catat, memungkinkan Anda untuk menyebarkan seluruh aplikasi dengan hanya melakukan klon git (plus menginstal dan mengkonfigurasi Apache / mod_wsgi). Salah satu masalah yang berpotensi signifikan dengan pendekatan ini adalah bahwa di Linux, path lengkap mendapat hard-coded dalam aktivasi venv, django-admin.py, easy_install, dan skrip pip. Ini berarti virtualenv Anda tidak akan sepenuhnya berfungsi jika Anda ingin menggunakan jalur yang berbeda, mungkin untuk menjalankan beberapa host virtual di server yang sama. Saya pikir situs web sebenarnya dapat bekerja dengan jalur yang salah dalam file-file itu, tetapi Anda akan memiliki masalah saat Anda mencoba menjalankan pip.

Solusinya, sudah diberikan, adalah untuk menyimpan informasi yang cukup di git sehingga selama penyebaran Anda dapat membuat virtualenv dan melakukan instalasi pip yang diperlukan. Biasanya orang lari pip freezeuntuk mendapatkan daftar lalu menyimpannya dalam file bernama requirement.txt. Itu bisa dimuat dengan pip install -r requirements.txt. RyanBrady sudah menunjukkan bagaimana Anda dapat merangkai pernyataan penerapan dalam satu baris:

# before 15.1.0
virtualenv --no-site-packages --distribute .env &&\
    source .env/bin/activate &&\
    pip install -r requirements.txt

# after deprecation of some arguments in 15.1.0
virtualenv .env && source .env/bin/activate && pip install -r requirements.txt

Secara pribadi, saya hanya meletakkan ini di skrip shell yang saya jalankan setelah melakukan git clone atau git pull.

Menyimpan direktori virtualenv juga membuatnya sedikit lebih sulit untuk menangani upgrade pip, karena Anda harus secara manual menambah / menghapus dan mengkomit file yang dihasilkan dari upgrade. Dengan file requirement.txt, Anda hanya perlu mengubah baris yang sesuai di requirement.txt dan menjalankannya kembali pip install -r requirements.txt. Seperti yang sudah disebutkan, ini juga mengurangi "melakukan spam".

David Sickmiller
sumber
4
Perhatikan bahwa --distribusi sekarang sudah tidak digunakan lagi (setidaknya dalam 15.1.0): --distribute DEPRECATED. Retained only for backward compatibility. This option has no effect.
AnthonyC
1
--no-site-packagessudah usang dalam 15.1.0 juga, karena itu sekarang default.
cjs
35

Saya biasa melakukan hal yang sama sampai saya mulai menggunakan perpustakaan yang dikompilasi berbeda tergantung pada lingkungan seperti PyCrypto. Mac PyCrypto saya tidak akan berfungsi di Cygwin tidak akan berfungsi di Ubuntu.

Menjadi mimpi buruk total untuk mengelola repositori.

Either way saya menemukan lebih mudah untuk mengelola pembekuan pip & file persyaratan daripada memiliki semuanya di git. Ini juga lebih bersih karena Anda bisa menghindari spam komit untuk ribuan file karena pustaka tersebut diperbarui ...

Yuji 'Tomita' Tomita
sumber
Hmm. Saya pasti tidak akan memiliki masalah dengan hal-hal yang dikompilasi secara berbeda di lingkungan yang berbeda. Saya kira itu mungkin layak tidak dilakukan hanya untuk menghindari komit spam.
Lyle Pratt
@ LylePratt: Saya pikir sebaliknya: lebih baik tidak memasukkan seluruh virtualenv ke dalam repositori hanya untuk menghindari masalah dengan memiliki alat yang hebat seperti PyCrypto atau PIL.
Tadeck
17

Saya pikir salah satu masalah utama yang terjadi adalah bahwa virtualenv mungkin tidak dapat digunakan oleh orang lain. Alasannya adalah selalu menggunakan jalur absolut. Jadi jika Anda virtualenv misalnya di /home/lyle/myenv/dalamnya akan menganggap yang sama untuk semua orang lain menggunakan repositori ini (itu harus persis jalan absolut yang sama). Anda tidak dapat menganggap orang menggunakan struktur direktori yang sama dengan Anda.

Praktik yang lebih baik adalah bahwa setiap orang menyiapkan lingkungan mereka sendiri (baik dengan atau tanpa virtualenv) dan menginstal perpustakaan di sana. Itu juga membuat kode Anda lebih dapat digunakan melalui platform yang berbeda (Linux / Windows / Mac), juga karena virtualenv diinstal berbeda di masing-masing platform.

Torsten Engelbrecht
sumber
Ini tepat untuk mengapa ini adalah ide yang buruk untuk menyimpan virtualenv di SCM, tetapi ada baiknya mempertimbangkan sesuatu seperti saran @ RJBrady atau membuat skrip bootstrap.py , karena memiliki beberapa cara untuk menciptakan kembali lingkungan yang sama di seluruh mesin adalah kebutuhan serius ketika bekerja dengan orang lain.
ig0774
Saya tidak begitu yakin masalah yang Anda sebutkan akan menjadi masalah dalam situasi saya sebenarnya. Aplikasi Django saya berisi file .wsgi yang menentukan di mana virtualenv relatif terhadap lokasinya (2 direktori di atas '../../env'). Jadi, dalam skenario saya, masalah jalur absolut seharusnya tidak berdampak negatif pada saya ... bukan?
Lyle Pratt
Jika Anda menjalankan aplikasi Anda selalu dengan WSGI maka Anda mungkin lolos begitu saja. Jika Anda menggunakan server pengembangan (via manage.py) Anda pasti akan mengalami masalah.
Torsten Engelbrecht
3

Saya menggunakan apa yang pada dasarnya jawaban David Sickmiller dengan sedikit lebih banyak otomatisasi. Saya membuat file (tidak dapat dieksekusi) di tingkat atas proyek saya dinamai activatedengan konten berikut:

[ -n "$BASH_SOURCE" ] \
    || { echo 1>&2 "source (.) this with Bash."; exit 2; }
(
    cd "$(dirname "$BASH_SOURCE")"
    [ -d .build/virtualenv ] || {
        virtualenv .build/virtualenv
        . .build/virtualenv/bin/activate
        pip install -r requirements.txt
    }
)
. "$(dirname "$BASH_SOURCE")/.build/virtualenv/bin/activate"

(Sesuai jawaban David, ini mengasumsikan Anda sedang melakukan pip freeze > requirements.txtuntuk menjaga agar daftar persyaratan Anda tetap mutakhir.)

Di atas memberikan gambaran umum; skrip aktif aktual ( dokumentasi ) yang biasanya saya gunakan sedikit lebih canggih, menawarkan -qopsi (sunyi), menggunakan pythonsaat python3tidak tersedia, dll.

Ini kemudian dapat bersumber dari direktori kerja saat ini dan akan mengaktifkan dengan benar, pertama-tama menyiapkan lingkungan virtual jika perlu. Skrip pengujian tingkat atas saya biasanya memiliki kode di sepanjang baris ini sehingga dapat dijalankan tanpa pengembang harus mengaktifkan terlebih dahulu:

cd "$(dirname "$0")"
[[ $VIRTUAL_ENV = $(pwd -P) ]] || . ./activate

Sumber ./activate, tidak activate, penting di sini karena yang terakhir akan menemukan yang lain activatedi jalur Anda sebelum akan menemukan yang ada di direktori saat ini.

cjs
sumber
Suka pendekatan ini! Kedengarannya sangat masuk akal, terima kasih telah berbagi.
Esolitos
Saya harus mengubah baris pertama [[ $_ != $0 ]] || { echo 1>&2 "source (.) this script with Bash."; exit 2; }untuk mendeteksi apakah skrip dieksekusi sebagai lawan bersumber
Chris Snow
3

Bukan ide yang baik untuk memasukkan komponen atau pengaturan yang bergantung pada lingkungan dalam repo Anda sebagai salah satu aspek utama menggunakan repo, mungkin, berbagi dengan pengembang lain. Berikut adalah cara saya mengatur lingkungan pengembangan saya pada PC Windows (katakanlah, Win10).

  1. Buka Pycharm dan pada halaman pertama, pilih untuk memeriksa proyek dari Sistem Kontrol Sumber Anda (dalam kasus saya, saya menggunakan github)

  2. Di Pycharm, navigasikan ke pengaturan dan pilih "Project Interpreter" dan pilih opsi untuk menambahkan lingkungan virtual baru, Anda dapat menyebutnya "venv".

  3. Pilih juru bahasa python dasar yang terletak di C: \ Users {user} \ AppData \ Local \ Programs \ Python \ Python36 (pastikan Anda memilih versi Python yang sesuai berdasarkan apa yang telah Anda instal)

  4. Perhatikan bahwa Pycharm akan membuat lingkungan virtual baru dan menyalin binari python dan pustaka yang diperlukan di bawah folder venv Anda di dalam folder proyek Anda.

  5. Biarkan Pycharm menyelesaikan pemindaiannya karena perlu membangun kembali / menyegarkan kerangka proyek Anda

  6. kecualikan folder venv dari interaksi git Anda (tambahkan venv \ ke file .gitignore di folder proyek Anda)

Bonus: Jika Anda ingin orang menginstal dengan mudah (well, hampir mudah) semua perpustakaan yang dibutuhkan perangkat lunak Anda, Anda dapat menggunakannya

pip freeze > requirements.txt

dan letakkan instruksi pada git Anda sehingga orang-orang dapat menggunakan perintah berikut untuk mengunduh semua perpustakaan yang diperlukan sekaligus.

pip install -r requirements.txt 
William Pourmajidi
sumber
2

Jika Anda tahu sistem operasi yang menjalankan aplikasi Anda, saya akan membuat satu virtualenv untuk setiap sistem dan memasukkannya ke dalam repositori saya. Kemudian saya akan membuat aplikasi saya mendeteksi sistem yang sedang berjalan dan menggunakan virtualenv yang sesuai.

Sistem misalnya dapat diidentifikasi menggunakan modul platform .

Bahkan, inilah yang saya lakukan dengan aplikasi in-house yang saya tulis, dan saya dapat dengan cepat menambahkan virtualenv sistem baru jika diperlukan. Dengan cara ini, saya tidak harus bergantung pada pip yang akan dapat berhasil mengunduh perangkat lunak yang diperlukan aplikasi saya. Saya juga tidak perlu khawatir tentang kompilasi misalnya psycopg2 yang saya gunakan.

Jika Anda tidak tahu sistem operasi yang menjalankan aplikasi Anda, Anda mungkin lebih baik menggunakan pip freezeseperti yang disarankan dalam jawaban lain di sini.

fredrik
sumber
0

Saya pikir yang terbaik adalah menginstal lingkungan virtual di jalur di dalam folder repositori, mungkin lebih baik inklusif untuk menggunakan subdirektori yang didedikasikan untuk lingkungan (saya telah menghapus secara tidak sengaja seluruh proyek saya ketika memaksa menginstal lingkungan virtual di root repositori folder, bagus bahwa proyek saya disimpan dalam versi terbarunya di Github).

Baik penginstal otomatis, atau dokumentasi harus menunjukkan jalur virtualenv sebagai jalur relatif, dengan cara ini Anda tidak akan mengalami masalah saat berbagi proyek dengan orang lain. Tentang paket, paket yang digunakan harus disimpan oleh pip freeze -r requirements.txt.

Lucioric2000
sumber
-1

Jika Anda hanya mengatur pengembangan env, maka gunakan file freeze pip, caz yang membuat repo git bersih.

Kemudian jika melakukan penyebaran produksi, maka checkin seluruh folder venv. Itu akan membuat penyebaran Anda lebih mudah direproduksi, tidak memerlukan paket libxxx-dev itu, dan menghindari masalah internet.

Jadi ada dua repo. Satu untuk kode sumber utama Anda, yang mencakup requirement.txt. Dan repo env, yang berisi seluruh folder venv.

Shuo
sumber