restore_backup_dir()   B
last analyzed

Complexity

Conditions 7

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
dl 0
loc 20
rs 7.3333
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
3
"""
4
conftest
5
--------
6
7
Contains pytest fixtures which are globally available throughout the suite.
8
"""
9
10
import logging
11
import os
12
import shutil
13
14
import pytest
15
16
from cookiecutter import utils
17
18
19
USER_CONFIG = u"""
20
cookiecutters_dir: "{cookiecutters_dir}"
21
replay_dir: "{replay_dir}"
22
"""
23
24
25
def backup_dir(original_dir, backup_dir):
26
    # If the default original_dir is pre-existing, move it to a temp location
27
    if not os.path.isdir(original_dir):
28
        return False
29
30
    # Remove existing backups before backing up. If they exist, they're stale.
31
    if os.path.isdir(backup_dir):
32
        utils.rmtree(backup_dir)
33
34
    shutil.copytree(original_dir, backup_dir)
35
    return True
36
37
38
def restore_backup_dir(original_dir, backup_dir, original_dir_found):
39
    # Carefully delete the created original_dir only in certain
40
    # conditions.
41
    original_dir_is_dir = os.path.isdir(original_dir)
42
    if original_dir_found:
43
        # Delete the created original_dir as long as a backup
44
        # exists
45
        if original_dir_is_dir and os.path.isdir(backup_dir):
46
            utils.rmtree(original_dir)
47
    else:
48
        # Delete the created original_dir.
49
        # There's no backup because it never existed
50
        if original_dir_is_dir:
51
            utils.rmtree(original_dir)
52
53
    # Restore the user's default original_dir contents
54
    if os.path.isdir(backup_dir):
55
        shutil.copytree(backup_dir, original_dir)
56
    if os.path.isdir(original_dir):
57
        utils.rmtree(backup_dir)
58
59
60
@pytest.fixture(scope='function')
61
def clean_system(request):
62
    """
63
    Fixture that simulates a clean system with no config/cloned cookiecutters.
64
65
    It runs code which can be regarded as setup code as known from a unittest
66
    TestCase. Additionally it defines a local function referring to values
67
    which have been stored to local variables in the setup such as the location
68
    of the cookiecutters on disk. This function is registered as a teardown
69
    hook with `request.addfinalizer` at the very end of the fixture. Pytest
70
    runs the named hook as soon as the fixture is out of scope, when the test
71
    finished to put it another way.
72
73
    During setup:
74
75
    * Back up the `~/.cookiecutterrc` config file to `~/.cookiecutterrc.backup`
76
    * Back up the `~/.cookiecutters/` dir to `~/.cookiecutters.backup/`
77
    * Back up the `~/.cookiecutter_replay/` dir to
78
      `~/.cookiecutter_replay.backup/`
79
    * Starts off a test case with no pre-existing `~/.cookiecutterrc` or
80
      `~/.cookiecutters/` or `~/.cookiecutter_replay/`
81
82
    During teardown:
83
84
    * Delete `~/.cookiecutters/` only if a backup is present at
85
      `~/.cookiecutters.backup/`
86
    * Delete `~/.cookiecutter_replay/` only if a backup is present at
87
      `~/.cookiecutter_replay.backup/`
88
    * Restore the `~/.cookiecutterrc` config file from
89
      `~/.cookiecutterrc.backup`
90
    * Restore the `~/.cookiecutters/` dir from `~/.cookiecutters.backup/`
91
    * Restore the `~/.cookiecutter_replay/` dir from
92
      `~/.cookiecutter_replay.backup/`
93
94
    """
95
96
    # If ~/.cookiecutterrc is pre-existing, move it to a temp location
97
    user_config_path = os.path.expanduser('~/.cookiecutterrc')
98
    user_config_path_backup = os.path.expanduser(
99
        '~/.cookiecutterrc.backup'
100
    )
101
    if os.path.exists(user_config_path):
102
        user_config_found = True
103
        shutil.copy(user_config_path, user_config_path_backup)
104
        os.remove(user_config_path)
105
    else:
106
        user_config_found = False
107
108
    # If the default cookiecutters_dir is pre-existing, move it to a
109
    # temp location
110
    cookiecutters_dir = os.path.expanduser('~/.cookiecutters')
111
    cookiecutters_dir_backup = os.path.expanduser('~/.cookiecutters.backup')
112
    cookiecutters_dir_found = backup_dir(
113
        cookiecutters_dir, cookiecutters_dir_backup
114
    )
115
116
    # If the default cookiecutter_replay_dir is pre-existing, move it to a
117
    # temp location
118
    cookiecutter_replay_dir = os.path.expanduser('~/.cookiecutter_replay')
119
    cookiecutter_replay_dir_backup = os.path.expanduser(
120
        '~/.cookiecutter_replay.backup'
121
    )
122
    cookiecutter_replay_dir_found = backup_dir(
123
        cookiecutter_replay_dir, cookiecutter_replay_dir_backup
124
    )
125
126
    def restore_backup():
127
        # If it existed, restore ~/.cookiecutterrc
128
        # We never write to ~/.cookiecutterrc, so this logic is simpler.
129
        if user_config_found and os.path.exists(user_config_path_backup):
130
            shutil.copy(user_config_path_backup, user_config_path)
131
            os.remove(user_config_path_backup)
132
133
        # Carefully delete the created ~/.cookiecutters dir only in certain
134
        # conditions.
135
        restore_backup_dir(
136
            cookiecutters_dir,
137
            cookiecutters_dir_backup,
138
            cookiecutters_dir_found
139
        )
140
141
        # Carefully delete the created ~/.cookiecutter_replay dir only in
142
        # certain conditions.
143
        restore_backup_dir(
144
            cookiecutter_replay_dir,
145
            cookiecutter_replay_dir_backup,
146
            cookiecutter_replay_dir_found
147
        )
148
149
    request.addfinalizer(restore_backup)
150
151
152
@pytest.fixture(scope='session')
153
def user_dir(tmpdir_factory):
154
    """Fixture that simulates the user's home directory"""
155
    return tmpdir_factory.mktemp('user_dir')
156
157
158
@pytest.fixture(scope='session')
159
def user_config_data(user_dir):
160
    """Fixture that creates 2 Cookiecutter user config dirs in the user's home
161
    directory:
162
    * `cookiecutters_dir`
163
    * `cookiecutter_replay`
164
165
    :returns: Dict with name of both user config dirs
166
    """
167
    cookiecutters_dir = user_dir.mkdir('cookiecutters')
168
    replay_dir = user_dir.mkdir('cookiecutter_replay')
169
170
    return {
171
        'cookiecutters_dir': str(cookiecutters_dir),
172
        'replay_dir': str(replay_dir),
173
    }
174
175
176
@pytest.fixture(scope='session')
177
def user_config_file(user_dir, user_config_data):
178
    """Fixture that creates a config file called `config` in the user's home
179
    directory, with YAML from `user_config_data`.
180
181
    :param user_dir: Simulated user's home directory
182
    :param user_config_data: Dict of config values
183
    :returns: String of path to config file
184
    """
185
    config_file = user_dir.join('config')
186
187
    config_text = USER_CONFIG.format(**user_config_data)
188
    config_file.write(config_text)
189
    return str(config_file)
190
191
192
@pytest.fixture(autouse=True)
193
def disable_poyo_logging():
194
    logging.getLogger('poyo').setLevel(logging.WARNING)
195