Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to README, Travis, test coverage #27

Merged
merged 5 commits into from Feb 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Expand Up @@ -7,7 +7,6 @@ python:

install:
- pip install -r test-requirements.txt
- pip install codecov
- pip install -e .

script:
Expand Down
85 changes: 45 additions & 40 deletions README.md
@@ -1,14 +1,54 @@
# conda-mirror
[![Build Status](https://travis-ci.org/maxpoint/conda-mirror.svg?branch=master)](https://travis-ci.org/maxpoint/conda-mirror)
[![PyPI version](https://badge.fury.io/py/conda-mirror.svg)](https://badge.fury.io/py/conda-mirror)
[![codecov](https://codecov.io/gh/maxpoint/conda-mirror/branch/master/graph/badge.svg)](https://codecov.io/gh/maxpoint/conda-mirror)

Mirrors an upstream conda channel to a local directory.

## Install

`pip install conda-mirror`

## CLI

CLI interface for `conda-mirror.py`

```
$ conda-mirror -h
usage: conda-mirror [-h] [--upstream-channel UPSTREAM_CHANNEL]
[--target-directory TARGET_DIRECTORY]
[--temp-directory TEMP_DIRECTORY] [--platform PLATFORM]
[-v] [--config CONFIG] [--pdb] [--version]

optional arguments:
-h, --help show this help message and exit
--upstream-channel UPSTREAM_CHANNEL
The target channel to mirror. Can be a channel on
anaconda.org like "conda-forge" or a full qualified
channel like "https://repo.continuum.io/pkgs/free/"
--target-directory TARGET_DIRECTORY
The place where packages should be mirrored to
--temp-directory TEMP_DIRECTORY
Temporary download location for the packages. Defaults
to a randomly selected temporary directory. Note that
you might need to specify a different location if your
default temp directory has less available space than
your mirroring target
--platform PLATFORM The OS platform(s) to mirror. one of: {'linux-64',
'linux-32','osx-64', 'win-32', 'win-64'}
-v, --verbose logging defaults to error/exception only. Takes up to
three '-v' flags. '-v': warning. '-vv': info. '-vvv':
debug.
--config CONFIG Path to the yaml config file
--pdb Enable PDB debugging on exception
--version Print version and quit
```

## Example Usage

WARNING: Invoking this command will pull ~10GB and take at least an hour
```bash
$ conda-mirror --upstream-channel conda-forge --target-directory local_mirror --platform linux-64
```

`conda-mirror --upstream-channel conda-forge --target-directory local_mirror --platform linux-64`

## More Details

Expand All @@ -33,7 +73,7 @@ upstream repodata.
whitelist conditions.

blacklist and whitelist both take lists of dictionaries. The keys in the
dictionary need to be values in the repodata.json metadata. The values are
dictionary need to be values in the `repodata.json` metadata. The values are
(unix) globs to match on. Go here for the full repodata of the upstream
"defaults" channel:
http://conda.anaconda.org/anaconda/linux-64/repodata.json
Expand All @@ -60,7 +100,7 @@ Here are the contents of one of the entries in repodata['packages']
'version': '1.4.10'}}
```

See implementation details in the conda_mirror:match function for more
See implementation details in the `conda_mirror:match` function for more
information.

#### Common usage patterns
Expand Down Expand Up @@ -91,41 +131,6 @@ whitelist:
- build: "*py3*"
```


## CLI
```
$ conda-mirror -h
usage: conda-mirror [-h] [--upstream-channel UPSTREAM_CHANNEL]
[--target-directory TARGET_DIRECTORY]
[--temp-directory TEMP_DIRECTORY] [--platform PLATFORM]
[-v] [--config CONFIG] [--pdb] [--version]

CLI interface for conda-mirror.py

optional arguments:
-h, --help show this help message and exit
--upstream-channel UPSTREAM_CHANNEL
The target channel to mirror. Can be a channel on
anaconda.org like "conda-forge" or a full qualified
channel like "https://repo.continuum.io/pkgs/free/"
--target-directory TARGET_DIRECTORY
The place where packages should be mirrored to
--temp-directory TEMP_DIRECTORY
Temporary download location for the packages. Defaults
to a randomly selected temporary directory. Note that
you might need to specify a different location if your
default temp directory has less available space than
your mirroring target
--platform PLATFORM The OS platform(s) to mirror. one of: {'linux-64',
'linux-32','osx-64', 'win-32', 'win-64'}
-v, --verbose logging defaults to error/exception only. Takes up to
three '-v' flags. '-v': warning. '-vv': info. '-vvv':
debug.
--config CONFIG Path to the yaml config file
--pdb Enable PDB debugging on exception
--version Print version and quit
```

## Testing

### Install test requirements
Expand Down
28 changes: 21 additions & 7 deletions conda_mirror/conda_mirror.py
Expand Up @@ -427,6 +427,25 @@ def _validate_packages(package_repodata, package_directory):
size=package_metadata.get('size'))


def _remove_local_blacklisted(blacklist, local_dir):
"""Removes any local conda packages that are blacklisted.

Parameters
----------
blacklist : list
Packages that should not be in `local_dir`
local_dir : str
Local directory to check for blacklisted conda packages
"""
# get list of current packages in folder
local_packages = _list_conda_packages(local_dir)
# if any are not in the final mirror list, remove them
for package_name in local_packages:
if package_name in blacklist:
_remove_package(os.path.join(local_dir, package_name),
reason="Package is blacklisted")


def main(upstream_channel, target_directory, temp_directory, platform,
blacklist=None, whitelist=None):
"""
Expand Down Expand Up @@ -540,13 +559,8 @@ def main(upstream_channel, target_directory, temp_directory, platform,
logger.debug(pformat(sorted(possible_packages_to_mirror)))

# 4. remove blacklisted packages
# get list of current packages in folder
local_packages = _list_conda_packages(local_directory)
# if any are not in the final mirror list, remove them
for package_name in local_packages:
if package_name in true_blacklist:
_remove_package(os.path.join(local_directory, package_name),
reason="Package is blacklisted")
_remove_local_blacklisted(true_blacklist, local_directory)

# 5. figure out final list of packages to mirror
# do the set difference of what is local and what is in the final
# mirror list
Expand Down
4 changes: 2 additions & 2 deletions test-requirements.txt
@@ -1,3 +1,3 @@
codecov
pytest
coverage
pytest-ordering
pytest-ordering
23 changes: 22 additions & 1 deletion test/test_conda_mirror.py
Expand Up @@ -11,6 +11,7 @@

anaconda_channel = 'https://repo.continuum.io/pkgs/free'


@pytest.fixture(scope='module')
def repodata():
repodata = {}
Expand All @@ -29,6 +30,7 @@ def test_match(repodata):
matched = conda_mirror._match(repodata_packages, {'name': "*"})
assert len(matched) == len(repodata_packages)


@pytest.mark.parametrize(
'channel,platform',
itertools.product([anaconda_channel, 'conda-forge'], ['linux-64']))
Expand Down Expand Up @@ -85,7 +87,6 @@ def test_cli(tmpdir, channel, platform, repodata):
assert len(rd['packages']) == len(disk_packages)



def test_handling_bad_package(tmpdir, repodata):
# ensure that bad conda packages are actually removed by run_conda_index
local_repo_root = tmpdir.mkdir('repo').strpath
Expand All @@ -111,3 +112,23 @@ def test_handling_bad_package(tmpdir, repodata):
assert bad_pkg_name in os.listdir(bad_pkg_root)
conda_mirror._validate_packages(anaconda_repodata, bad_pkg_root)
assert bad_pkg_name not in os.listdir(bad_pkg_root)


def test_local_blacklisted_package(tmpdir):
local_repo_root = tmpdir.mkdir('repo').strpath
pkg_root = os.path.join(local_repo_root, 'linux-64')
os.makedirs(pkg_root)
blacklisted_pkg_name = 'remove-1-0.tar.bz2'
non_blacklisted_pkg_name = 'keep-1-0.tar.bz2'
with bz2.BZ2File(os.path.join(pkg_root, blacklisted_pkg_name), 'wb') as f:
f.write("This is a blacklisted package".encode())
with bz2.BZ2File(os.path.join(pkg_root, non_blacklisted_pkg_name), 'wb') as f:
f.write("This is not a blacklisted package".encode())
blacklist = [blacklisted_pkg_name]

# Test removal of local blacklisted packages
conda_mirror.logger.info("Testing %s", blacklisted_pkg_name)
assert blacklisted_pkg_name in os.listdir(pkg_root)
conda_mirror._remove_local_blacklisted(blacklist, pkg_root)
assert blacklisted_pkg_name not in os.listdir(pkg_root)
assert non_blacklisted_pkg_name in os.listdir(pkg_root)