Thanks to visit codestin.com
Credit goes to github.com

Skip to content

CLI tool to list and download specific versions of the cqlsh from 2025.1 and 2025.2 releases.

Notifications You must be signed in to change notification settings

jeamon/cqlshutil

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cqlshutil

This tool helps to download specific versions of the cqlsh utility from 2025.1 and 2025.2 releases. It provides command to list of available versions and another command to download a given version. All current downloadable files can be found at https://downloads.scylladb.com/downloads/scylla/relocatable/ To see whether each version is available on Scylla Cloud fetch this information from the https://api.cloud.scylladb.com/deployment/scylla-versions

Usage

  • Commands:

    • list: shows all available versions of cqlsh for download and availability in ScyllaDB Cloud.

      • Optional -lt flag accepted to show only versions that are less than the specified value.
      • Optional -gt flag accepted to show only versions that are greater than the user-specified value.
      • Flags -lt and -gt could be combined to select the specified exclusive range.
      • Flags -lt and -gt accept version values like X or X.Y or X.Y.Z or X.Y.Z~rcN. X, Y, Z, N are numbers.
    • download: fetches the archive of the specified version and outputs the downloaded file to STDOUT.

  • Syntax:

    cqlshutil list [-lt <archive-version>] [-gt <archive-version>]

    cqlshutil download <archive-version>

    cqlshutil help

  • Examples:

	$ ./cqlshutil list
	$ ./cqlshutil list -lt 2025.1.5
	$ ./cqlshutil list -gt 2025.1.0~rc0
	$ ./cqlshutil list -gt 2025.1 -lt 2025.2.0~rc1
	$ ./cqlshutil download 2025.2.1 > cqlsh.tar.gz
	
	$ ./cqlshutil help

Design & Structure

This project adopts a simple structure to make easy to understand and navigate into the codebase. There are 4 folders where 3 are go packages and 1 is just a folder containing tests data / assets.

The core package is represented by the app folder. It contains all key services routines used by list and download commands. It is exposed with a Service interface which makes easy to extend the functionalities and unit testing more flexible.

The other package is represented by testhelpers folder. It provides essentials routines to build unit tests and perform assertions during those tests. It contains some mocks for http client and http servers involved into during operation of service calls.

The last package is represented by cmd folder. This is the entry point of the program. The main function is hosted there. Commands and arguments parsing are inside this package.

Finally the testdata folder contains 3 files which mimic real dataset fetched from official page and api endpoint. Those data are used during unit and functional tests inside the app package. This to ensure robust tests. sycalla-versions.json file contains some scylla versions into json format. archives-versions.2025.1.xml and archives-versions.2025.2.xml files contains data that mimic each download page contents since this program deals with 2 minor releases 2025.1 and 2025.2. There are mocked server into the testhelpers package that serve those files depending on the request URL.

One key important details about the design is using download command will firstly trigger the fetching of all available archives versions in order to build the archive direct download url, after which tthe real archive file downloading will take place. This to avoid dumping temporary data into file on disk which could lead to some issues depending on the environment and use case.

Improvements Ideas

  • adding -eq flag on list command could help quick check availability of specific version
  • adding a timeout could help auto terminate so avoid waiting in case the http call is hanging
  • adding a shutdown mechanism with signal handling could help controlling termination in case the tool is running into an automated manner

Demo

