- Notifications
You must be signed in to change notification settings - Fork 112
Utility/example for deleting empty project versions older than <d> days #174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e556a48 e070360 3b81934 3b9ac4b 06528e3 960cfcc f206dff eff69fb 8d33d16 File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| VERSION = (1, 0, 2) | ||
| VERSION = (1, 0, 3) | ||
| | ||
| __version__ = '.'.join(map(str, VERSION)) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| from blackduck import Client | ||
| from blackduck.Utils import to_datetime | ||
| | ||
| from datetime import datetime, timedelta | ||
| import argparse | ||
| import logging | ||
| import requests | ||
| | ||
| logging.basicConfig( | ||
| level=logging.INFO, | ||
| format="[%(asctime)s] {%(module)s:%(lineno)d} %(levelname)s - %(message)s" | ||
| ) | ||
| logger = logging.getLogger(__name__) | ||
| | ||
| parser = argparse.ArgumentParser("delete_empty_project_versions") | ||
| parser.add_argument("--base-url", required=True, help="blackduck hub server url e.g. https://your.app.blackduck.com") | ||
| parser.add_argument("--token-file", dest='token_file', required=True, help="path to file containing blackduck hub token") | ||
| parser.add_argument("--no-verify", dest='verify', action='store_false', help="disable TLS certificate verification") | ||
| parser.add_argument("--days", dest='days', default=30, type=int, help="projects/versions older than <days>") | ||
| parser.add_argument("--delete", dest='delete', action='store_true', help="without this flag script will log/print only") | ||
| args = parser.parse_args() | ||
| | ||
| with open(args.token_file, 'r') as tf: | ||
| access_token = tf.readline().strip() | ||
| | ||
| bd = Client( | ||
| base_url=args.base_url, | ||
| token=access_token, | ||
| verify=args.verify | ||
| ) | ||
| | ||
| max_age = datetime.now() - timedelta(days=args.days) | ||
| | ||
| for project in bd.get_resource('projects'): | ||
| # skip projects younger than max age | ||
| if to_datetime(project.get('createdAt')) > max_age: continue | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm getting an exception here: TypeError: can't compare offset-naive and offset-aware datetimes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A possible solution could be to add something like this to utils: Normally I'd avoid creating wrappers for stl functions but in this case I don't think it is obvious how to get a timezone aware datetime given There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In sage_version_activity_to_csv.py I used: from dateutil.parser import isoparse There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll take a look at that tonight | ||
| | ||
| for version in bd.get_resource('versions', project): | ||
| # skip versions with > 0 code locations | ||
| if int(bd.get_metadata('codelocations', version).get('totalCount')): continue | ||
| # skip versions younger than max age | ||
| if to_datetime(version.get('createdAt')) > max_age: continue | ||
| # delete all others | ||
| logger.info(f"delete {project.get('name')} version {version.get('versionName')}") | ||
| if args.delete: bd.session.delete(version.get('href')).raise_for_status() | ||
| | ||
| # skip projects with any remaining versions | ||
| if int(bd.get_metadata('versions', project).get('totalCount')): continue | ||
| # delete all others | ||
| logger.info(f"deleting {project.get('name')}") | ||
| if args.delete: bd.session.delete(project.get('href')).raise_for_status() | ||
| | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I am all for deleting code, are these methods that you just recently added e.g. this year? Generally, deleting or changing method signatures are considered as breaking backwards-compatibility in an API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of these were in HubInstance - the only use they had was in demo_client, though I'll update that to use the two new methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay I'm fine with deleting them.