Skip to content

Commit

Permalink
deprecate delete-file-version
Browse files Browse the repository at this point in the history
  • Loading branch information
adal-chiriliuc-reef committed Apr 29, 2024
1 parent aaefec9 commit 5dbde55
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 22 deletions.
1 change: 1 addition & 0 deletions b2/_internal/b2v3/rm.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ class Rm(B2URIBucketNFolderNameArgMixin, BaseRm):
- **listFiles**
- **deleteFiles**
- **bypassGovernance** (if --bypass-governance is used)
"""
13 changes: 11 additions & 2 deletions b2/_internal/console_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -1694,7 +1694,7 @@ def _run(self, args):
return 0


class DeleteFileVersion(FileIdAndOptionalFileNameMixin, Command):
class DeleteFileVersionBase(FileIdAndOptionalFileNameMixin, Command):
"""
Permanently and irrevocably deletes one version of a file.
Expand Down Expand Up @@ -2535,7 +2535,8 @@ class BaseRm(ThreadsMixin, AbstractLsCommand, metaclass=ABCMeta):
example if a file matching a pattern is uploaded during a run of ``rm`` command, it MIGHT
be deleted (as "latest") instead of the one present when the ``rm`` run has started.
In order to safely delete a single file version, please use ``delete-file-version``.
If a file is in governance retention mode, and the retention period has not expired,
adding --bypass-governance is required.
To list (but not remove) files to be deleted, use ``--dry-run``. You can also
list files via ``ls`` command - the listing behaviour is exactly the same.
Expand Down Expand Up @@ -2617,6 +2618,7 @@ def _run_removal(self, executor: Executor):
self.runner.api.delete_file_version,
file_version.id_,
file_version.file_name,
self.args.bypass_governance,
)
with self.mapping_lock:
self.futures_mapping[future] = file_version
Expand Down Expand Up @@ -2649,6 +2651,7 @@ def _removal_done(self, future: Future) -> None:

@classmethod
def _setup_parser(cls, parser):
add_normalized_argument(parser, '--bypass-governance', action='store_true', default=False)
add_normalized_argument(parser, '--dry-run', action='store_true')
add_normalized_argument(parser,
'--queue-size',
Expand Down Expand Up @@ -2738,6 +2741,7 @@ class Rm(B2IDOrB2URIMixin, BaseRm):
- **listFiles**
- **deleteFiles**
- **bypassGovernance** (if --bypass-governance is used)
"""


Expand Down Expand Up @@ -5112,6 +5116,11 @@ class GetDownloadUrlWithAuth(CmdReplacedByMixin, GetDownloadUrlWithAuthBase):
replaced_by_cmd = (File, FileUrl)


class DeleteFileVersion(CmdReplacedByMixin, DeleteFileVersionBase):
__doc__ = DeleteFileVersionBase.__doc__
replaced_by_cmd = Rm


class ConsoleTool:
"""
Implements the commands available in the B2 command-line tool
Expand Down
1 change: 1 addition & 0 deletions changelog.d/+command-delete-file-version.deprecated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecated `delete-file-version`, use `rm` instead. Added `--bypass-governance` option to `rm`.
36 changes: 19 additions & 17 deletions test/integration/test_b2_command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ def test_basic(b2_tool, bucket_name, sample_file, tmp_path, b2_uri_args):
}
should_equal(expected_info, file_info['fileInfo'])

b2_tool.should_succeed(['delete-file-version', 'c', first_c_version['fileId']])
b2_tool.should_succeed(['rm', f"b2id://{first_c_version['fileId']}"])
b2_tool.should_succeed(
['ls', *b2_uri_args(bucket_name)], f'^a{os.linesep}b/{os.linesep}c{os.linesep}d{os.linesep}'
)
Expand Down Expand Up @@ -2385,18 +2385,18 @@ def deleting_locked_files(
locked_file = upload_locked_file(b2_tool, lock_enabled_bucket_name, sample_file)
b2_tool.should_fail(
[ # master key
'delete-file-version',
locked_file['fileName'],
locked_file['fileId'],
'rm',
f"b2id://{locked_file['fileId']}",
],
"ERROR: Access Denied for application key "
)
b2_tool.should_succeed([ # master key
'delete-file-version',
locked_file['fileName'],
locked_file['fileId'],
'--bypass-governance'
])
b2_tool.should_succeed(
[ # master key
'rm',
'--bypass-governance'
f"b2id://{locked_file['fileId']}",
]
)

locked_file = upload_locked_file(b2_tool, lock_enabled_bucket_name, sample_file)

Expand All @@ -2406,12 +2406,14 @@ def deleting_locked_files(
lock_disabled_key
],
)
b2_tool.should_fail([ # lock disabled key
'delete-file-version',
locked_file['fileName'],
locked_file['fileId'],
'--bypass-governance',
], "ERROR: unauthorized for application key with capabilities '")
b2_tool.should_fail(
[ # lock disabled key
'rm',
'--bypass-governance',
f"b2id://{locked_file['fileId']}",
],
"ERROR: unauthorized for application key with capabilities '"
)