% go build -o dist/cqlshutil cmd/cqlshutil/*
% chmod +x dist/cqlshutil
% dist/cqlshutil list
VERSION         CLOUD
2025.1.0        DISABLED
2025.1.0~rc0    N/A
2025.1.0~rc1    N/A
2025.1.0~rc2    N/A
2025.1.0~rc3    N/A
2025.1.0~rc4    N/A
2025.1.1        DISABLED
2025.1.2        DISABLED
2025.1.3        DISABLED
2025.1.4        DISABLED
2025.1.5        DISABLED
2025.2.0        DISABLED
2025.2.0~rc0    N/A
2025.2.0~rc1    N/A
2025.2.1        ENABLED
% dist/cqlshutil list -lt 2025.1.1
VERSION         CLOUD
2025.1.0        DISABLED
2025.1.0~rc0    N/A
2025.1.0~rc1    N/A
2025.1.0~rc2    N/A
2025.1.0~rc3    N/A
2025.1.0~rc4    N/A
% dist/cqlshutil list -gt 2025.2.0
VERSION         CLOUD
2025.2.0~rc0    N/A
2025.2.0~rc1    N/A
2025.2.1        ENABLED
% dist/cqlshutil list -gt 2025.1.0 -lt 2025.1.1
VERSION         CLOUD
2025.1.0~rc0    N/A
2025.1.0~rc1    N/A
2025.1.0~rc2    N/A
2025.1.0~rc3    N/A
2025.1.0~rc4    N/A
% dist/cqlshutil download 2025.1.0 > cqlsh.tar.gz
Download completed

Tests

% go test ./... -count=1 -v
=== RUN   TestDownloadArchive
=== RUN   TestDownloadArchive/success_2025.1.0_version_for_arm64
=== RUN   TestDownloadArchive/success_2025.1.0_version_for_x86_64
=== RUN   TestDownloadArchive/success_2025.2.0~rc0_version_for_arm64
=== RUN   TestDownloadArchive/inexistant_2025.3.0_version_for_arm64
=== RUN   TestDownloadArchive/fail_on_404_from_server
=== RUN   TestDownloadArchive/fail_on_500_from_server
--- PASS: TestDownloadArchive (0.01s)
    --- PASS: TestDownloadArchive/success_2025.1.0_version_for_arm64 (0.01s)
    --- PASS: TestDownloadArchive/success_2025.1.0_version_for_x86_64 (0.00s)
    --- PASS: TestDownloadArchive/success_2025.2.0~rc0_version_for_arm64 (0.00s)
    --- PASS: TestDownloadArchive/inexistant_2025.3.0_version_for_arm64 (0.00s)
    --- PASS: TestDownloadArchive/fail_on_404_from_server (0.00s)
    --- PASS: TestDownloadArchive/fail_on_500_from_server (0.00s)
=== RUN   TestGetDownloadPageContents
=== RUN   TestGetDownloadPageContents/success_with_200_status
=== RUN   TestGetDownloadPageContents/failure_with_404_status
=== RUN   TestGetDownloadPageContents/failure_with_500_status
--- PASS: TestGetDownloadPageContents (0.00s)
    --- PASS: TestGetDownloadPageContents/success_with_200_status (0.00s)
    --- PASS: TestGetDownloadPageContents/failure_with_404_status (0.00s)
    --- PASS: TestGetDownloadPageContents/failure_with_500_status (0.00s)
=== RUN   TestGetScyllaVersions
=== RUN   TestGetScyllaVersions/success_with_200_status
=== RUN   TestGetScyllaVersions/failure_with_404_status
=== RUN   TestGetScyllaVersions/failure_with_500_status
--- PASS: TestGetScyllaVersions (0.00s)
    --- PASS: TestGetScyllaVersions/success_with_200_status (0.00s)
    --- PASS: TestGetScyllaVersions/failure_with_404_status (0.00s)
    --- PASS: TestGetScyllaVersions/failure_with_500_status (0.00s)
=== RUN   TestParseDownloadedXMLContents
=== RUN   TestParseDownloadedXMLContents/invalid_xml_content
=== RUN   TestParseDownloadedXMLContents/valid_xml_content
--- PASS: TestParseDownloadedXMLContents (0.00s)
    --- PASS: TestParseDownloadedXMLContents/invalid_xml_content (0.00s)
    --- PASS: TestParseDownloadedXMLContents/valid_xml_content (0.00s)
=== RUN   TestParseDownloadedJSONScyllaVersions
=== RUN   TestParseDownloadedJSONScyllaVersions/invalid_json_content
=== RUN   TestParseDownloadedJSONScyllaVersions/valid_json_content
--- PASS: TestParseDownloadedJSONScyllaVersions (0.00s)
    --- PASS: TestParseDownloadedJSONScyllaVersions/invalid_json_content (0.00s)
    --- PASS: TestParseDownloadedJSONScyllaVersions/valid_json_content (0.00s)
=== RUN   TestListAllArchiveVersions
=== RUN   TestListAllArchiveVersions/success
=== RUN   TestListAllArchiveVersions/fail_on_404_from_server
=== RUN   TestListAllArchiveVersions/fail_on_500_from_server
--- PASS: TestListAllArchiveVersions (0.00s)
    --- PASS: TestListAllArchiveVersions/success (0.00s)
    --- PASS: TestListAllArchiveVersions/fail_on_404_from_server (0.00s)
    --- PASS: TestListAllArchiveVersions/fail_on_500_from_server (0.00s)
=== RUN   TestListArchiveVersionsGreaterThan
=== RUN   TestListArchiveVersionsGreaterThan/success
=== RUN   TestListArchiveVersionsGreaterThan/fail_on_404_from_server
=== RUN   TestListArchiveVersionsGreaterThan/fail_on_500_from_server
--- PASS: TestListArchiveVersionsGreaterThan (0.00s)
    --- PASS: TestListArchiveVersionsGreaterThan/success (0.00s)
    --- PASS: TestListArchiveVersionsGreaterThan/fail_on_404_from_server (0.00s)
    --- PASS: TestListArchiveVersionsGreaterThan/fail_on_500_from_server (0.00s)
=== RUN   TestListArchiveVersionsLesserThan
=== RUN   TestListArchiveVersionsLesserThan/success
=== RUN   TestListArchiveVersionsLesserThan/fail_on_404_from_server
=== RUN   TestListArchiveVersionsLesserThan/fail_on_500_from_server
--- PASS: TestListArchiveVersionsLesserThan (0.00s)
    --- PASS: TestListArchiveVersionsLesserThan/success (0.00s)
    --- PASS: TestListArchiveVersionsLesserThan/fail_on_404_from_server (0.00s)
    --- PASS: TestListArchiveVersionsLesserThan/fail_on_500_from_server (0.00s)
=== RUN   TestListArchiveVersionsFromRange
=== RUN   TestListArchiveVersionsFromRange/success
=== RUN   TestListArchiveVersionsFromRange/fail_on_404_from_server
=== RUN   TestListArchiveVersionsFromRange/fail_on_500_from_server
--- PASS: TestListArchiveVersionsFromRange (0.00s)
    --- PASS: TestListArchiveVersionsFromRange/success (0.00s)
    --- PASS: TestListArchiveVersionsFromRange/fail_on_404_from_server (0.00s)
    --- PASS: TestListArchiveVersionsFromRange/fail_on_500_from_server (0.00s)
PASS
ok    github.com/jeamon/cqlshutil/app   2.256s
=== RUN   TestExecute_SuccessAppServiceCalls
=== RUN   TestExecute_SuccessAppServiceCalls/missing_command
=== RUN   TestExecute_SuccessAppServiceCalls/invalid_command
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_without_arguments
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_less_than_flag_X
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y.Z
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y.Z~rcN
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_less_than_flag
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y.Z
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y.Z~rcN
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_greater_than_flag
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_range_flags_X
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y.Z
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y.Z~rcN
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_range_flags
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_equal_range_flags
=== RUN   TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_misorder_range_flags
=== RUN   TestExecute_SuccessAppServiceCalls/valid_download_command_with_valid_version_X
Download completed
=== RUN   TestExecute_SuccessAppServiceCalls/valid_download_command_with_valid_version_X.Y
Download completed
=== RUN   TestExecute_SuccessAppServiceCalls/valid_download_command_with_valid_version_X.Y.Z
Download completed
=== RUN   TestExecute_SuccessAppServiceCalls/valid_download_command_with_valid_version_X.Y.Z~rcN
Download completed
=== RUN   TestExecute_SuccessAppServiceCalls/valid_download_command_with_version
=== RUN   TestExecute_SuccessAppServiceCalls/valid_download_command_without_version
=== RUN   TestExecute_SuccessAppServiceCalls/valid_download_command_invalid_version
--- PASS: TestExecute_SuccessAppServiceCalls (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/missing_command (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/invalid_command (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_without_arguments (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_less_than_flag_X (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y.Z (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y.Z~rcN (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_less_than_flag (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y.Z (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y.Z~rcN (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_greater_than_flag (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_range_flags_X (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y.Z (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y.Z~rcN (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_range_flags (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_equal_range_flags (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_list_command_with_invalid_misorder_range_flags (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_download_command_with_valid_version_X (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_download_command_with_valid_version_X.Y (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_download_command_with_valid_version_X.Y.Z (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_download_command_with_valid_version_X.Y.Z~rcN (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_download_command_with_version (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_download_command_without_version (0.00s)
    --- PASS: TestExecute_SuccessAppServiceCalls/valid_download_command_invalid_version (0.00s)
=== RUN   TestExecute_FailedAppServiceCalls
=== RUN   TestExecute_FailedAppServiceCalls/missing_command
=== RUN   TestExecute_FailedAppServiceCalls/invalid_command
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_without_arguments
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_less_than_flag_X
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y.Z
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y.Z~rcN
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_less_than_flag
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y.Z
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y.Z~rcN
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_greater_than_flag
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_range_flags_X
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y.Z
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y.Z~rcN
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_range_flags
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_equal_range_flags
=== RUN   TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_misorder_range_flags
=== RUN   TestExecute_FailedAppServiceCalls/valid_download_command_with_valid_version_X
=== RUN   TestExecute_FailedAppServiceCalls/valid_download_command_with_valid_version_X.Y
=== RUN   TestExecute_FailedAppServiceCalls/valid_download_command_with_valid_version_X.Y.Z
=== RUN   TestExecute_FailedAppServiceCalls/valid_download_command_with_valid_version_X.Y.Z~rcN
=== RUN   TestExecute_FailedAppServiceCalls/valid_download_command_with_empty_version
=== RUN   TestExecute_FailedAppServiceCalls/valid_download_command_without_version
=== RUN   TestExecute_FailedAppServiceCalls/valid_download_command_invalid_version
--- PASS: TestExecute_FailedAppServiceCalls (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/missing_command (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/invalid_command (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_without_arguments (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_less_than_flag_X (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y.Z (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_less_than_flag_X.Y.Z~rcN (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_less_than_flag (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y.Z (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_greater_than_flag_X.Y.Z~rcN (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_greater_than_flag (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_range_flags_X (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y.Z (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_valid_range_flags_X.Y.Z~rcN (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_range_flags (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_equal_range_flags (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_list_command_with_invalid_misorder_range_flags (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_download_command_with_valid_version_X (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_download_command_with_valid_version_X.Y (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_download_command_with_valid_version_X.Y.Z (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_download_command_with_valid_version_X.Y.Z~rcN (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_download_command_with_empty_version (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_download_command_without_version (0.00s)
    --- PASS: TestExecute_FailedAppServiceCalls/valid_download_command_invalid_version (0.00s)
PASS
ok    github.com/jeamon/cqlshutil/cmd/cqlshutil 1.527s
?     github.com/jeamon/cqlshutil/testhelpers   [no test files]

License

Please check & read the license details

Contact

Feel free to reach out to me before any action. Feel free to connect on Twitter or linkedin

About

CLI tool to list and download specific versions of the cqlsh from 2025.1 and 2025.2 releases.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages