Skip to content
Commits on Source (13)
# New contributors should email kfranz@anaconda.com to request a Contributor License Agreement
# that can be electronically signed. A signed contributor license agreement for a pull request
# author needs to be on file with Anaconda, Inc. for pull requests to be merged. This file,
# while not an official record, is used by conda-bot for the purposes of CLA status on pull
# requests.
# A signed contributor license agreement for a pull request author needs to be on file with
# Anaconda, Inc. for pull requests to be merged. This file, while not an official record,
# is used by conda-bot for the purposes of CLA status on pull requests.
# Each row in this file has three fields. The first field is github username. The second field
# is git id, the output of `git log -n1 --format="%aN <%aE>"` when HEAD is at a specific user's
......@@ -19,6 +17,7 @@ alanhdu | Alan Du <alanhdu@gmail.com> | 2018-06-05
albertmichaelj | Michael Albert <albertmichaelj@gmail.com> | 2019-02-27
aldanor | Ivan Smirnov <i.s.smirnov@gmail.com> | 2018-07-24
alexbw | Alex Wiltschko <alex.bw@gmail.com> | 2018-05-23
alexhall | Alex Hall <alexhall99@gmail.com> | 2019-05-22
almarklein | Almar Klein <almar.klein@gmail.com> | 2018-06-04
analog-cbarber | Christopher Barber <christopher.barber@analog.com> | 2019-03-22
arkottke | Albert Kottke <albert.kottke@gmail.com> | 2018-07-23
......@@ -40,8 +39,11 @@ certik | Ondřej Čertík <ondrej.certik@gmail.com> | 2018-07-24
cgranade | Christopher Granade <cgranade@cgranade.com> | 2018-09-21
chdoig | Christine Doig <christine.doig.cardet@gmail.com> | Anaconda, Inc.
chrislf | Chris Linton-Ford <chris.lintonford@gmail.com> | 2018-08-01
chrisburr | Chris Burr <chrisburr73@gmail.com> | 2019-05-13
CJ-Wright | christopher <cjwright4242@gmail.com> | 2018-08-20
cjmartian | Connor Martin <connormartin7@gmail.com> | Anaconda, Inc.
csoja | Crystal Soja <crystal.soja@continuum.io> | Anaconda, Inc.
csosborn | Chris Osborn <csosborn@gmail.com> | 2019-06-04
cstich | Christoph Stich <christoph.n.stich@gmail.com> | 2018-06-13
dan-blanchard | Dan Blanchard <dan.blanchard@gmail.com> | 2018-07-24
davemasino | Dave Masino <davem@slalom.com> | 2019-02-07
......@@ -49,15 +51,18 @@ dawehner | Daniel Wehner <dawehner@users.noreply.github.com> | 2018-06-02
ddale | Darren Dale <dsdale24@gmail.com> | 2018-07-26
dedalusj | Jacopo <dedalusj@gmail.com> | 2018-06-01
delicb | Bojan Delic <bojan@delic.in.rs> | 2018-07-24
dennispg | Dennis George <dennispg@gmail.com> | 2019-03-29
desilinguist | Nitin Madnani <nmadnani@gmail.com> | 2018-06-01
dhirschfeld | David Hirschfeld <david.hirschfeld@gazprom-mt.com> | 2018-07-25
dmkent | David Kent <davidkent@fastmail.com.au> | 2018-07-23
dorzel | Dylan Orzel <dylan.orzel@gmail.com> | Anaconda, Inc.
dsludwig | Derek Ludwig <dludwig@continuum.io> | Anaconda, Inc.
duncanmmacleod | Duncan Macleod <duncanmmacleod@gmail.com> | 2019-04-02
electronwill | Will Warner <electronwill@gmail.com> | Anaconda, Inc.
elehcim | Michele Mastropietro <michele.mastropietro@gmail.com> | 2018-07-24
ericdill | Eric Dill <edill@bnl.gov> | 2018-06-04
esc | Valentin Haenel <valentin@haenel.co> | 2018-07-24
EternalPhane | Zongyuan Zuo <eternalphane@gmail.com> | 2019-04-24
faph | Florenz A. P. Hollebrandse <faph@users.noreply.github.com> | 2018-09-19
flaviomartins | Flavio Martins <flaviomartins@acm.org> | 2018-06-05
frol | Vlad Frolov <frolvlad@gmail.com> | 2018-06-04
......@@ -74,12 +79,15 @@ hubmann | Patricio Hubmann <phubmann@machinalis.com> | 2018-07-24
HugoTian | Tian Zhang <zhangtian1000@gmail.com> | Anaconda, Inc.
ijstokes | Ian Stokes-Rees <ijstokes@continuum.io> | Anaconda, Inc.
ilanschnell | Ilan Schnell <ilan@continuum.io> | Anaconda, Inc.
ilango100 | Ilango R <ilangokul@gmail.com> | 2019-04-02
immerrr | immerrr <immerrr@gmail.com> | 2018-07-30
ivigamberdiev | Igor <ivigamberdiev@gmail.com> | 2019-04-08
jacoblsmith | Jacob Smith <jacoblsmith@gmail.com> | 2018-08-01
jaimergp | Jaime RGP <jaime.rogue@gmail.com> | 2018-06-01
jakirkham | John Kirkham <kirkhamj@janelia.hhmi.org> | 2018-08-02
jameswinegar | James Winegar <jameswinegar@users.noreply.github.com> | 2018-07-23
JarnoRFB | Rüdiger Busche <ruedigerbusche@web.de> | 2018-07-23
javabrett | Brett Randall <javabrett@gmail.com> | 2019-04-02
jerowe | Jillian Rowe <jillian.e.rowe@gmail.com> | 2018-07-23
jesse- | Jesse Hamer <4989897+jesse-@users.noreply.github.com> | 2018-08-05
jharriman | Justyn Harriman <justyn@nextdoor.com> | 2018-07-30
......@@ -88,6 +96,7 @@ jjhelmus | Jonathan J. Helmus <jjhelmus@gmail.com> | 2018-06-07
jni | Juan Nunez-Iglesias <juan.n@unimelb.edu.au> | 2018-06-01
joelhullcio | joel.hull@continuum.io <joel.hull@continuum.io> | Anaconda, Inc.
joelkim | Joel Kim <kim.dohhyoung@gmail.com> | 2018-07-24
jpgill86 | Jeffrey Gill <jeffrey.p.gill@gmail.com> | 2019-04-10
jrovegno | jrovegno <tatadeluxe@gmail.com> | 2018-07-31
jseabold | Skipper Seabold <jsseabold@gmail.com> | 2018-06-01
Juanlu001 | Juan Luis Cano Rodríguez <juanlu001@gmail.com> | 2018-06-01
......@@ -108,6 +117,7 @@ mandeep | mandeep <mbhutani@continuum.io> | 2018-09-04
marcelotrevisani | Marcelo Duarte Trevisani <marceloduartetrevisani@gmail.com> | 2018-06-04
MarckK | Kara de la Marck <karadelamarck@gmail.com> | 2019-02-19
mariusvniekerk | Marius van Niekerk <marius.v.niekerk@gmail.com> | 2019-01-04
martinkou | Man Tong Kou <bitanarch@gmail.com> | 2019-05-19
matta9001 | Matthew Anderson <matta9001@gmail.com> | 2019-02-23
MaxNoe | Maximilian Noethe <maximilian.noethe@tu-dortmund.de> | 2018-07-24
mbargull | Marcel Bargull <mbargull@users.noreply.github.com> | 2018-06-04
......@@ -121,15 +131,20 @@ mika-fischer | Mika Fischer <mika.fischer@zoopnet.de> | 2018-07-05
mingwandroid | Ray Donnelly <mingw.android@gmail.com> | Anaconda, Inc.
minrk | MinRK <benjaminrk@gmail.com> | 2018-07-30
mmarchetti | Michael Marchetti <mmarchetti@continuum.io> | Anaconda, Inc.
MrKriss | Chris Musselle <chris.j.musselle@gmail.com> | 2019-05-09
msarahan | Michael Sarahan <msarahan@continuum.io> | Anaconda, Inc.
murraryreadccdc | M.G. Read <read@ccdc.cam.ac.uk> | 2019-02-05
mutirri | irritum <kamil.kwiek@continuum.io> | Anaconda, Inc.
mwabumba | Mohamed Mwabumba <mwabbumba@gmail.com> | 2019-04-25
mwiebe | Mark Wiebe <mwiebe@continuum.io> | Anaconda, Inc.
Naftali | Naftali Eichen <naftalieichen@gmail.com | 2019-06-03
necaris | Rami R Chowdhury <rami.chowdhury@gmail.com 2019-05-27
nehaljwani | Nehal J Wani <nehaljw.kkd1@gmail.com> | 2018-06-01
nh3 | Ni Huang <ni.huang@sanger.ac.uk> | 2019-03-20
nickeubank | Nick Eubank <nickeubank@users.noreply.github.com> | 2018-06-04
nicoddemus | Bruno Oliveira <nicoddemus@gmail.com> | 2018-05-23
njalerikson | Odegard, Ken <ken.odegard@gmail.com> | 2018-06-01
noahp | Noah Pendleton <noah.pendleton@gmail.com> | 2019-04-15
nok | Darius Moraweic <darius.morawiec@nok.onl> | 2018-12-28
nouiz | Frederic Bastien <nouiz@nouiz.org> | 2018-06-11
ofek | Ofek Lev <ofekmeister@gmail.com> | 2018-06-04
......@@ -148,6 +163,7 @@ remram44 | Remi Rampin <remirampin@gmail.com> | 2018-06-01
rgommers | Ralf Gommers <ralf.gommers@googlemail.com> | 2018-07-23
rrigdon | Rachel Rigdon <rrigdon@anaconda.com> | Anaconda, Inc.
sachinbiradar9 | Sachin G Biradar <sachin@wirelessprvnat-172-16-196-108.near.illinois.edu> | 2018-07-23
satoshi | Satoshi Yagi <satoshi.yagi@yahoo.com> | 2019-05-07
scopatz | Anthony Scopatz <scopatz@gmail.com> | 2018-06-04
scw | Shaun Walbridge <shaun.walbridge@gmail.com> | 2018-05-24
sdvillal | santi <sdvillal@gmail.com> | 2018-06-01
......@@ -161,6 +177,7 @@ stefanseefeld | Stefan Seefeld <stefan@seefeld.name> | Anaconda, Inc.
stuarteberg | Stuart Berg <bergs@janelia.hhmi.org> | 2018-06-04
tadeu | Tadeu Manoel <tadeu@esss.com.br> | 2018-06-04
takluyver | Thomas Kluyver <takowl@gmail.com> | 2018-06-15
tarasama | Tara Samander <tarasamander@yahoo.co.uk> | 2019-04-07
teake | Teake Nutma <t.a.nutma@rug.nl> | 2018-07-24
teoliphant | Travis E. Oliphant <teoliphant@gmail.com> | Anaconda, Inc.
tdhopper| Tim Hopper <tdhopper@gmail.com> | 2018-08-01
......@@ -174,6 +191,7 @@ ukoethe | Ullrich Koethe <ullrich.koethe@iwr.uni-heidelberg.de> | 2018-07-24
vestuto | Jason Vestuto <jvestuto@continuum.io> | Anaconda, Inc.
wojdyr | Marcin Wojdyr <wojdyr@gmail.com> | 2018-06-01
wulmer | Wolfgang Ulmer <wolfgang.ulmer@de.bosch.com> | 2018-06-11
yuvalreches | Yuval <bigbirds@gmail.com> | 2019-05-05
Zaharid | Zahari <zaharid@gmail.com> | 2018-07-24
zdog234 | Zane Dufour <zane.dufour@gmail.com | 2019-03-26
zzag | Vlad Zagorodniy <vladzzag@gmail.com> | 2018-07-24
......
......@@ -35,3 +35,4 @@ miniconda*.exe
.pytest_cache/
docs/source/_build
**/.vscode
conda.tmp/
requirements_file: utils/requirements-docs.txt
conda:
file: utils/environment.yml
python:
version: 3
## 4.7.12 (2019-09-12)
### Enhancements:
* add support for env file creation based on explicit specs in history (#9093)
* detect prefix paths when -p nor -n not given (#9135)
* Add config parameter to disable conflict finding (for faster time to errors) (#9190)
### Bug fixes
* fix race condition with creation of repodata cache dir (#9073)
* fix ProxyError expected arguments (#9123)
* makedirs to initialize .conda folder when registering env - fixes permission errors with .conda folders not existing when package cache gets created (#9215)
* fix list duplicates errors in reading repodata/prefix data (#9132)
* fix neutered specs not being recorded in history, leading to unsatisfiable environments later (#9147)
* Standardize "conda env list" behavior between platforms (#9166)
* add JSON output to conda env create/update (#9204)
* speed up finding conflicting specs (speed regression in 4.7.11) (#9218)
### Contributors
* @beenje
* @Bezier89
* @cjmartian
* @forrestwaters
* @jjhelmus
* @martin-raden
* @msarahan
* @nganani
* @rrigdon
* @soapy1
* @WesRoach
* @zheaton
## 4.7.11 (2019-08-06)
### Enhancements
* add config for control of number of threads. These can be set in condarc or using environment variables. Names/default values are: `default_threads/None`, `repodata_threads/None`, `verify_threads/1`, `execute_threads/1` (#9044)
### Bug fixes
* fix repodata_fns from condarc not being respected (#8998)
* Fix handling of UpdateModifiers other than FREEZE_INSTALLED (#8999)
* Improve conflict finding graph traversal (#9006)
* Fix setuptools being removed due to conda run_constrains (#9014)
* Avoid calling find_conflicts until all retries are spent (#9015)
* refactor _conda_activate.bat in hopes of improving behavior in parallel environments (#9021)
* Add support for local version specs in PYPI installed packages (#9025)
* fix boto3 initialization race condition (#9037)
* Fix return condition in package_cache_data (#9039)
* utilize libarchive_enabled attribute provided by conda-package-handling to fall back to .tar.bz2 files only. (#9041, #9053)
* Fix menu creation on windows having race condition, leading to popups about python.exe not being found (#9044)
* Improve list error when egg-link leads to extra egg-infos (#9045)
* Fix incorrect RemoveError when operating on an env that has one of conda's deps, but is not the env in which the current conda in use resides (#9054)
### Docs
* Document new package format better
* Document `conda init` command
* Document availability of RSS feed for CDN-backed channels that clone
### Contributors
* @Bezier89
* @forrestwaters
* @hajapy
* @ihnorton
* @matthewwardrop
* @msarahan
* @rogererens
* @rrigdon
* @soapy1
## 4.7.10 (2019-07-19)
### Bug fixes
* fix merging of specs
* fix bugs in building of chains in prefix graph
### Contributors:
* @msarahan
## 4.7.9 (2019-07-18)
### Bug fixes
* fix Non records in comprehension
* fix potential keyerror in depth-first search
* fix PackageNotFound attribute error
### Contributors:
* @jjhelmus
* @msarahan
## 4.7.8 (2019-07-17)
### Improvements
* improve unsatisfiable messages - try to group and explain output better. Remove lots of extraneous stuff that was showing up in 4.7.7 (#8910)
* preload openssl on windows to avoid library conflicts and missing library issues (#8949)
### Bug fixes
* fix handling of channels where more than one channel contains packages with similar name, subdir, version and build_number. This was causing mysterious unsatisfiable errors for some users. (#8938)
* reverse logic check in checking channel equality, because == is not reciprocal to != with py27 (no `__ne__`) (#8938)
* fix an infinite loop or otherwise large process with building the unsatisfiable info. Improve the depth-first search implementation. (#8941)
* streamline fallback paths to unfrozen solve in case frozen fails. (#8942)
* Environment activation output only shows `conda activate envname` now, instead of sometimes showing just `activate`. (#8947)
### Contributors:
* @forrestwaters
* @jjhelmus
* @katietz
* @msarahan
* @rrigdon
* @soapy1
## 4.7.7 (2019-07-12)
### Improvements
* When an update command doesn't do anything because installed software conflicts with the update, information about the conflict is shown, rather than just saying "all requests are already satisfied" (#8899)
### Bug fixes
* fix missing package_type attr in finding virtual packages (#8917)
* fix parallel operations of loading index to preserve channel ordering (#8921, #8922)
* filter PrefixRecords out from PackageRecords when making a graph to show unsatisfiable deps. Fixes comparison error between mismatched types. (#8924)
* install entry points before running post-link scripts, because post link scripts may depend on entry points. (#8925)
### Contributors
* @jjhelmus
* @msarahan
* @rrigdon
* @soapy1
## 4.7.6 (2019-07-11)
### Improvements
* Improve cuda virtual package conflict messages to show the `__cuda` virtual package as part of the conflict (#8834)
* add additional debugging info to Resolve.solve (#8895)
### Bug fixes
* deduplicate error messages being shown for post-link scripts. Show captured stdout/stderr on failure (#8833)
* fix the checkout step in the Windows dev env setup instructions (#8827)
* bail out early when implicit python pinning renders an explicit spec unsatisfiable (#8834)
* handle edge cases in pinned specs better (#8843)
* extract package again if url is None (#8868)
* update docs regarding indexing and subdirs (#8874)
* remove warning about conda-build needing an update that was bothering people (#8884)
* only add repodata fn into cache key when fn is not repodata.json (#8900)
* allow conda to be downgraded with an explicit spec (#8892)
* add target to specs from historic specs (#8901)
* improve message when solving with a repodata file before repodata.json fails (#8907)
* fix distutils usage for "which" functionality. Fix inability to change python version in envs with noarch packages (#8909)
* fix anaconda metapackage being removed because history matching was too restrictive (#8911)
* make freezing less aggressive; add fallback to non-frozen solve (#8912)
### Contributors
* @forrestwaters
* @jjhelmus
* @mcopes73
* @msarahan
* @richardjgowers
* @rrigdon
* @soapy1
* @twinssbc
## 4.7.5 (2019-06-24)
### Improvements
* improve wording in informational message when a particular `*_repodata.json` can't be found. No need for alarm. (#8808)
### Bug fixes
* restore tests being run on win-32 appveyor (#8801)
* fix Dist class handling of .conda files (#8816)
* fix strict channel priority handling when a package is unsatisfiable and thus not present in the collection (#8819)
* handle JSONDecodeError better when package is corrupted at extract time (#8820)
### Contributors
* @dhirschfeld
* @msarahan
* @rrigdon
## 4.7.4 (2019-06-19)
### Improvements
* Revert to and improve the unsatisfiability determination from 4.7.2 that was reverted in 4.7.3. It's faster. (#8783)
### Bug fixes
* fix tcsh/csh init scripts (#8792)
### Docs improvements
* clean up docs of run_command
* fix broken links
* update docs environment.yaml file to update conda-package-handling
* conda logo favicon
* update strict channel priority info
* noarch package content ported from conda-forge
* add info about conda-forge
* remove references to things as they were before conda 4.1. That was a long time ago. This is not a history book.
### Contributors
* @jjhelmus
* @msarahan
* @rrigdon
* @soapy1
## 4.7.3 (2019-06-14)
### Bug fixes
* target prefix overrid applies to entry points in addition to replacements in standard files (#8769)
* Revert to solver-based unsatisfiability determination (#8775)
* fix renaming of existing prompt function in powershell (#8774)
### Contributors:
* @jjhelmus
* @msarahan
* @rrigdon
* @ScottEvtuch
## 4.7.2 (2019-06-10)
### Behavior changes
* unsatisfiability is determined in a slightly different way now. It no longer
uses the SAT solver, but rather determines whether any specs have no
candidates at all after running through get_reduced_index. This has been
faster in benchmarks, but we welcome further data from your use cases about
whether this was a good change. (#8741)
* when using the --only-deps flag for the `install` command, conda now
explicitly records those specs in your history. This primarily serves to
reduce conda accidentally removing packages that you have actually requested. (#8766)
### Improvements
* UnsatisfiableError messages are now grouped into categories and explained a bit better. (#8741)
* --repodata-fn argument can be passed multiple times to have more fallback
paths. `repodata_fns` conda config setting does the same thing, but saves you
from needing to do it for every command invocation. (#8741)
### Bug fixes
* fix channel flip-flopping that was happening when adding a channel other than earlier ones (#8741)
* refactor flow control for multiple repodata files to not use exceptions (#8741)
* force conda to use only old .tar.bz2 files if conda-build <3.18.3 is
installed. Conda-build breaks when inspecting file contents, and this is fixed
in conda-build 3.18.3 (#8741)
* use --force when using rsync to improve behavior with folders that may exist
in the destination somehow. (#8750)
* handle EPERM errors when renaming, because MacOS lets you remove or create
files, but not rename them. Thanks Apple. (#8755)
* fix conda removing packages installed via `install` with --only-deps flag when
either `update` or `remove` commands are run. See behavior changes above.
(#8766)
### Contributors
* @csosborn
* @jjhelmus
* @katietz
* @msarahan
* @rrigdon
## 4.7.1 (2019-05-30)
### Improvements
* Base initial solver specs map on explicitly requested specs (new and historic) (#8689)
* Improve anonymization of automatic error reporting (#8715)
* Add option to keep using .tar.bz2 files, in case new .conda isn't working for whatever reason (#8723)
### Bug fixes
* fix parsing hyphenated PyPI specs (change hyphens in versions to .) (#8688)
* fix PrefixRecord creation when file inputs are .conda files (#8689)
* fix PrefixRecord creation for pip-installed packages (#8689)
* fix progress bar stopping at 75% (no extract progress with new libarchive) (#8689)
* preserve pre-4.7 download() interface in conda.exports (#8698)
* virtual packages (such as cuda) are represented by leading double underscores
by convention, to avoid confusion with existing single underscore packages
that serve other purposes (#8738)
### Deprecations/Breaking Changes
* The `--prune` flag no longer does anything. Pruning is implicitly the
standard behavior now as a result of the initial solver specs coming from
explicitly requested specs. Conda will remove packages that are not explicitly
requested and are not required directly or indirectly by any explicitly
installed package.
### Docs improvements
* Document removal of the `free` channel from defaults (#8682)
* Add reference to conda config --describe (#8712)
* Add a tutorial for .condarc modification (#8737)
### Contributors
* @alexhall
* @cjmartian
* @kalefranz
* @martinkou
* @msarahan
* @rrigdon
* @soapy1
## 4.7.0 (2019-05-17)
### Improvements
* Implement support for "virtual" CUDA packages, to make conda consider the system-installed CUDA driver and act accordingly (#8267)
* Support and prefer new .conda file format where available (#8265, #8639)
* Use comma-separated env names in prompt when stacking envs (#8431)
* show valid choices in error messages for enums (#8602)
* freeze already-installed packages when running `conda install` as a first attempt, to speed up the solve in existing envs. Fall back to full solve as necessary (#8260, #8626)
* add optimization criterion to prefer arch over noarch packages when otherwise equivalent (#8267)
* Remove `free` channel from defaults collection. Add `restore_free_channel` config parameter if you want to keep it. (#8579)
* Improve unsatisfiable hints (#8638)
* Add capability to use custom repodata filename, for smaller subsets of repodata (#8670)
* Parallelize SubdirData readup (#8670)
* Parallelize transacation verification and execution (#8670)
### Bug fixes
* Fix PATH handling with deactivate.d scripts (#8464)
* Fix usage of deprecated collections ABCs (#)
* fix tcsh/csh initialization block (#8591)
* fix missing CWD display in powershell prompt (#8596)
* `wrap_subprocess_call`: fallback to sh if no bash (#8611)
* move `TemporaryDirectory` to avoid importing from `conda.compat` (#8671)
* fix missing conda-package-handling dependency in dev/start (#8624)
* fix `path_to_url` string index out of range error (#8265)
* fix conda init for xonsh (#8644)
* fix fish activation (#8645)
* improve error handling for read-only filesystems (#8665, #8674)
* break out of minimization when bisection has nowhere to go (#8672)
* Handle None values for link channel name gracefully (#8680)
### Contributors
* @chrisburr
* @EternalPhane
* @jjhelmus
* @kalefranz
* @mbargull
* @msarahan
* @rrigdon
* @scopatz
* @seibert
* @soapy1
* @nehaljwani
* @nh3
* @teake
* @yuvalreches
## 4.6.14 (2019-04-17)
### Bug fixes
* export extra function in powershell Conda.psm1 script (fixes anaconda powershell prompt) (#8570)
### Contributors
* @msarahan
## 4.6.13 (2019-04-16)
### Bug fixes
* disable ``test_legacy_repodata`` on win-32 (missing dependencies) (#8540)
* Fix activation problems on windows with bash, powershell, and batch. Improve tests. (#8550, #8564)
* pass -U flag to for pip dependencies in conda env when running "conda env update" (#8542)
* rename ``conda.common.os`` to ``conda.common._os`` to avoid shadowing os built-in (#8548)
* raise exception when pip subprocess fails with conda env (#8562)
* fix installing recursive requirements.txt files in conda env specs with python 2.7 (#8562)
* Don't modify powershell prompt when "changeps1" setting in condarc is False (#8465)
### Contributors
* @dennispg
* @jjhelmus
* @jpgill86
* @mingwandroid
* @msarahan
* @noahp
## 4.6.12 (2019-04-10)
### Bug fixes
* Fix compat import warning (#8507)
* Adjust collections import to avoid deprecation warning (#8499)
* Fix bug in CLI tests (#8468)
* Disallow the number sign in environment names (#8521)
* Workaround issues with noarch on certain repositories (#8523)
* Fix activation on Windows when spaces are in path (#8503)
* Fix conda init profile modification for powershell (#8531)
* Point conda.bat to condabin (#8517)
* Fix various bugs in activation (#8520, #8528)
### Docs improvements
* Fix links in README (#8482)
* Changelogs for 4.6.10 and 4.6.11 (#8502)
### Contributors
@Bezier89
@duncanmmacleod
@ivigamberdiev
@javabrett
@jjhelmus
@katietz
@mingwandroid
@msarahan
@nehaljwani
@rrigdon
## 4.6.11 (2019-04-04)
### Bug fixes
* Remove sys.prefix from front of PATH in basic_posix (#8491)
* add import to fix conda.core.index.get_index (#8495)
### Docs improvements
* Changelogs for 4.6.10
### Contributors
* @jjhelmus
* @mingwandroid
* @msarahan
## 4.6.10 (2019-04-01)
### Bug fixes
......
......@@ -87,9 +87,6 @@ In these steps, we assume `git` is installed and available on `PATH`.
cd "%CONDA_PROJECT_ROOT%"
git remote add %GITHUB_USERNAME% git@github.com:%GITHUB_USERNAME%/conda
To be sure that the conda code being interpreted is the code in the project directory,
look at the value of `conda location:` in the output of `conda info --all`.
3. Create a local development environment, and activate that environment
.\dev\start.bat
......@@ -98,6 +95,9 @@ In these steps, we assume `git` is installed and available on `PATH`.
the environment already exists, this command will just quickly activate the
already-created `.\devenv` environment.
To be sure that the conda code being interpreted is the code in the project directory,
look at the value of `conda location:` in the output of `conda info --all`.
## Conda Contributor License Agreement
......@@ -107,10 +107,11 @@ In case you're new to CLAs, this is rather standard procedure for larger project
### Process
New contributors should email kfranz@anaconda.com to request a Contributor License Agreement that
can be electronically signed. A signed contributor license agreement for a pull request author
needs to be on file with Anaconda, Inc. for pull requests to be merged. A record of signatories is
kept in the [`.cla-signers`](https://github.com/conda/conda/blob/master/.cla-signers) file in the
New contributors should complete the Conda Contributor License Agreement located
[here](https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement). A
signed contributor license agreement for a pull request author needs to be on file with
Anaconda, Inc. for pull requests to be merged. A record of signatories is kept in the
[`.cla-signers`](https://github.com/conda/conda/blob/master/.cla-signers) file in the
project root.
### Individual Contributor License Agreement – Conda Code Organization
......
......@@ -26,7 +26,7 @@
Conda is a cross-platform, language-agnostic binary package manager. It is the
package manager used by `Anaconda
<https://www.anaconda.com/download/>`_ installations, but it may be
<https://www.anaconda.com/distribution/>`_ installations, but it may be
used for other systems as well. Conda makes environments first-class
citizens, making it easy to create independent environments even for C
libraries. Conda is written entirely in Python, and is BSD licensed open
......@@ -41,7 +41,7 @@ Installation
------------
Conda is a part of the `Anaconda Distribution <https://repo.anaconda.com>`_.
Use `Miniconda <https://conda.io/miniconda.html>`_ to bootstrap a minimal installation
Use `Miniconda <https://conda.io/en/latest/miniconda.html>`_ to bootstrap a minimal installation
that only includes conda and its dependencies.
......@@ -71,7 +71,7 @@ and to install a package, use
The real power of conda comes from its ability to manage environments. In
conda, an environment can be thought of as a completely separate installation.
Conda installs packages into environments efficiently using `hard links
<http://en.wikipedia.org/wiki/Hard_links>`_ by default when it is possible, so
<https://en.wikipedia.org/wiki/Hard_link>`_ by default when it is possible, so
environments are space efficient, and take seconds to create.
The default environment, which ``conda`` itself is installed into is called
......@@ -118,10 +118,10 @@ You can easily build your own packages for conda, and upload them
to `anaconda.org <https://anaconda.org>`_, a free service for hosting
packages for conda, as well as other package managers.
To build a package, create a recipe. Package building documentation is available
`here <https://conda.io/docs/user-guide/tasks/build-packages/index.html>`_.
See http://github.com/AnacondaRecipes for the recipes that make up the Anaconda Distribution
`here <https://conda.io/projects/conda-build/en/latest/>`_.
See https://github.com/AnacondaRecipes for the recipes that make up the Anaconda Distribution
and ``defaults`` channel. `Conda-forge <https://conda-forge.org/feedstocks/>`_ and
`Bioconda <https://bioconda.github.io/recipes.html>`_ are community-driven
`Bioconda <https://github.com/bioconda/bioconda-recipes>`_ are community-driven
conda-based distributions.
To upload to anaconda.org, create an account. Then, install the
......@@ -153,7 +153,7 @@ to add).
Getting Help
------------
The documentation for conda is at http://conda.io/docs/. You can
The documentation for conda is at https://conda.io/en/latest/. You can
subscribe to the `conda mailing list
<https://groups.google.com/a/continuum.io/forum/#!forum/conda>`_. The source
code and issue tracker for conda are on `GitHub <https://github.com/conda/conda>`_.
......
......@@ -10,10 +10,10 @@ environment:
secure: ZaE7K9EHorv40AjYhSuWtQeRAsMN1+QqPf7u8rOlvEY50kdaHj87Mh5GIDZgJBzj
matrix:
- PYTHON: "C:\\Python3_64"
PYTHON_VERSION: "3.7"
- PYTHON: "C:\\Python36_64"
PYTHON_VERSION: "3.6"
PYTHON_ARCH: "64"
PYTHON_ROOT: "C:\\Miniconda3-x64"
PYTHON_ROOT: "C:\\Miniconda36-x64"
CONDA_INSTRUMENTATION_ENABLED: "true"
- PYTHON: "C:\\Python27_32"
......@@ -22,32 +22,29 @@ environment:
PYTHON_ROOT: "C:\\Miniconda"
CONDA_INSTRUMENTATION_ENABLED: "true"
skip_commits:
files:
- docs/*
init:
- ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH% %HOME%
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
on_finish:
#on_finish:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
install:
- '%PYTHON_ROOT%\\Scripts\\conda install -y -c conda-canary -c defaults -c conda-forge python=%PYTHON_VERSION% pycosat conda requests ruamel_yaml pytest pytest-cov pytest-timeout mock responses pexpect pywin32 anaconda-client'
- "%PYTHON_ROOT%\\Scripts\\conda install -yq conda-build=3.13"
- CALL "%PYTHON_ROOT%\\Scripts\\activate.bat"
- 'conda install -y -c conda-canary -c defaults -c conda-forge python=%PYTHON_VERSION% pycosat conda requests ruamel_yaml pytest pytest-cov pytest-timeout mock responses pexpect pywin32 anaconda-client conda-package-handling'
- "conda install -yq conda-build=3.13"
# conda install -y -c defaults -c conda-forge pytest pytest-cov pytest-timeout mock responses pexpect xonsh
# TODO: add xonsh for PY3 builds
- "%PYTHON_ROOT%\\Scripts\\pip install codecov==2.0.5"
- "%PYTHON_ROOT%\\python -m conda init cmd.exe --dev"
- "pip install codecov==2.0.5"
- "python -m conda init cmd.exe --dev"
build: false
test_script:
- CALL dev-init.bat
- py.test %ADD_COV% -m "not integration and not installed" -v
- py.test %ADD_COV% --cov-append -m "integration and not installed" -v
- py.test %ADD_COV% -m "not integration and not installed" -v --basetemp=C:\tmp
- py.test %ADD_COV% --cov-append -m "integration and not installed" -v --basetemp=C:\tmp
- DEL /Q /F conda.egg-info
- conda.exe build conda.recipe
- conda build conda.recipe
- codecov --env PYTHON_VERSION --required
- python -m conda.common.io
# The Docker images used here are
# - condatest/linux-64-python-3.7 [https://github.com/conda/conda-docker/blob/master/condatest/linux-64-python3.7/Dockerfile]
# - condatest/linux-64-python-3.6 [https://github.com/conda/conda-docker/blob/master/condatest/linux-64-python3.6/Dockerfile]
# - condatest/linux-64-python-2.7 [https://github.com/conda/conda-docker/blob/master/condatest/linux-64-python2.7/Dockerfile]
defaults: &defaults
working_directory: ~/conda
docker:
- image: condatest/linux-64-python-3.6
# Dockerfile at https://github.com/conda/conda-docker/blob/master/condatest/linux-64-python3.6/Dockerfile
- image: condatest/linux-64-python-3.7
main_test: &main_test
<<: *defaults
......@@ -23,7 +23,7 @@ main_test: &main_test
conda info
# remove the pkg cache. We can't hardlink from here anyway. Having it around causes log problems.
sudo rm -rf /opt/conda/pkgs/*-*-*
py.test $ADD_COV -m "not integration and not installed"
py.test $ADD_COV -m "not integration and not installed" -v
fi
- run:
name: integration tests
......@@ -77,12 +77,12 @@ conda_build_test: &conda_build_test
echo "safety_checks: disabled" >> ~/.condarc
echo "local_repodata_ttl: 1800" >> ~/.condarc
conda create -n blarg -yq --download-only python=2.7
conda create -n blarg -yq --download-only python=3.4
conda create -n blarg -yq -c https://repo.anaconda.com/pkgs/free --download-only python=3.4
conda create -n blarg -yq --download-only python=3.5
conda create -n blarg -yq --download-only python=3.6
conda create -n blarg -yq --download-only python=3.7
conda create -n blarg -yq --download-only python setuptools cython certifi
conda create -n blarg -yq --download-only libpng=1.6.17
conda create -n blarg -yq -c https://repo.anaconda.com/pkgs/free --download-only libpng=1.6.17
- run:
name: conda-build conda
......@@ -141,6 +141,10 @@ conda_build_test: &conda_build_test
echo "Only docs changed detected, skipping tests"
else
eval "$(sudo /opt/conda/bin/python -m conda init --dev bash)"
conda config --add default_channels https://repo.anaconda.com/pkgs/free
conda config --add default_channels https://repo.anaconda.com/pkgs/r
conda config --add default_channels https://repo.anaconda.com/pkgs/main
conda config --set unsatisfiable_hints False
conda info
cd ~/conda-build
py.test --basetemp /tmp/cb -v --durations=20 -n 2 -m "not serial" tests -k "$CONDABUILD_SKIP"
......@@ -169,6 +173,11 @@ conda_build_test: &conda_build_test
echo "Only docs changed detected, skipping tests"
else
eval "$(sudo /opt/conda/bin/python -m conda init --dev bash)"
conda config --add default_channels https://repo.anaconda.com/pkgs/free
conda config --add default_channels https://repo.anaconda.com/pkgs/r
conda config --add default_channels https://repo.anaconda.com/pkgs/main
conda config --set unsatisfiable_hints False
conda info
cd ~/conda-build
py.test --basetemp /tmp/cb -v --durations=20 -n 0 -m "serial" tests -k "$CONDABUILD_SKIP"
/opt/conda/bin/python -m conda.common.io
......@@ -212,13 +221,11 @@ jobs:
- image: condatest/linux-64-python-2.7
environment:
- CONDA_INSTRUMENTATION_ENABLED: true
# 3.0 conda-build:
# <<: *conda_build_test
# environment:
# - CONDA_BUILD: 3.0.21
# - CONDA_INSTRUMENTATION_ENABLED: true
3.10 conda-build:
<<: *conda_build_test
# mpi4py test in conda-build needs py<3.7
docker:
- image: condatest/linux-64-python-3.6
environment:
- CONDA_BUILD: 3.10.1
- CONDA_INSTRUMENTATION_ENABLED: true
......@@ -233,7 +240,6 @@ workflows:
- py37 main tests
# - py36 main tests
- py27 main tests
# - 3.0 conda-build
- 3.10 conda-build
- flake8
- build_docs
#!/bin/bash
echo $PKG_VERSION > conda/.version
$PYTHON setup.py install --single-version-externally-managed --record record.txt
if [[ $(uname -o) != Msys ]]; then
rm -rf "$SP_DIR/conda/shell/*.exe"
fi
$PYTHON -m conda init --install
if [[ $(uname -o) == Msys ]]; then
sed -i "s|CONDA_EXE=.*|CONDA_EXE=\'${PREFIXW//\\/\\\\}\\\\Scripts\\\\conda.exe\'|g" $PREFIX/etc/profile.d/conda.sh
fi
{% set on_win = SUBDIR in ('win-64', 'win-32') %}
package:
name: conda
version: "{{ GIT_DESCRIBE_TAG }}"
version: {{ GIT_DESCRIBE_TAG }}.{{ GIT_BUILD_STR }}
source:
path: ../
# git_url is nice in that it won't capture devenv stuff. However, it only
# captures committed code, so pay attention.
git_url: ../
build:
# These are present when the new environment is created
# so we have to exempt them from the list of initial files
# for conda-build to realize they should be included.
always_include_files:
- bin/conda [unix]
- bin/activate [unix]
- bin/deactivate [unix]
- Scripts/activate.bat [win]
- Scripts/activate [win]
- Scripts/deactivate [win]
- bin/conda # [unix]
- bin/activate # [unix]
- bin/deactivate # [unix]
- Scripts/activate.bat # [win]
- Scripts/activate # [win]
- Scripts/deactivate # [win]
requirements:
build:
- m2-filesystem # [win]
- m2-bash # [win]
- m2-base # [win]
host:
- python
- conda-package-handling
- enum34 # [py<34]
- futures >=3.0.0 # [py<34]
- menuinst >=1.4.11,<2 # [win]
......@@ -30,6 +36,7 @@ requirements:
- setuptools >=31.0.1
run:
- python
- conda-package-handling
- enum34 # [py<34]
- futures >=3.0.0 # [py<34]
- menuinst >=1.4.11,<2 # [win]
......@@ -55,53 +62,37 @@ test:
- pexpect
- responses
- conda-build
- m2-filesystem # [win]
- m2-bash # [win]
- m2-base # [win]
imports:
- conda
- conda_env
commands:
{% if on_win %}
- echo
# - SET CONDA_SHLVL=
# - CALL %PREFIX%\condabin\conda_hook.bat
# - CALL conda.bat activate base
# - FOR /F "delims=" %%i IN ('python -c "import sys; print(sys.version_info[0])"') DO set "PYTHON_MAJOR_VERSION=%%i"
# - set TEST_PLATFORM=win
# - FOR /F "delims=" %%i IN ('python -c "import random as r; print(r.randint(0,4294967296))"') DO set "PYTHONHASHSEED=%%i"
# - set
# - conda info
# - conda create -y -p .\built-conda-test-env
# - CALL conda.bat activate .\built-conda-test-env
# - echo %CONDA_PREFIX%
# - IF NOT "%CONDA_PREFIX%"=="%CD%\built-conda-test-env" EXIT /B 1
# - CALL conda.bat deactivate
# - py.test tests -m "not integration and not installed" -vv
{% else %}
- unset CONDA_SHLVL
- eval "$(python -m conda shell.bash hook)"
- conda activate base
- export PYTHON_MAJOR_VERSION=$(python -c "import sys; print(sys.version_info[0])")
- export TEST_PLATFORM=$(python -c "import sys; print('win' if sys.platform.startswith('win') else 'unix')")
- export PYTHONHASHSEED=$(python -c "import random as r; print(r.randint(0,4294967296))") && echo "PYTHONHASHSEED=$PYTHONHASHSEED"
- env | sort
- conda info
- conda create -y -p ./built-conda-test-env
- conda activate ./built-conda-test-env
- echo $CONDA_PREFIX
- '[ "$CONDA_PREFIX" = "$PWD/built-conda-test-env" ] || exit 1'
- conda deactivate
- py.test tests -m "not integration and not installed" -vv
{% endif %}
about:
home: https://conda.io/
license: BSD
home: https://conda.io
license: BSD 3-Clause
license_file: LICENSE.txt
summary: OS-agnostic, system-level binary package and environment manager.
description: |
description: >
Conda is an open source package management system and environment
management system for installing multiple versions of software packages
and their dependencies and switching easily between them. It works on
Linux, OS X and Windows, and was created for Python programs but can
package and distribute any software.
doc_url: http://conda.pydata.org/docs/
doc_url: https://conda.io/projects/conda/en/latest/
dev_url: https://github.com/conda/conda
extra:
recipe-maintainers:
- jakirkham
- jjhelmus
- kalefranz
- mcg1969
- mingwandroid
- msarahan
- mwcraig
- ocefpaf
- patricksnape
- pelson
- scopatz
#!/usr/bin/env bash
set -x
unset CONDA_SHLVL
unset _CE_CONDA
unset _CE_M
unset CONDA_EXE
eval "$(python -m conda shell.bash hook)"
conda activate base
export PYTHON_MAJOR_VERSION=$(python -c "import sys; print(sys.version_info[0])")
export TEST_PLATFORM=$(python -c "import sys; print('win' if sys.platform.startswith('win') else 'unix')")
export PYTHONHASHSEED=$(python -c "import random as r; print(r.randint(0,4294967296))") && echo "PYTHONHASHSEED=$PYTHONHASHSEED"
env | sort
conda info
conda create -y -p ./built-conda-test-env python=3.5
conda activate ./built-conda-test-env
echo $CONDA_PREFIX
[ "$CONDA_PREFIX" = "$PWD/built-conda-test-env" ] || exit 1
[ $(python -c "import sys; print(sys.version_info[1])") = 5 ] || exit 1
conda deactivate
py.test tests -m "not integration and not installed" -vv
......@@ -66,7 +66,7 @@ if sys.version_info[0] < 3:
if 'CONDA_TEST_SAVE_TEMPS' in os.environ:
delete = False
return codecs.getwriter('utf-8')(NamedTemporaryFile(mode=mode, bufsize=bufsize, suffix=suffix,
prefix=template, dir=None, delete=delete))
prefix=template, dir=dir, delete=delete))
else:
def Utf8NamedTemporaryFile(mode='w+b', buffering=-1, newline=None,
suffix=None, prefix=None, dir=None, delete=True):
......
# -*- coding: utf-8 -*-
# Copyright (C) 2012 Anaconda, Inc
# SPDX-License-Identifier: BSD-3-Clause
......@@ -7,6 +8,7 @@ from collections import OrderedDict
from errno import ENOENT
from glob import glob
from itertools import chain
from logging import getLogger
import os
from os.path import abspath, basename, dirname, expanduser, expandvars, isdir, join
import re
......@@ -22,6 +24,8 @@ from .base.context import ROOT_ENV_NAME, context, locate_prefix_by_name
from .common.compat import FILESYSTEM_ENCODING, PY2, iteritems, on_win, string_types, text_type
from .common.path import paths_equal
log = getLogger(__name__)
class _Activator(object):
# Activate and deactivate have three tasks
......@@ -165,6 +169,9 @@ class _Activator(object):
builder.append(fsrc.read())
if auto_activate_base is None and context.auto_activate_base or auto_activate_base:
builder.append("conda activate base\n")
postamble = self._hook_postamble()
if postamble is not None:
builder.append(postamble)
return "\n".join(builder)
def execute(self):
......@@ -192,6 +199,9 @@ class _Activator(object):
# must be implemented in subclass
raise NotImplementedError()
def _hook_postamble(self):
return None
def _parse_and_set_args(self, arguments):
# the first index of arguments MUST be either activate, deactivate, or reactivate
if arguments is None:
......@@ -256,6 +266,9 @@ class _Activator(object):
self.command = command
def _yield_commands(self, cmds_dict):
for key, value in sorted(iteritems(cmds_dict.get('export_path', {}))):
yield self.export_var_tmpl % (key, value)
for script in cmds_dict.get('deactivate_scripts', ()):
yield self.run_script_tmpl % script
......@@ -354,6 +367,7 @@ class _Activator(object):
}
def build_deactivate(self):
self._deactivate = True
# query environment
old_conda_prefix = self.environ.get('CONDA_PREFIX')
old_conda_shlvl = int(self.environ.get('CONDA_SHLVL', '').strip() or 0)
......@@ -380,13 +394,13 @@ class _Activator(object):
# deactivated conda and anything at all in my env still references it (apart from the
# shell script, we need something I suppose!)
export_vars, unset_vars = self.get_export_unset_vars(odargs=OrderedDict((
('path', new_path),
('conda_prefix', None),
('conda_shlvl', new_conda_shlvl),
('conda_default_env', None),
('conda_prompt_modifier', None))))
conda_prompt_modifier = ''
activate_scripts = ()
export_path = {'PATH': new_path, }
else:
assert old_conda_shlvl > 1
new_prefix = self.environ.get('CONDA_PREFIX_%d' % new_conda_shlvl)
......@@ -406,13 +420,12 @@ class _Activator(object):
)
export_vars, unset_vars2 = self.get_export_unset_vars(odargs=OrderedDict((
('path', new_path),
('conda_prefix', new_prefix),
('conda_shlvl', new_conda_shlvl),
('conda_default_env', conda_default_env),
('conda_prompt_modifier', conda_prompt_modifier))))
unset_vars += unset_vars2
export_path = {'PATH': new_path, }
activate_scripts = self._get_activate_scripts(new_prefix)
if context.changeps1:
......@@ -422,11 +435,13 @@ class _Activator(object):
'unset_vars': unset_vars,
'set_vars': set_vars,
'export_vars': export_vars,
'export_path': export_path,
'deactivate_scripts': deactivate_scripts,
'activate_scripts': activate_scripts,
}
def build_reactivate(self):
self._reactivate = True
conda_prefix = self.environ.get('CONDA_PREFIX')
conda_shlvl = int(self.environ.get('CONDA_SHLVL', '').strip() or 0)
if not conda_prefix or conda_shlvl < 1:
......@@ -475,7 +490,6 @@ class _Activator(object):
clean_paths[sys.platform] if sys.platform in clean_paths else
'/usr/bin')
path_split = path.split(os.pathsep)
if on_win:
# We used to prepend sys.prefix\Library\bin to PATH on startup but not anymore.
# Instead, in conda 4.6 we add the full suite of entries. This is performed in
# condabin\conda.bat and condabin\ _conda_activate.bat. However, we
......@@ -546,8 +560,13 @@ class _Activator(object):
if first_idx is None:
first_idx = 0
else:
last_idx = index_of_path(path_list, prefix_dirs[-1])
assert last_idx is not None
prefix_dirs_idx = len(prefix_dirs) - 1
last_idx = None
while last_idx is None and prefix_dirs_idx > -1:
last_idx = index_of_path(path_list, prefix_dirs[prefix_dirs_idx])
if last_idx is None:
log.info("Did not find path entry {}".format(prefix_dirs[prefix_dirs_idx]))
prefix_dirs_idx = prefix_dirs_idx - 1
# this compensates for an extra Library/bin dir entry from the interpreter on
# windows. If that entry isn't being added, it should have no effect.
library_bin_dir = self.path_conversion(
......@@ -578,8 +597,44 @@ class _Activator(object):
def _prompt_modifier(self, prefix, conda_default_env):
if context.changeps1:
# Get current environment and prompt stack
env_stack = []
prompt_stack = []
old_shlvl = int(self.environ.get('CONDA_SHLVL', '0').rstrip())
for i in range(1, old_shlvl+1):
if i == old_shlvl:
env_i = self._default_env(self.environ.get('CONDA_PREFIX', ''))
else:
env_i = self._default_env(
self.environ.get('CONDA_PREFIX_{}'.format(i), '').rstrip())
stacked_i = bool(self.environ.get('CONDA_STACKED_{}'.format(i), '').rstrip())
env_stack.append(env_i)
if not stacked_i:
prompt_stack = prompt_stack[0:-1]
prompt_stack.append(env_i)
# Modify prompt stack according to pending operation
deactivate = getattr(self, '_deactivate', False)
reactivate = getattr(self, '_reactivate', False)
if deactivate:
prompt_stack = prompt_stack[0:-1]
env_stack = env_stack[0:-1]
stacked = bool(self.environ.get('CONDA_STACKED_{}'.format(old_shlvl), '').rstrip())
if not stacked and env_stack:
prompt_stack.append(env_stack[-1])
elif reactivate:
pass
else:
stack = getattr(self, 'stack', False)
if not stack:
prompt_stack = prompt_stack[0:-1]
prompt_stack.append(conda_default_env)
conda_stacked_env = ','.join(prompt_stack[::-1])
return context.env_prompt.format(
default_env=conda_default_env,
stacked_env=conda_stacked_env,
prefix=prefix,
name=basename(prefix),
)
......@@ -673,11 +728,11 @@ def native_path_to_unix(paths): # pragma: unix no cover
def path_identity(paths):
if isinstance(paths, string_types):
return paths
return os.path.normpath(paths)
elif paths is None:
return None
else:
return tuple(paths)
return tuple(os.path.normpath(_) for _ in paths)
class PosixActivator(_Activator):
......@@ -716,22 +771,6 @@ class PosixActivator(_Activator):
})
def _hook_preamble(self):
if on_win:
if context.dev:
return ('export CONDA_EXE="$(cygpath \'%s\')"\n'
'export _CE_M=-m\n'
'export _CE_CONDA=conda\n'
'export PYTHONPATH="$(cygpath \'%s\')"\n'
% (sys.executable, dirname(CONDA_PACKAGE_ROOT))
)
else:
return ('export CONDA_EXE="$(cygpath \'%s\')"\n'
'export _CE_M=-m\n'
'export _CE_CONDA=conda\n'
'export CONDA_BAT="%s"'
% (context.conda_exe, join(context.conda_prefix, 'condabin', 'conda.bat'))
)
else:
result = ''
for key, value in context.conda_exe_vars_dict.items():
if value is None:
......@@ -739,6 +778,10 @@ class PosixActivator(_Activator):
# with shell flag -u set (error on unset).
# result += join(self.unset_var_tmpl % key) + '\n'
result += join(self.export_var_tmpl % (key, '')) + '\n'
else:
if key in ('PYTHONPATH', 'CONDA_EXE'):
result += join(self.export_var_tmpl % (
key, self.path_conversion(value))) + '\n'
else:
result += join(self.export_var_tmpl % (key, value)) + '\n'
return result
......@@ -776,13 +819,16 @@ class CshActivator(_Activator):
if on_win:
return ('setenv CONDA_EXE `cygpath %s`\n'
'setenv _CONDA_ROOT `cygpath %s`\n'
'setenv _CONDA_EXE `cygpath %s`'
% (context.conda_exe, context.conda_prefix, context.conda_exe))
'setenv _CONDA_EXE `cygpath %s`\n'
'setenv CONDA_PYTHON_EXE `cygpath %s`'
% (context.conda_exe, context.conda_prefix, context.conda_exe, sys.executable))
else:
return ('setenv CONDA_EXE "%s"\n'
'setenv _CONDA_ROOT "%s"\n'
'setenv _CONDA_EXE "%s"'
% (context.conda_exe, context.conda_prefix, context.conda_exe))
'setenv _CONDA_EXE "%s"\n'
'setenv CONDA_PYTHON_EXE "%s"'
% (context.conda_exe, context.conda_prefix, context.conda_exe,
sys.executable))
class XonshActivator(_Activator):
......@@ -792,7 +838,7 @@ class XonshActivator(_Activator):
self.sep = '/'
self.path_conversion = native_path_to_unix
self.script_extension = '.xsh'
self.tempfile_extension = '.xsh'
self.tempfile_extension = None
self.command_join = '\n'
self.unset_var_tmpl = 'del $%s'
......@@ -805,7 +851,7 @@ class XonshActivator(_Activator):
super(XonshActivator, self).__init__(arguments)
def _hook_preamble(self):
return 'CONDA_EXE = "%s"' % context.conda_exe
return '$CONDA_EXE = "%s"' % context.conda_exe
class CmdExeActivator(_Activator):
......@@ -858,13 +904,15 @@ class FishActivator(_Activator):
if on_win:
return ('set -gx CONDA_EXE (cygpath "%s")\n'
'set _CONDA_ROOT (cygpath "%s")\n'
'set _CONDA_EXE (cygpath "%s")'
% (context.conda_exe, context.conda_prefix, context.conda_exe))
'set _CONDA_EXE (cygpath "%s")\n'
'set -gx CONDA_PYTHON_EXE (cygpath "%s")'
% (context.conda_exe, context.conda_prefix, context.conda_exe, sys.executable))
else:
return ('set -gx CONDA_EXE "%s"\n'
'set _CONDA_ROOT "%s"\n'
'set _CONDA_EXE "%s"'
% (context.conda_exe, context.conda_prefix, context.conda_exe))
'set _CONDA_EXE "%s"\n'
'set -gx CONDA_PYTHON_EXE "%s"'
% (context.conda_exe, context.conda_prefix, context.conda_exe, sys.executable))
class PowerShellActivator(_Activator):
......@@ -878,8 +926,8 @@ class PowerShellActivator(_Activator):
self.command_join = '\n'
self.unset_var_tmpl = 'Remove-Item Env:/%s'
self.export_var_tmpl = '$env:%s = "%s"'
self.set_var_tmpl = '$env:%s = "%s"'
self.export_var_tmpl = '$Env:%s = "%s"'
self.set_var_tmpl = '$Env:%s = "%s"'
self.run_script_tmpl = '. "%s"'
self.hook_source_path = join(CONDA_PACKAGE_ROOT, 'shell', 'condabin', 'conda-hook.ps1')
......@@ -889,12 +937,15 @@ class PowerShellActivator(_Activator):
def _hook_preamble(self):
if context.dev:
return dedent("""\
$Env:CONDA_EXE = "{context.conda_exe}"
$Env:PYTHONPATH = "{python_path}"
$Env:CONDA_EXE = "{sys_exe}"
$Env:_CE_M = "-m"
$Env:_CE_CONDA = "conda"
$Env:_CONDA_ROOT = "{context.conda_prefix}"
$Env:_CONDA_ROOT = "{python_path}{s}conda"
$Env:_CONDA_EXE = "{context.conda_exe}"
""".format(context=context))
""".format(s=os.sep,
python_path=dirname(CONDA_PACKAGE_ROOT),
sys_exe=sys.executable, context=context))
else:
return dedent("""\
$Env:CONDA_EXE = "{context.conda_exe}"
......@@ -904,6 +955,11 @@ class PowerShellActivator(_Activator):
$Env:_CONDA_EXE = "{context.conda_exe}"
""".format(context=context))
def _hook_postamble(self):
if context.changeps1:
return "Add-CondaEnvironmentToPrompt"
return None
activator_map = {
'posix': PosixActivator,
......
......@@ -6,8 +6,8 @@ from __future__ import absolute_import, division, print_function, unicode_litera
from .common.constants import NULL
from .core.package_cache_data import PackageCacheData as _PackageCacheData
from .core.prefix_data import PrefixData as _PrefixData
from .core.solve import (DepsModifier as _DepsModifier, Solver as _Solver,
UpdateModifier as _UpdateModifier)
from .core.solve import DepsModifier as _DepsModifier, Solver as _Solver
from .core.solve import UpdateModifier as _UpdateModifier
from .core.subdir_data import SubdirData as _SubdirData
from .models.channel import Channel
......
......@@ -78,13 +78,11 @@ RECOGNIZED_URL_SCHEMES = ('http', 'https', 'ftp', 's3', 'file')
DEFAULT_CHANNELS_UNIX = (
'https://repo.anaconda.com/pkgs/main',
'https://repo.anaconda.com/pkgs/free',
'https://repo.anaconda.com/pkgs/r',
)
DEFAULT_CHANNELS_WIN = (
'https://repo.anaconda.com/pkgs/main',
'https://repo.anaconda.com/pkgs/free',
'https://repo.anaconda.com/pkgs/r',
'https://repo.anaconda.com/pkgs/msys2',
)
......@@ -136,9 +134,17 @@ else:
# Maximum priority, reserved for packages we really want to remove
MAX_CHANNEL_PRIORITY = 10000
CONDA_TARBALL_EXTENSION = '.tar.bz2'
CONDA_PACKAGE_EXTENSION_V1 = ".tar.bz2"
CONDA_PACKAGE_EXTENSION_V2 = ".conda"
CONDA_PACKAGE_EXTENSIONS = (
CONDA_PACKAGE_EXTENSION_V2,
CONDA_PACKAGE_EXTENSION_V1,
)
CONDA_TARBALL_EXTENSION = CONDA_PACKAGE_EXTENSION_V1 # legacy support for conda-build; remove this line # NOQA
CONDA_TEMP_EXTENSION = '.c~'
UNKNOWN_CHANNEL = "<unknown>"
REPODATA_FN = 'repodata.json'
class SafetyChecks(Enum):
......
......@@ -12,7 +12,7 @@ from os.path import abspath, basename, expanduser, isdir, isfile, join, split as
import platform
import sys
from .constants import (APP_NAME, ChannelPriority, DEFAULTS_CHANNEL_NAME,
from .constants import (APP_NAME, ChannelPriority, DEFAULTS_CHANNEL_NAME, REPODATA_FN,
DEFAULT_AGGRESSIVE_UPDATE_PACKAGES, DEFAULT_CHANNELS,
DEFAULT_CHANNEL_ALIAS, DEFAULT_CUSTOM_CHANNELS, DepsModifier,
ERROR_UPLOAD_URL, PLATFORM_DIRECTORIES, PREFIX_MAGIC_FILE, PathConflict,
......@@ -27,9 +27,10 @@ from .._vendor.toolz import concat, concatv, unique
from ..common.compat import NoneType, iteritems, itervalues, odict, on_win, string_types
from ..common.configuration import (Configuration, ConfigurationLoadError, MapParameter,
PrimitiveParameter, SequenceParameter, ValidationError)
from ..common.os.linux import linux_get_libc_version
from ..common._os.linux import linux_get_libc_version
from ..common.path import expand, paths_equal
from ..common.url import has_scheme, path_to_url, split_scheme_auth_token
from ..common.decorators import env_override
from .. import CONDA_PACKAGE_ROOT
......@@ -142,6 +143,17 @@ class Context(Configuration):
pip_interop_enabled = PrimitiveParameter(False)
# multithreading in various places
_default_threads = PrimitiveParameter(0, element_type=int,
aliases=('default_threads',))
_repodata_threads = PrimitiveParameter(0, element_type=int,
aliases=('repodata_threads',))
_verify_threads = PrimitiveParameter(0, element_type=int,
aliases=('verify_threads',))
# this one actually defaults to 1 - that is handled in the property below
_execute_threads = PrimitiveParameter(0, element_type=int,
aliases=('execute_threads',))
# Safety & Security
_aggressive_update_packages = SequenceParameter(string_types,
DEFAULT_AGGRESSIVE_UPDATE_PACKAGES,
......@@ -157,6 +169,8 @@ class Context(Configuration):
track_features = SequenceParameter(string_types)
use_index_cache = PrimitiveParameter(False)
separate_format_cache = PrimitiveParameter(False)
_root_prefix = PrimitiveParameter("", aliases=('root_dir', 'root_prefix'))
_envs_dirs = SequenceParameter(string_types, aliases=('envs_dirs', 'envs_path'),
string_delimiter=os.pathsep,
......@@ -216,6 +230,10 @@ class Context(Configuration):
show_channel_urls = PrimitiveParameter(None, element_type=(bool, NoneType))
use_local = PrimitiveParameter(False)
whitelist_channels = SequenceParameter(string_types, expandvars=True)
restore_free_channel = PrimitiveParameter(False)
repodata_fns = SequenceParameter(string_types, ("current_repodata.json", REPODATA_FN))
_use_only_tar_bz2 = PrimitiveParameter(None, element_type=(bool, NoneType),
aliases=('use_only_tar_bz2',))
always_softlink = PrimitiveParameter(False, aliases=('softlink',))
always_copy = PrimitiveParameter(False, aliases=('copy',))
......@@ -249,12 +267,13 @@ class Context(Configuration):
# update_specs = PrimitiveParameter(False)
# update_all = PrimitiveParameter(False)
prune = PrimitiveParameter(False)
force_remove = PrimitiveParameter(False)
force_reinstall = PrimitiveParameter(False)
target_prefix_override = PrimitiveParameter('')
unsatisfiable_hints = PrimitiveParameter(True)
# conda_build
bld_path = PrimitiveParameter('')
anaconda_upload = PrimitiveParameter(None, aliases=('binstar_upload',),
......@@ -358,6 +377,34 @@ class Context(Configuration):
def platform(self):
return _platform_map.get(sys.platform, 'unknown')
@property
def default_threads(self):
return self._default_threads if self._default_threads else None
@property
def repodata_threads(self):
return self._repodata_threads if self._repodata_threads else self.default_threads
@property
def verify_threads(self):
if self._verify_threads:
threads = self._verify_threads
elif self.default_threads:
threads = self.default_threads
else:
threads = 1
return threads
@property
def execute_threads(self):
if self._execute_threads:
threads = self._execute_threads
elif self.default_threads:
threads = self.default_threads
else:
threads = 1
return threads
@property
def subdir(self):
if self._subdir:
......@@ -502,7 +549,8 @@ class Context(Configuration):
('PYTHONPATH', os.path.dirname(CONDA_PACKAGE_ROOT) + '{}{}'.format(
os.pathsep, os.environ.get('PYTHONPATH', ''))),
('_CE_M', '-m'),
('_CE_CONDA', 'conda')])
('_CE_CONDA', 'conda'),
('CONDA_PYTHON_EXE', sys.executable)])
else:
bin_dir = 'Scripts' if on_win else 'bin'
exe = 'conda.exe' if on_win else 'conda'
......@@ -510,7 +558,8 @@ class Context(Configuration):
# error-on-undefined.
return OrderedDict([('CONDA_EXE', os.path.join(sys.prefix, bin_dir, exe)),
('_CE_M', ''),
('_CE_CONDA', '')])
('_CE_CONDA', ''),
('CONDA_PYTHON_EXE', sys.executable)])
@memoizedproperty
def channel_alias(self):
......@@ -541,8 +590,12 @@ class Context(Configuration):
def custom_multichannels(self):
from ..models.channel import Channel
default_channels = list(self._default_channels)
if self.restore_free_channel:
default_channels.insert(1, 'https://repo.anaconda.com/pkgs/free')
reserved_multichannel_urls = odict((
(DEFAULTS_CHANNEL_NAME, self._default_channels),
(DEFAULTS_CHANNEL_NAME, default_channels),
('local', self.conda_build_local_urls),
))
reserved_multichannels = odict(
......@@ -605,6 +658,27 @@ class Context(Configuration):
(DEFAULTS_CHANNEL_NAME,))))
return tuple(IndexedSet(concatv(local_add, self._channels)))
@property
def use_only_tar_bz2(self):
from ..models.version import VersionOrder
# we avoid importing this at the top to avoid PATH issues. Ensure that this
# is only called when use_only_tar_bz2 is first called.
import conda_package_handling.api
use_only_tar_bz2 = False
if self._use_only_tar_bz2 is None:
try:
import conda_build
use_only_tar_bz2 = VersionOrder(conda_build.__version__) < VersionOrder("3.18.3")
except ImportError:
pass
if self._argparse_args and 'use_only_tar_bz2' in self._argparse_args:
use_only_tar_bz2 &= self._argparse_args['use_only_tar_bz2']
return ((hasattr(conda_package_handling.api, 'libarchive_enabled') and
not conda_package_handling.api.libarchive_enabled) or
self._use_only_tar_bz2 or
use_only_tar_bz2)
@property
def binstar_upload(self):
# backward compatibility for conda-build
......@@ -689,6 +763,12 @@ class Context(Configuration):
info = _get_cpu_info()
return info['flags']
@memoizedproperty
@env_override('CONDA_OVERRIDE_CUDA', convert_empty_to_none=True)
def cuda_version(self):
from conda.common.cuda import cuda_detect
return cuda_detect()
@property
def category_map(self):
return odict((
......@@ -704,10 +784,15 @@ class Context(Configuration):
'migrated_custom_channels',
'add_anaconda_token',
'allow_non_channel_urls',
'restore_free_channel',
'repodata_fns',
'use_only_tar_bz2',
'repodata_threads',
)),
('Basic Conda Configuration', ( # TODO: Is there a better category name here?
'envs_dirs',
'pkgs_dirs',
'default_threads',
)),
('Network Configuration', (
'client_ssl_cert',
......@@ -729,7 +814,6 @@ class Context(Configuration):
'force_reinstall',
'pinned_packages',
'pip_interop_enabled',
'prune',
'track_features',
)),
('Package Linking and Install-time Configuration', (
......@@ -742,6 +826,9 @@ class Context(Configuration):
'extra_safety_checks',
'shortcuts',
'non_admin_enabled',
'separate_format_cache',
'verify_threads',
'execute_threads',
)),
('Conda-build Configuration', (
'bld_path',
......@@ -760,6 +847,7 @@ class Context(Configuration):
'report_errors',
'show_channel_urls',
'verbosity',
'unsatisfiable_hints'
)),
('CLI-only', (
'deps_modifier',
......@@ -932,6 +1020,14 @@ class Context(Configuration):
# version of Python (2/3) to be used in new environments. Defaults to
# the version used by conda itself.
# """),
'default_threads': dals("""
Threads to use by default for parallel operations. Default is None,
which allows operations to choose themselves. For more specific
control, see the other *_threads parameters:
* repodata_threads - for fetching/loading repodata
* verify_threads - for verifying package contents in transactions
* execute_threads - for carrying out the unlinking and linking steps
"""),
'disallowed_packages': dals("""
Package specifications to disallow installing. The default is to allow
all packages.
......@@ -954,6 +1050,11 @@ class Context(Configuration):
flag), or otherwise holds the value of '{prefix}'. Templating uses python's
str.format() method.
"""),
'execute_threads': dals("""
Threads to use when performing the unlink/link transaction. When not set,
defaults to 1. This step is pretty strongly I/O limited, and you may not
see much benefit here.
"""),
'force_reinstall': dals("""
Ensure that any user-requested package for the current operation is uninstalled
and reinstalled, even if that package already exists in the environment.
......@@ -1029,10 +1130,6 @@ class Context(Configuration):
'scheme://[user:password@]host[:port]'. The optional 'user:password' inclusion
enables HTTP Basic Auth with your proxy.
"""),
'prune': dals("""
Remove packages that have previously been brought into an environment to satisfy
dependencies of user-requested packages, but are no longer needed.
"""),
'quiet': dals("""
Disable progress bar display and other output.
"""),
......@@ -1048,11 +1145,19 @@ class Context(Configuration):
read timeout is the number of seconds conda will wait for the server to send
a response.
"""),
'repodata_threads': dals("""
Threads to use when downloading and reading repodata. When not set,
defaults to None, which uses the default ThreadPoolExecutor behavior.
"""),
'report_errors': dals("""
Opt in, or opt out, of automatic error reporting to core maintainers. Error
reports are anonymous, with only the error stack trace and information given
by `conda info` being sent.
"""),
'restore_free_channel': dals(""""
Add the "free" channel back into defaults, behind "main" in priority. The "free"
channel was removed from the collection of default channels in conda 4.7.0.
"""),
'rollback_enabled': dals("""
Should any error occur during an unlink/link transaction, revert any disk
mutations made to that point in the transaction.
......@@ -1061,6 +1166,14 @@ class Context(Configuration):
Enforce available safety guarantees during package installation.
The value must be one of 'enabled', 'warn', or 'disabled'.
"""),
'separate_format_cache': dals("""
Treat .tar.bz2 files as different from .conda packages when
filenames are otherwise similar. This defaults to False, so
that your package cache doesn't churn when rolling out the new
package format. If you'd rather not assume that a .tar.bz2 and
.conda from the same place represent the same content, set this
to True.
"""),
'extra_safety_checks': dals("""
Spend extra time validating package contents. Currently, runs sha256 verification
on every file within each package during installation.
......@@ -1084,19 +1197,40 @@ class Context(Configuration):
A list of features that are tracked by default. An entry here is similar to
adding an entry to the create_default_packages list.
"""),
'repodata_fns': dals("""
Specify filenames for repodata fetching. The default is ('current_repodata.json',
'repodata.json'), which tries a subset of the full index containing only the
latest version for each package, then falls back to repodata.json. You may
want to specify something else to use an alternate index that has been reduced
somehow.
"""),
'use_index_cache': dals("""
Use cache of channel index files, even if it has expired.
"""),
'use_only_tar_bz2': dals("""
A boolean indicating that only .tar.bz2 conda packages should be downloaded.
This is forced to True if conda-build is installed and older than 3.18.3,
because older versions of conda break when conda feeds it the new file format.
"""),
'verbosity': dals("""
Sets output log level. 0 is warn. 1 is info. 2 is debug. 3 is trace.
"""),
'verify_threads': dals("""
Threads to use when performing the transaction verification step. When not set,
defaults to 1.
"""),
'whitelist_channels': dals("""
The exclusive list of channels allowed to be used on the system. Use of any
other channels will result in an error. If conda-build channels are to be
allowed, along with the --use-local command line flag, be sure to include the
'local' channel in the list. If the list is empty or left undefined, no
channel exclusions will be enforced.
""")
"""),
'unsatisfiable_hints': dals("""
A boolean to determine if conda should find conflicting packages in the case
of a failed install.
"""),
})
......@@ -1107,6 +1241,7 @@ def conda_in_private_env():
def reset_context(search_path=SEARCH_PATH, argparse_args=None):
global context
context.__init__(search_path, argparse_args)
context.__dict__.pop('_Context__conda_build', None)
from ..models.channel import Channel
......@@ -1180,17 +1315,19 @@ def stack_context_default(pushing, argparse_args=None):
return stack_context(pushing, search_path=(), argparse_args=argparse_args)
def replace_context(pushing, search_path=SEARCH_PATH, argparse_args=None):
def replace_context(pushing=None, search_path=SEARCH_PATH, argparse_args=None):
# pushing arg intentionally not used here, but kept for API compatibility
return context_stack.replace(search_path, argparse_args)
def replace_context_default(pushing, argparse_args=None):
def replace_context_default(pushing=None, argparse_args=None):
# pushing arg intentionally not used here, but kept for API compatibility
return context_stack.replace(search_path=(), argparse_args=argparse_args)
# Tests that want to only declare 'I support the project-wide default for how to
# manage stacking of contexts'. Tests that are known to be careful with context
# can use `replace_context_with_default` which might be faster, though it should
# can use `replace_context_default` which might be faster, though it should
# be a stated goal to set conda_tests_ctxt_mgmt_def_pol to replace_context_default
# and not to stack_context_default.
conda_tests_ctxt_mgmt_def_pol = replace_context_default
......@@ -1269,7 +1406,7 @@ def determine_target_prefix(ctx, args=None):
elif prefix_path is not None:
return expand(prefix_path)
else:
disallowed_chars = ('/', ' ', ':')
disallowed_chars = ('/', ' ', ':', '#')
if any(_ in prefix_name for _ in disallowed_chars):
from ..exceptions import CondaValueError
builder = ["Invalid environment name: '" + prefix_name + "'"]
......
......@@ -204,7 +204,7 @@ def print_envs_list(known_conda_prefixes, output=True):
def check_non_admin():
from ..common.os import is_admin
from ..common._os import is_admin
if not context.non_admin_enabled and not is_admin():
from ..exceptions import OperationNotAllowed
raise OperationNotAllowed(dals("""
......
......@@ -1437,6 +1437,17 @@ def add_parser_channels(p):
action="store_true",
help="""Do not search default or .condarc channels. Requires --channel.""",
)
channel_customization_options.add_argument(
"--repodata-fn",
action="append",
dest="repodata_fns",
help=("Specify name of repodata on remote server. Conda will try "
"whatever you specify, but will ultimately fall back to repodata.json if "
"your specs are not satisfiable with what you specify here. This is used "
"to employ repodata that is reduced in time scope. You may pass this flag"
"more than once. Leftmost entries are tried first, and the fallback to"
"repodata.json is added for you automatically.")
)
return channel_customization_options
......@@ -1531,6 +1542,14 @@ def add_parser_update_modifiers(solver_mode_options):
help="Update all installed packages in the environment.",
default=NULL,
)
update_modifiers.add_argument(
"--update-specs",
action="store_const",
const=UpdateModifier.UPDATE_SPECS,
dest="update_modifier",
help="Update based on provided specifications.",
default=NULL,
)
def add_parser_prune(p):
......@@ -1538,8 +1557,7 @@ def add_parser_prune(p):
"--prune",
action="store_true",
default=NULL,
help="Remove packages that have previously been brought into the environment to satisfy "
"dependencies of user-requested packages, but are no longer needed.",
help=SUPPRESS,
)
......
......@@ -11,10 +11,11 @@ from . import common
from .common import check_non_admin
from .. import CondaError
from .._vendor.auxlib.ish import dals
from ..base.constants import ROOT_ENV_NAME, UpdateModifier
from ..base.constants import ROOT_ENV_NAME, UpdateModifier, REPODATA_FN
from ..base.context import context, locate_prefix_by_name
from ..common.compat import on_win, text_type
from ..common.path import paths_equal
from ..common.compat import text_type
from ..common.constants import NULL
from ..common.path import paths_equal, is_package_file
from ..core.index import calculate_channel_urls, get_index
from ..core.prefix_data import PrefixData
from ..core.solve import DepsModifier, Solver
......@@ -22,7 +23,8 @@ from ..exceptions import (CondaExitZero, CondaImportError, CondaOSError, CondaSy
CondaValueError, DirectoryNotACondaEnvironmentError,
DirectoryNotFoundError, DryRunExit, EnvironmentLocationNotFound,
NoBaseEnvironmentError, PackageNotInstalledError, PackagesNotFoundError,
TooManyArgumentsError, UnsatisfiableError)
TooManyArgumentsError, UnsatisfiableError,
SpecsConfigurationConflictError)
from ..gateways.disk.create import mkdir_p
from ..gateways.disk.delete import delete_trash, path_is_clean
from ..misc import clone_env, explicit, touch_nonadmin
......@@ -82,7 +84,6 @@ def clone(src_arg, dst_prefix, json=False, quiet=False, index_args=None):
def print_activate(env_name_or_prefix): # pragma: no cover
if not context.quiet and not context.json:
if 'CONDA_SHLVL' in os.environ or os.path.split(os.environ.get('SHELL', ''))[-1] == 'fish':
message = dals("""
#
# To activate this environment, use
......@@ -93,28 +94,6 @@ def print_activate(env_name_or_prefix): # pragma: no cover
#
# $ conda deactivate
""") % env_name_or_prefix
elif on_win:
message = dals("""
#
# To activate this environment, use:
# > activate %s
#
# To deactivate an active environment, use:
# > deactivate
#
# * for power-users using bash, you must source
#
""") % env_name_or_prefix
else:
message = dals("""
#
# To activate this environment, use:
# > conda activate %s
#
# To deactivate an active environment, use:
# > conda deactivate
#
""") % env_name_or_prefix
print(message) # TODO: use logger
......@@ -131,10 +110,16 @@ def install(args, parser, command='install'):
"""
context.validate_configuration()
check_non_admin()
# this is sort of a hack. current_repodata.json may not have any .tar.bz2 files,
# because it deduplicates records that exist as both formats. Forcing this to
# repodata.json ensures that .tar.bz2 files are available
if context.use_only_tar_bz2:
args.repodata_fns = ('repodata.json', )
newenv = bool(command == 'create')
isupdate = bool(command == 'update')
isinstall = bool(command == 'install')
isremove = bool(command == 'remove')
if newenv:
common.ensure_name_or_prefix(args, command)
prefix = context.target_prefix
......@@ -189,7 +174,7 @@ def install(args, parser, command='install'):
'use_local': args.use_local
}
num_cp = sum(s.endswith('.tar.bz2') for s in args_packages)
num_cp = sum(is_package_file(s) for s in args_packages)
if num_cp:
if num_cp == len(args_packages):
explicit(args_packages, prefix, verbose=not context.quiet)
......@@ -239,39 +224,96 @@ def install(args, parser, command='install'):
print_activate(args.name if args.name else prefix)
return
repodata_fns = args.repodata_fns
if not repodata_fns:
repodata_fns = context.repodata_fns
if REPODATA_FN not in repodata_fns:
repodata_fns.append(REPODATA_FN)
args_set_update_modifier = hasattr(args, "update_modifier") and args.update_modifier != NULL
# This helps us differentiate between an update, the --freeze-installed option, and the retry
# behavior in our initial fast frozen solve
_should_retry_unfrozen = (not args_set_update_modifier or args.update_modifier not in (
UpdateModifier.FREEZE_INSTALLED,
UpdateModifier.UPDATE_SPECS)) and not newenv
for repodata_fn in repodata_fns:
try:
if isinstall and args.revision:
index = get_index(channel_urls=index_args['channel_urls'],
prepend=index_args['prepend'], platform=None,
use_local=index_args['use_local'], use_cache=index_args['use_cache'],
unknown=index_args['unknown'], prefix=prefix)
unlink_link_transaction = revert_actions(prefix, get_revision(args.revision), index)
use_local=index_args['use_local'],
use_cache=index_args['use_cache'],
unknown=index_args['unknown'], prefix=prefix,
repodata_fn=repodata_fn)
unlink_link_transaction = revert_actions(prefix, get_revision(args.revision),
index)
else:
solver = Solver(prefix, context.channels, context.subdirs, specs_to_add=specs,
repodata_fn=repodata_fn, command=args.cmd)
update_modifier = context.update_modifier
if (isinstall or isremove) and args.update_modifier == NULL:
update_modifier = UpdateModifier.FREEZE_INSTALLED
deps_modifier = context.deps_modifier
if isupdate:
deps_modifier = context.deps_modifier or DepsModifier.UPDATE_SPECS
else:
deps_modifier = context.deps_modifier
solver = Solver(prefix, context.channels, context.subdirs, specs_to_add=specs)
unlink_link_transaction = solver.solve_for_transaction(
deps_modifier=deps_modifier,
update_modifier=update_modifier,
force_reinstall=context.force_reinstall or context.force,
should_retry_solve=(_should_retry_unfrozen or repodata_fn != repodata_fns[-1]),
)
except ResolvePackageNotFound as e:
# we only need one of these to work. If we haven't raised an exception,
# we're good.
break
except (ResolvePackageNotFound, PackagesNotFoundError) as e:
# end of the line. Raise the exception
if repodata_fn == repodata_fns[-1]:
# PackagesNotFoundError is the only exception type we want to raise.
# Over time, we should try to get rid of ResolvePackageNotFound
if isinstance(e, PackagesNotFoundError):
raise e
else:
channels_urls = tuple(calculate_channel_urls(
channel_urls=index_args['channel_urls'],
prepend=index_args['prepend'],
platform=None,
use_local=index_args['use_local'],
))
# convert the ResolvePackageNotFound into PackagesNotFoundError
raise PackagesNotFoundError(e._formatted_chains, channels_urls)
except (UnsatisfiableError, SystemExit) as e:
except (UnsatisfiableError, SystemExit, SpecsConfigurationConflictError) as e:
# Quick solve with frozen env or trimmed repodata failed. Try again without that.
if not hasattr(args, 'update_modifier'):
if repodata_fn == repodata_fns[-1]:
raise e
elif _should_retry_unfrozen:
try:
unlink_link_transaction = solver.solve_for_transaction(
deps_modifier=deps_modifier,
update_modifier=UpdateModifier.UPDATE_SPECS,
force_reinstall=context.force_reinstall or context.force,
should_retry_solve=(repodata_fn != repodata_fns[-1]),
)
except (UnsatisfiableError, SystemExit, SpecsConfigurationConflictError) as e:
# Unsatisfiable package specifications/no such revision/import error
if e.args and 'could not import' in e.args[0]:
raise CondaImportError(text_type(e))
raise
# we want to fall through without raising if we're not at the end of the list
# of fns. That way, we fall to the next fn.
if repodata_fn == repodata_fns[-1]:
raise e
elif repodata_fn != repodata_fns[-1]:
continue # if we hit this, we should retry with next repodata source
else:
# end of the line. Raise the exception
# Unsatisfiable package specifications/no such revision/import error
if e.args and 'could not import' in e.args[0]:
raise CondaImportError(text_type(e))
raise e
handle_txn(unlink_link_transaction, prefix, args, newenv)
......
......@@ -6,12 +6,11 @@ from __future__ import absolute_import, division, print_function, unicode_litera
from collections import defaultdict
import fnmatch
from logging import getLogger
from os import listdir, lstat, walk, unlink
from os.path import getsize, isdir, join, exists
from os import listdir, lstat, unlink, walk
from os.path import exists, getsize, isdir, join
import sys
from ..base.constants import CONDA_TARBALL_EXTENSION
from ..common.constants import CONDA_TEMP_EXTENSION
from ..base.constants import CONDA_PACKAGE_EXTENSIONS, CONDA_TEMP_EXTENSION
from ..base.context import context
log = getLogger(__name__)
......@@ -21,14 +20,14 @@ def find_tarballs():
from ..core.package_cache_data import PackageCacheData
pkgs_dirs = defaultdict(list)
totalsize = 0
part_ext = CONDA_TARBALL_EXTENSION + '.part'
part_ext = tuple(e + '.part' for e in CONDA_PACKAGE_EXTENSIONS)
for package_cache in PackageCacheData.writable_caches(context.pkgs_dirs):
pkgs_dir = package_cache.pkgs_dir
if not isdir(pkgs_dir):
continue
root, _, filenames = next(walk(pkgs_dir))
for fn in filenames:
if fn.endswith(CONDA_TARBALL_EXTENSION) or fn.endswith(part_ext):
if fn.endswith(CONDA_PACKAGE_EXTENSIONS) or fn.endswith(part_ext):
pkgs_dirs[pkgs_dir].append(fn)
totalsize += getsize(join(root, fn))
......