13
13
14
14
from .arg_parser import parse
15
15
from .config import Config
16
+ from .definitions import COLLECTIONS_PATH as CP
17
+ from .definitions import AnsibleCfg
16
18
from .output import Output
17
19
from .utils import TermFeatures
18
20
@@ -30,6 +32,10 @@ def __init__(self) -> None:
30
32
self .config : Config
31
33
self .output : Output
32
34
self .term_features : TermFeatures
35
+ self .acfg_cwd = AnsibleCfg (path = Path ("./ansible.cfg" ))
36
+ self .acfg_home = AnsibleCfg (path = Path ("~/.ansible.cfg" ).expanduser ().resolve ())
37
+ self .acfg_system = AnsibleCfg (path = Path ("/etc/ansible/ansible.cfg" ))
38
+ self .acfg_trusted : Path | None
33
39
34
40
def parse_args (self ) -> None :
35
41
"""Parse the command line arguments."""
@@ -92,8 +98,92 @@ def args_sanity(self) -> None:
92
98
err = "Editable can not be used with a requirements file."
93
99
self .output .critical (err )
94
100
95
- def ensure_isolated (self ) -> None :
96
- """Ensure the environment is isolated."""
101
+ def isolation_check (self ) -> bool :
102
+ """Check the environment for isolation.
103
+
104
+ Returns:
105
+ True if ade can continue, false otherwise.
106
+ """
107
+ if not hasattr (self .args , "isolation_mode" ):
108
+ return True
109
+ if self .args .isolation_mode == "restrictive" :
110
+ return self .isolation_restrictive ()
111
+ if self .args .isolation_mode == "cfg" :
112
+ return self .isolation_cfg ()
113
+ if self .args .isolation_mode == "none" :
114
+ return self .isolation_none ()
115
+ self .acfg_trusted = None
116
+ return False
117
+
118
+ def isolation_cfg (self ) -> bool :
119
+ """Ensure the environment is isolated using cfg isolation.
120
+
121
+ Returns:
122
+ True if ade can continue, false otherwise.
123
+ """
124
+ if os .environ .get ("ANSIBLE_CONFIG" ):
125
+ err = "ANSIBLE_CONFIG is set"
126
+ self .output .error (err )
127
+ hint = "Run `unset ANSIBLE_CONFIG` to unset it using cfg isolation mode."
128
+ self .output .hint (hint )
129
+ self .acfg_trusted = None
130
+ return False
131
+
132
+ if self .acfg_cwd .exists :
133
+ if self .acfg_cwd .collections_path_is_dot :
134
+ msg = f"{ self .acfg_cwd .path } has '{ CP } ' which isolates this workspace."
135
+ self .output .info (msg )
136
+ else :
137
+ self .acfg_cwd .set_or_update_collections_path ()
138
+ msg = f"{ self .acfg_cwd .path } updated with '{ CP } ' to isolate this workspace."
139
+ self .output .warning (msg )
140
+ self .acfg_trusted = self .acfg_cwd .path
141
+ return True
142
+
143
+ if self .acfg_home .exists :
144
+ if self .acfg_home .collections_path_is_dot :
145
+ msg = f"{ self .acfg_home .path } has '{ CP } ' which isolates this and all workspaces."
146
+ self .output .info (msg )
147
+ else :
148
+ self .acfg_home .set_or_update_collections_path ()
149
+ msg = (
150
+ f"{ self .acfg_home .path } updated with '{ CP } ' to isolate this and all workspaces."
151
+ )
152
+ self .output .warning (msg )
153
+ self .acfg_trusted = self .acfg_home .path
154
+ return True
155
+
156
+ if self .acfg_system .exists and self .acfg_system .collections_path_is_dot :
157
+ msg = f"{ self .acfg_system .path } has '{ CP } ' which isolates this and all workspaces."
158
+ self .output .info (msg )
159
+ self .acfg_trusted = self .acfg_system .path
160
+ return True
161
+
162
+ self .acfg_cwd .author_new ()
163
+ msg = f"{ self .acfg_cwd .path } created with '{ CP } ' to isolate this workspace."
164
+ self .output .info (msg )
165
+ self .acfg_trusted = self .acfg_cwd .path
166
+ return True
167
+
168
+ def isolation_none (self ) -> bool :
169
+ """No isolation.
170
+
171
+ Returns:
172
+ True if ade can continue, false otherwise.
173
+ """
174
+ self .output .warning (
175
+ "An unisolated development environment can cause issues with conflicting dependency"
176
+ " versions and the use of incompatible collections." ,
177
+ )
178
+ self .acfg_trusted = None
179
+ return True
180
+
181
+ def isolation_restrictive (self ) -> bool :
182
+ """Ensure the environment is isolated.
183
+
184
+ Returns:
185
+ True if ade can continue, false otherwise.
186
+ """
97
187
env_vars = os .environ
98
188
errored = False
99
189
if "ANSIBLE_COLLECTIONS_PATHS" in env_vars :
@@ -127,11 +217,11 @@ def ensure_isolated(self) -> None:
127
217
hint = "Run `sudo rm -rf /usr/share/ansible/collections` to remove them."
128
218
self .output .hint (hint )
129
219
errored = True
130
-
131
220
if errored :
132
221
err = "The development environment is not isolated, please resolve the above errors."
133
-
134
- self .output .critical (err )
222
+ self .output .warning (err )
223
+ return False
224
+ return True
135
225
136
226
def run (self ) -> None :
137
227
"""Run the application."""
@@ -145,9 +235,9 @@ def run(self) -> None:
145
235
subcommand_cls = getattr (subcommands , self .config .args .subcommand .capitalize ())
146
236
subcommand = subcommand_cls (config = self .config , output = self .output )
147
237
subcommand .run ()
148
- self ._exit ()
238
+ self .exit ()
149
239
150
- def _exit (self ) -> None :
240
+ def exit (self ) -> None :
151
241
"""Exit the application setting the return code."""
152
242
if self .output .call_count ["error" ]:
153
243
sys .exit (1 )
@@ -171,6 +261,7 @@ def main(*, dry: bool = False) -> None:
171
261
cli .output .warning (str (warn .message ))
172
262
warnings .resetwarnings ()
173
263
cli .args_sanity ()
174
- cli .ensure_isolated ()
264
+ if not cli .isolation_check ():
265
+ cli .exit ()
175
266
if not dry :
176
267
cli .run ()
0 commit comments