{"action":"created","issue":{"url":"https://api.github.com/repos/pypa/pip/issues/3137","labels_url":"https://api.github.com/repos/pypa/pip/issues/3137/labels{/name}","comments_url":"https://api.github.com/repos/pypa/pip/issues/3137/comments","events_url":"https://api.github.com/repos/pypa/pip/issues/3137/events","html_url":"https://github.com/pypa/pip/pull/3137","id":108250489,"number":3137,"title":"Repeatable installs via hashing","user":{"login":"erikrose","id":295816,"avatar_url":"https://avatars.githubusercontent.com/u/295816?v=3","gravatar_id":"","url":"https://api.github.com/users/erikrose","html_url":"https://github.com/erikrose","followers_url":"https://api.github.com/users/erikrose/followers","following_url":"https://api.github.com/users/erikrose/following{/other_user}","gists_url":"https://api.github.com/users/erikrose/gists{/gist_id}","starred_url":"https://api.github.com/users/erikrose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erikrose/subscriptions","organizations_url":"https://api.github.com/users/erikrose/orgs","repos_url":"https://api.github.com/users/erikrose/repos","events_url":"https://api.github.com/users/erikrose/events{/privacy}","received_events_url":"https://api.github.com/users/erikrose/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":22,"created_at":"2015-09-25T02:27:13Z","updated_at":"2015-10-19T18:33:10Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/pypa/pip/pulls/3137","html_url":"https://github.com/pypa/pip/pull/3137","diff_url":"https://github.com/pypa/pip/pull/3137.diff","patch_url":"https://github.com/pypa/pip/pull/3137.patch"},"body":"Add checks against requirements-file-dwelling hashes for most kinds of packages. Close #1175.\r\n\r\nThis lets you add `--hash=sha256:abcde…` to a line in a requirements file to verify a package against a good local hash, guaranteeing repeatable installs without needing to run your own index mirrors, in the vein of https://pypi.python.org/pypi/peep/.\r\n\r\n* Add --require-hashes option. This is handy in deployment scripts to force application authors to hash their requirements. It is also a convenient way to get pip to show computed hashes for a virgin, unhashed requirements file. Eventually, additions to `pip freeze` should fill a superset of this use case.\r\n  * In --require-hashes mode, at least one hash is required to match for each requirement, even subrequirements.\r\n  * Option-based requirements (--hash=sha256:...) turn on --require-hashes mode implicitly.\r\n  * Internet-derived URL-based hashes are \"necessary but not sufficient\": they do not satisfy --require-hashes mode when they match, but they are still used to guard against transmission errors.\r\n  * Locally stored URL-based requirements (#md5=...) are treated just like option-based ones, except they don't turn on --require-hashes. Basically, that spelling is deprecated in favor of the option syntax.\r\n  * --require-hashes disallows --egg, which would bypass its dependency control by delegating everything to setuptools.\r\n* Complain informatively, with the most devastating errors first so you don't chase your tail all day only to run up against a brick wall at the end. This also means we don't complain that a hash is missing, only for the user to find, after fixing it, that we have no idea how to even compute a hash for that type of requirement.\r\n  * Complain about unpinned requirements when hash-checking mode is on, lest they cause the user surprise later.\r\n  * Complain about missing hashes.\r\n  * Complain about requirement types we don't know how to hash (like VCS ones and local dirs).\r\n* Have InstallRequirement keep its original Link around (original_link) so we can differentiate between URL hashes from requirements files and ones downloaded from the (untrustworthy) internet.\r\n* Remove test_download_hashes, which is obsolete. Similar coverage is provided in test_utils.TestHashes and the various hash cases in test_req.py.\r\n* Add a `pip hash` command for hashing package archives.\r\n* Add hash-checking support for `pip download` and `pip wheel`.\r\n\r\nFor a later release:\r\n\r\n* Support for --hash options on the commandline, interspersed with packages\r\n* Possible additions to `pip freeze`\r\n* See https://github.com/erikrose/peep/wiki/PipHashing for details"},"comment":{"url":"https://api.github.com/repos/pypa/pip/issues/comments/149306612","html_url":"https://github.com/pypa/pip/pull/3137#issuecomment-149306612","issue_url":"https://api.github.com/repos/pypa/pip/issues/3137","id":149306612,"user":{"login":"qwcode","id":1052224,"avatar_url":"https://avatars.githubusercontent.com/u/1052224?v=3","gravatar_id":"","url":"https://api.github.com/users/qwcode","html_url":"https://github.com/qwcode","followers_url":"https://api.github.com/users/qwcode/followers","following_url":"https://api.github.com/users/qwcode/following{/other_user}","gists_url":"https://api.github.com/users/qwcode/gists{/gist_id}","starred_url":"https://api.github.com/users/qwcode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qwcode/subscriptions","organizations_url":"https://api.github.com/users/qwcode/orgs","repos_url":"https://api.github.com/users/qwcode/repos","events_url":"https://api.github.com/users/qwcode/events{/privacy}","received_events_url":"https://api.github.com/users/qwcode/received_events","type":"User","site_admin":false},"created_at":"2015-10-19T18:33:10Z","updated_at":"2015-10-19T18:33:10Z","body":"> I think we actually already bake the sdist hash into the cache key.... \r\n> if the hash is part of the URL like it is on PyPI.\r\n\r\ntrue, we do, but the point here would be do it always (e.g. for find-links too), *and* to use the hash the user specified using `--hash`, not what happens to be in the PyPI url."}}