diff --git a/artifact-ctl/artifact_ctl.py b/artifact-ctl/artifact_ctl.py new file mode 100644 index 0000000..5d8de92 --- /dev/null +++ b/artifact-ctl/artifact_ctl.py @@ -0,0 +1,107 @@ +import json as JSON +import os +import re +import urllib.parse + +import click +import requests + + +def extract_name(filepath: str) -> str: + filename = os.path.basename(filepath) # Get the filename from the path + match = re.match(r'^(.*)-\d+\.\d+\.\d+\.json$', filename) + if match: + return match.group(1) + return "" + + +def extract_version(filepath: str) -> str: + filename = os.path.basename(filepath) # Get the filename from the path + match = re.search(r'-(\d+\.\d+\.\d+)\.json$', filename) + if match: + return match.group(1) + return "" + + +@click.group() +def cli(): + """A CLI tool to manage artifacts.""" + pass + + +@click.command() +@click.option('--jar', help='Path to JAR file.') +@click.option('--json', help='Path to JSON file.') +@click.option('--host', default='http://localhost:11015', help='Instance url') +@click.option('--namespace', default='default', help='Set your namespace where do you want to deploy the artifact.') +@click.option('--auth_token', help='Auth Token', default='') +def load(jar, json, namespace, host, auth_token): + namespaces_url = '/v3/namespaces/' + name = extract_name(json) + version = extract_version(json) + + with open(json, 'r') as f: + json_file = JSON.load(f) + + with open(jar, 'rb') as f: + jar_file = f.read() + + auth_headers = get_auth_headers(auth_token) + + deploy_jar_headers = { + 'Artifact-Extends': '/'.join(json_file['parents']), + 'Artifact-Version': version, + 'Content-Type': 'application/java-archive', + **auth_headers + } + deploy_jar = requests.post( + f'{host}{namespaces_url}{namespace}/artifacts/{name}', + headers=deploy_jar_headers, + data=jar_file + ) + + deploy_json = requests.put( + f'{host}{namespaces_url}{namespace}/artifacts/{name}/versions/{version}/properties', + headers=auth_headers, + data=JSON.dumps(json_file['properties']) + ) + + if deploy_jar.status_code == 200 and deploy_json.status_code == 200: + print('Successfully deployed artifact') + else: + print('Failed to add artifact.') + + +@click.command() +@click.option('--name', help='Artifact name') +@click.option('--version', help='Artivact version.') +@click.option('--namespace', default='default', help='Set your namespace where do you want to deploy the artifact.') +@click.option('--host', default='http://localhost:11015', help='Instance url') +@click.option('--auth_token', help='Auth Token') +def delete(name, version, ns, host, auth_token): + namespaces_url = '/v3/namespaces/' + auth_headers = get_auth_headers(auth_token) + + delete_artifact_res = requests.delete( + f'{host}{namespaces_url}{ns}/artifacts/{name}/versions/{version}', + headers=auth_headers + ) + + if delete_artifact_res.status_code == 200: + print('Successfully deleted artifact') + else: + print('Failed to delete artifact.') + + +def get_auth_headers(auth_token: str = None): + if auth_token and auth_token != '': + decoded_token = urllib.parse.unquote(auth_token) + return {'Authorization': f'Bearer {decoded_token}'} + return {} + + +cli.add_command(load) +cli.add_command(delete) + +if __name__ == '__main__': + cli() diff --git a/artifact-ctl/build.sh b/artifact-ctl/build.sh new file mode 100644 index 0000000..48ab10e --- /dev/null +++ b/artifact-ctl/build.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# Exit on any error +set -e + +# Constants +ENV_NAME="artifact_env" +SCRIPT_NAME="artifact_ctl.py" +EXECUTABLE_NAME="artifact-ctl" +OUTPUT_DIR="dist" + +# Detect OS +OS=$(uname | tr '[:upper:]' '[:lower:]') +IS_WINDOWS=0 + +if [[ "$OS" == "mingw"* || "$OS" == "cygwin"* ]]; then + IS_WINDOWS=1 +fi + +# Notify the user +echo "Detected OS: $OS" +if [[ "$IS_WINDOWS" -eq 1 ]]; then + echo "Building for Windows..." +else + echo "Building for $OS..." +fi + +# Step 1: Create and activate a virtual environment +echo "Setting up virtual environment..." +python3 -m venv $ENV_NAME +source $ENV_NAME/bin/activate + +# Step 2: Install required dependencies +echo "Installing dependencies..." +pip install --upgrade pip +pip install pyinstaller click requests + +# Step 3: Build the executable +echo "Building the standalone executable..." +if [[ "$IS_WINDOWS" -eq 1 ]]; then + pyinstaller --onefile --name $EXECUTABLE_NAME $SCRIPT_NAME +else + pyinstaller --onefile --name $EXECUTABLE_NAME $SCRIPT_NAME +fi + +# Step 4: Handle cross-platform extensions +if [[ "$IS_WINDOWS" -eq 1 ]]; then + EXT=".exe" +else + EXT="" +fi + +# Ensure output filename consistency +mv "$OUTPUT_DIR/$EXECUTABLE_NAME$EXT" "$OUTPUT_DIR/$EXECUTABLE_NAME$EXT" + +# Step 5: Add metadata or compress the output +echo "Preparing the final executable..." +if [[ "$IS_WINDOWS" -eq 1 ]]; then + # Compress the executable for Windows distribution + zip "$OUTPUT_DIR/$EXECUTABLE_NAME.zip" "$OUTPUT_DIR/$EXECUTABLE_NAME$EXT" + echo "Compressed executable available at $OUTPUT_DIR/$EXECUTABLE_NAME.zip" +else + # Optionally compress for macOS/Linux + tar -czvf "$OUTPUT_DIR/$EXECUTABLE_NAME.tar.gz" -C "$OUTPUT_DIR" "$EXECUTABLE_NAME$EXT" + echo "Compressed executable available at $OUTPUT_DIR/$EXECUTABLE_NAME.tar.gz" +fi + +# Step 6: Cleanup virtual environment +echo "Cleaning up..." +deactivate +rm -rf $ENV_NAME + +# Notify user of successful build +echo "Build complete. Executable is in the $OUTPUT_DIR/ folder." diff --git a/artifact-ctl/setup.py b/artifact-ctl/setup.py new file mode 100644 index 0000000..4755c48 --- /dev/null +++ b/artifact-ctl/setup.py @@ -0,0 +1,15 @@ +from setuptools import setup + +setup( + name="artifact-ctl", + version='0.1', + py_modules=['artifact_ctl.py'], + install_requires=[ + 'Click', + 'Requests' + ], + entry_points=''' + [console_scripts] + artifact-ctl=artifact_ctl:main + ''', +) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7e14ceb --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +click +urllib +requests +pyinstaller