Skip to content

Commit

Permalink
Refactor code that adds UNLINK step
Browse files Browse the repository at this point in the history
This provides a pivot point that allows us to add ENSURE_WRITE at all
points when an unlink is happening.
  • Loading branch information
tswicegood committed Apr 21, 2015
1 parent 5ff9c66 commit 331640c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
18 changes: 12 additions & 6 deletions conda/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ def nothing_to_do(actions):
return True


def add_unlink(actions, dist):
if inst.UNLINK not in actions:
actions[inst.UNLINK] = []
actions[inst.UNLINK].append(dist)


def plan_from_actions(actions):
if 'op_order' in actions and actions['op_order']:
op_order = actions['op_order']
Expand Down Expand Up @@ -296,7 +302,7 @@ def force_linked_actions(dists, index, prefix):
actions[inst.RM_EXTRACTED].append(dist)
actions[inst.EXTRACT].append(dist)
if isfile(join(prefix, 'conda-meta', dist + '.json')):
actions[inst.UNLINK].append(dist)
add_unlink(actions, dist)
actions[inst.LINK].append(dist)
return actions

Expand Down Expand Up @@ -426,7 +432,7 @@ def install_actions(prefix, index, specs, force=False, only_names=None,
for dist in sorted(linked):
name = install.name_dist(dist)
if name in must_have and dist != must_have[name]:
actions[inst.UNLINK].append(dist)
add_unlink(actions, dist)

return actions

Expand Down Expand Up @@ -454,7 +460,7 @@ def remove_actions(prefix, specs, index=None, pinned=True):
"Cannot remove %s because it is pinned. Use --no-pin "
"to override." % dist)

actions[inst.UNLINK].append(dist)
add_unlink(actions, dist)
if r and fn in index and r.track_features(fn):
features_actions = remove_features_actions(
prefix, index, r.track_features(fn))
Expand Down Expand Up @@ -482,9 +488,9 @@ def remove_features_actions(prefix, index, features):
if fn not in index:
continue
if r.track_features(fn).intersection(features):
actions[inst.UNLINK].append(dist)
add_unlink(actions, dist)
if r.features(fn).intersection(features):
actions[inst.UNLINK].append(dist)
add_unlink(actions, dist)
subst = r.find_substitute(_linked, features, fn)
if subst:
to_link.append(subst[:-8])
Expand All @@ -508,7 +514,7 @@ def revert_actions(prefix, revision=-1):

actions = ensure_linked_actions(state, prefix)
for dist in curr - state:
actions[inst.UNLINK].append(dist)
add_unlink(actions, dist)

return actions

Expand Down
36 changes: 36 additions & 0 deletions tests/test_plan.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import sys
import json
import random
import unittest
from os.path import dirname, join
from collections import defaultdict

import pytest

from conda.config import default_python, pkgs_dirs
import conda.config
from conda.install import LINK_HARD
Expand All @@ -12,13 +15,17 @@
from conda.plan import display_actions
from conda.resolve import Resolve

# FIXME This should be a relative import
from tests.helpers import captured
from conda.exceptions import CondaException

from .helpers import mock

with open(join(dirname(__file__), 'index.json')) as fi:
index = json.load(fi)
r = Resolve(index)


def solve(specs):
return [fn[:-8] for fn in r.solve(specs)]

Expand All @@ -34,6 +41,35 @@ def test_split_linkarg(self):
self.assertEqual(inst.split_linkarg(arg), res)


@pytest.mark.parametrize("args", [
(),
("one", ),
("one", "two", "three", ),
])
def test_add_unlink_takes_two_arguments(args):
with pytest.raises(TypeError):
plan.add_unlink(*args)


class add_unlink_TestCase(unittest.TestCase):
def test_simply_adds_unlink_on_non_windows(self):
actions = {}
dist = {"foo": "bar%s" % random.randint(100, 200)}
with mock.patch.object(plan, "sys") as sys:
sys.platform = "not win32"
plan.add_unlink(actions, dist)
self.assertIn(inst.UNLINK, actions)
self.assertEqual(actions[inst.UNLINK], [dist, ])

def test_adds_to_existing_actions(self):
actions = {inst.UNLINK: [{"foo": "bar"}]}
dist = {"foo": "bar%s" % random.randint(100, 200)}
with mock.patch.object(plan, "sys") as sys:
sys.platform = "not win32"
plan.add_unlink(actions, dist)
self.assertEqual(2, len(actions[inst.UNLINK]))


class TestAddDeaultsToSpec(unittest.TestCase):
# tests for plan.add_defaults_to_specs(r, linked, specs)

Expand Down

0 comments on commit 331640c

Please sign in to comment.