dvc-utils 0.0.4__py3-none-any.whl → 0.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
dvc_utils/main.py CHANGED
@@ -1,14 +1,11 @@
1
1
  from functools import cache
2
2
  from os import environ as env, getcwd
3
-
4
- from typing import Optional, Tuple
5
-
6
- import shlex
7
3
  from os.path import join, relpath
4
+ import shlex
5
+ from subprocess import Popen, PIPE
6
+ from typing import Optional, Tuple
8
7
 
9
8
  from click import option, argument, group
10
- from subprocess import Popen
11
-
12
9
  import click
13
10
  import yaml
14
11
  from utz import process, singleton, err
@@ -52,7 +49,7 @@ def dvc_cache_dir(log: bool = False) -> str:
52
49
  def dvc_md5(git_ref: str, dvc_path: str, log: bool = False) -> str:
53
50
  dir_path = get_dir_path()
54
51
  dir_path = '' if dir_path == '.' else f'{dir_path}/'
55
- dvc_spec = process.output('git', 'show', f'{git_ref}:{dir_path}{dvc_path}', log=log)
52
+ dvc_spec = process.output('git', 'show', f'{git_ref}:{dir_path}{dvc_path}', log=err if log else None)
56
53
  dvc_obj = yaml.safe_load(dvc_spec)
57
54
  out = singleton(dvc_obj['outs'], dedupe=False)
58
55
  md5 = out['md5']
@@ -73,15 +70,28 @@ def dvc_cache_path(ref: str, dvc_path: Optional[str] = None, log: bool = False)
73
70
 
74
71
 
75
72
  def diff_cmds(
76
- cmd1: str,
77
- cmd2: str,
73
+ cmds1: list[str],
74
+ cmds2: list[str],
78
75
  verbose: bool = False,
79
76
  color: bool = False,
80
77
  unified: int | None = None,
81
78
  ignore_whitespace: bool = False,
82
79
  **kwargs,
83
80
  ):
84
- """Run two commands and diff their output.
81
+ """Run two sequences of piped commands and diff their output.
82
+
83
+ Args:
84
+ cmds1: First sequence of commands to pipe together
85
+ cmds2: Second sequence of commands to pipe together
86
+ verbose: Whether to print commands being executed
87
+ color: Whether to show colored diff output
88
+ unified: Number of unified context lines, or None
89
+ ignore_whitespace: Whether to ignore whitespace changes
90
+ **kwargs: Additional arguments passed to subprocess.Popen
91
+
92
+ Each command sequence will be piped together before being compared.
93
+ For example, if cmds1 = ['cat foo.txt', 'sort'], the function will
94
+ execute 'cat foo.txt | sort' before comparing with cmds2's output.
85
95
 
86
96
  Adapted from https://stackoverflow.com/a/28840955"""
87
97
  with named_pipes(n=2) as pipes:
@@ -96,11 +106,45 @@ def diff_cmds(
96
106
  ]
97
107
  diff = Popen(diff_cmd)
98
108
  processes = []
99
- for path, cmd in ((pipe1, cmd1), (pipe2, cmd2)):
100
- with open(path, 'wb', 0) as pipe:
101
- if verbose:
102
- err(f"Running: {cmd}")
103
- processes.append(Popen(cmd, stdout=pipe, close_fds=True, **kwargs))
109
+
110
+ for pipe, cmds in ((pipe1, cmds1), (pipe2, cmds2)):
111
+ if verbose:
112
+ err(f"Running pipeline: {' | '.join(cmds)}")
113
+
114
+ # Create the pipeline of processes
115
+ prev_process = None
116
+ for i, cmd in enumerate(cmds):
117
+ is_last = i + 1 == len(cmds)
118
+
119
+ # For the first process, take input from the original source
120
+ stdin = None if prev_process is None else prev_process.stdout
121
+
122
+ # For the last process, output to the named pipe
123
+ if is_last:
124
+ with open(pipe, 'wb', 0) as pipe_fd:
125
+ proc = Popen(
126
+ cmd,
127
+ stdin=stdin,
128
+ stdout=pipe_fd,
129
+ close_fds=True,
130
+ **kwargs
131
+ )
132
+ # For intermediate processes, output to a pipe
133
+ else:
134
+ proc = Popen(
135
+ cmd,
136
+ stdin=stdin,
137
+ stdout=PIPE,
138
+ close_fds=True,
139
+ **kwargs
140
+ )
141
+
142
+ if prev_process is not None:
143
+ prev_process.stdout.close()
144
+
145
+ processes.append(proc)
146
+ prev_process = proc
147
+
104
148
  for p in [diff] + processes:
105
149
  p.wait()
106
150
 