def test_profile_switch(b2_tool):
Expand Down Expand Up @@ -2864,7 +2866,7 @@ def test_replication_monitoring(b2_tool, bucket_name, sample_file, schedule_buck
)

# there is just one file, so clean after itself for faster execution
b2_tool.should_succeed(['delete-file-version', uploaded_a['fileName'], uploaded_a['fileId']])
b2_tool.should_succeed(['rm', f"b2id://{uploaded_a['fileId']}"])

# run stats command
replication_status_deprecated_pattern = re.compile(
Expand Down
47 changes: 44 additions & 3 deletions test/unit/test_console_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,37 @@ def test_bucket_info_from_json(self):
expected_json_in_stdout=expected_json,
)

@pytest.mark.apiver(from_ver=4)
def test_rm_fileid_v4(self):

self._authorize_account()
self._run_command(['bucket', 'create', 'my-bucket', 'allPublic'], 'bucket_0\n', '', 0)

with TempDir() as temp_dir:
local_file1 = self._make_local_file(temp_dir, 'file1.txt')
# For this test, use a mod time without millis. My mac truncates
# millis and just leaves seconds.
mod_time = 1500111222
os.utime(local_file1, (mod_time, mod_time))
self.assertEqual(1500111222, os.path.getmtime(local_file1))

# Upload a file
self._run_command(
[
'file', 'upload', '--no-progress', 'my-bucket', local_file1, 'file1.txt',
'--cache-control=private, max-age=3600'
],
remove_version=True,
)

# Hide file
self._run_command(['file', 'hide', 'my-bucket', 'file1.txt'],)

# Delete one file version
self._run_command(['rm', 'b2id://9998'])
# Delete one file version
self._run_command(['rm', 'b2id://9999'])

def test_files(self):

self._authorize_account()
Expand Down Expand Up @@ -1135,14 +1166,20 @@ def test_files(self):
expected_json = {"action": "delete", "fileId": "9998", "fileName": "file1.txt"}

self._run_command(
['delete-file-version', 'file1.txt', '9998'], expected_json_in_stdout=expected_json
['delete-file-version', 'file1.txt', '9998'],
expected_stderr=
'WARNING: `delete-file-version` command is deprecated. Use `rm` instead.\n',
expected_json_in_stdout=expected_json
)

# Delete one file version, not passing the name in
expected_json = {"action": "delete", "fileId": "9999", "fileName": "file1.txt"}

self._run_command(
['delete-file-version', '9999'], expected_json_in_stdout=expected_json
['delete-file-version', '9999'],
expected_stderr=
'WARNING: `delete-file-version` command is deprecated. Use `rm` instead.\n',
expected_json_in_stdout=expected_json
)

def test_files_encrypted(self):
Expand Down Expand Up @@ -1337,14 +1374,18 @@ def test_files_encrypted(self):

self._run_command(
['delete-file-version', 'file1.txt', '9998'],
expected_json_in_stdout=expected_json,
expected_stderr=
'WARNING: `delete-file-version` command is deprecated. Use `rm` instead.\n',
expected_json_in_stdout=expected_json
)

# Delete one file version, not passing the name in
expected_json = {"action": "delete", "fileId": "9999", "fileName": "file1.txt"}

self._run_command(
['delete-file-version', '9999'],
expected_stderr=
'WARNING: `delete-file-version` command is deprecated. Use `rm` instead.\n',
expected_json_in_stdout=expected_json,
)

Expand Down

0 comments on commit 5dbde55

Please sign in to comment.