@@ -112,7 +156,8 @@ def diff_cmds(
112
156
  @option('-U', '--unified', type=int, help='Number of lines of context to show (passes through to `diff`)')
113
157
  @option('-v', '--verbose', is_flag=True, help="Log intermediate commands to stderr")
114
158
  @option('-w', '--ignore-whitespace', is_flag=True, help="Ignore whitespace differences (pass `-w` to `diff`)")
115
- @argument('args', metavar='[cmd...] <path>', nargs=-1)
159
+ @option('-x', '--exec-cmd', 'exec_cmds', multiple=True, help='Command(s) to execute before diffing; alternate syntax to passing commands as positional arguments')
160
+ @argument('args', metavar='[exec_cmd...] <path>', nargs=-1)
116
161
  def dvc_utils_diff(
117
162
  color: bool,
118
163
  refspec: str | None,
@@ -120,6 +165,7 @@ def dvc_utils_diff(
120
165
  unified: int | None,
121
166
  verbose: bool,
122
167
  ignore_whitespace: bool,
168
+ exec_cmds: Tuple[str, ...],
123
169
  args: Tuple[str, ...],
124
170
  ):
125
171
  """Diff a file at two commits (or one commit vs. current worktree), optionally passing both through `cmd` first
@@ -134,14 +180,8 @@ def dvc_utils_diff(
134
180
  raise click.UsageError('Must specify [cmd...] <path>')
135
181
 
136
182
  shell = not no_shell
137
- if len(args) == 2:
138
- cmd, path = args
139
- cmd = shlex.split(cmd)
140
- elif len(args) == 1:
141
- cmd = None
142
- path, = args
143
- else:
144
- raise click.UsageError('Maximum 2 positional args: [cmd] <path>')
183
+ *cmds, path = args
184
+ cmds = list(exec_cmds) + cmds
145
185
 
146
186
  path, dvc_path = dvc_paths(path)
147
187
 
@@ -158,17 +198,27 @@ def dvc_utils_diff(
158
198
  before_path = dvc_cache_path(before, dvc_path, log=log)
159
199
  after_path = path if after is None else dvc_cache_path(after, dvc_path, log=log)
160
200
 
161
- if cmd:
162
- def args(path: str):
163
- arr = cmd + [path]
164
- return shlex.join(arr) if shell else arr
201
+ if cmds:
202
+ cmd, *sub_cmds = cmds
203
+ if not shell:
204
+ sub_cmds = [ shlex.split(c) for c in sub_cmds ]
205
+ before_cmds = [
206
+ shlex.split(f'{cmd} {before_path}'),
207
+ *sub_cmds,
208
+ ]
209
+ after_cmds = [
210
+ shlex.split(f'{cmd} {after_path}'),
211
+ *sub_cmds,
212
+ ]
213
+ shell_kwargs = {}
214
+ else:
215
+ before_cmds = [ f'{cmd} {before_path}', *sub_cmds ]
216
+ after_cmds = [ f'{cmd} {after_path}', *sub_cmds ]
217
+ shell_kwargs = dict(shell=shell)
165
218
 
166
- shell_kwargs = dict(shell=shell) if shell else {}
167
- before_cmd = args(before_path)
168
- after_cmd = args(after_path)
169
219
  diff_cmds(
170
- before_cmd,
171
- after_cmd,
220
+ before_cmds,
221
+ after_cmds,
172
222
  verbose=verbose,
173
223
  color=color,
174
224
  unified=unified,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dvc-utils
3
- Version: 0.0.4
3
+ Version: 0.0.5
4
4
  Summary: CLI for diffing DVC files at two commits (or one commit vs. current worktree), optionally passing both through another command first
5
5
  Home-page: https://github.com/runsascoded/dvc-utils
6
6
  Author: Ryan Williams
@@ -0,0 +1,9 @@
1
+ dvc_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ dvc_utils/main.py,sha256=UhCm28Zu_xwsmfzOKgmAYJrCrfumryid_10F_-Rg-2M,7850
3
+ dvc_utils/named_pipes.py,sha256=VQ2t9BYCazFq_-MABj4t2HS7GHDvSqXXx8fOLz5DsTc,492
4
+ dvc_utils-0.0.5.dist-info/LICENSE,sha256=ZS8AReay7xmQzBAHwxIuTouGXz3SKgUa2_Sz8Ip0EzQ,1070
5
+ dvc_utils-0.0.5.dist-info/METADATA,sha256=y46AoDbejlmv318zUD4aKiY9SprlRh9hdCBcoGZ4H4M,6924
6
+ dvc_utils-0.0.5.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
7
+ dvc_utils-0.0.5.dist-info/entry_points.txt,sha256=W9OuZ6CX8QF9ojbqLtfXFo8Q2hnJ-zlcGY4_7nO8paM,49
8
+ dvc_utils-0.0.5.dist-info/top_level.txt,sha256=jT0-PJa2t_eFRE9rn-52AjdnZ8nQeEHllf2kJmaGh80,10
9
+ dvc_utils-0.0.5.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- dvc_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- dvc_utils/main.py,sha256=oszbPch2tASbhKQunE9DiiOZxUHkfd_s2iHWqDM5vZg,5687
3
- dvc_utils/named_pipes.py,sha256=VQ2t9BYCazFq_-MABj4t2HS7GHDvSqXXx8fOLz5DsTc,492
4
- dvc_utils-0.0.4.dist-info/LICENSE,sha256=ZS8AReay7xmQzBAHwxIuTouGXz3SKgUa2_Sz8Ip0EzQ,1070
5
- dvc_utils-0.0.4.dist-info/METADATA,sha256=Pr8ov2afc0wlJkzWWqTNoey-LvrKRSIrG8JM_x4q03A,6924
6
- dvc_utils-0.0.4.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
7
- dvc_utils-0.0.4.dist-info/entry_points.txt,sha256=W9OuZ6CX8QF9ojbqLtfXFo8Q2hnJ-zlcGY4_7nO8paM,49
8
- dvc_utils-0.0.4.dist-info/top_level.txt,sha256=jT0-PJa2t_eFRE9rn-52AjdnZ8nQeEHllf2kJmaGh80,10
9
- dvc_utils-0.0.4.dist-info/RECORD,,