'Generic Commit'
Some checks failed
Build-Test-Publish / build (push) Failing after 14s

This commit is contained in:
Your Name 2025-06-22 10:15:10 +12:00
parent ce10325a7f
commit 9c64c8cdce
9 changed files with 7863 additions and 34 deletions

133
getpkg/src/hash.cpp Normal file
View File

@ -0,0 +1,133 @@
#include "hash.hpp"
#define XXH_INLINE_ALL
#include "xxhash.hpp"
#include "output.hpp"
#include <fstream>
#include <filesystem>
#include <iostream>
namespace dropshell {
uint64_t hash_file(const std::string &path) {
// Create hash state
XXH64_state_t* const state = XXH64_createState();
if (state == nullptr) {
error << "Failed to create hash state" << std::endl;
return 0;
}
// Initialize state with seed 0
XXH64_hash_t const seed = 0; /* or any other value */
if (XXH64_reset(state, seed) == XXH_ERROR) return 0;
// Open file
std::ifstream file(path, std::ios::binary);
if (!file.is_open()) {
error << "Failed to open file: " << path << std::endl;
XXH64_freeState(state);
return 0;
}
// Read file in chunks and update hash
const size_t buffer_size = 4096;
char buffer[buffer_size];
while (file.read(buffer, buffer_size)) {
if (XXH64_update(state, buffer, file.gcount()) == XXH_ERROR) {
error << "Failed to update hash" << std::endl;
XXH64_freeState(state);
return 0;
}
}
// Handle any remaining bytes
if (file.gcount() > 0) {
if (XXH64_update(state, buffer, file.gcount()) == XXH_ERROR) {
error << "Failed to update hash" << std::endl;
XXH64_freeState(state);
return 0;
}
}
// Get final hash
XXH64_hash_t hash = XXH64_digest(state);
XXH64_freeState(state);
return hash;
}
uint64_t hash_directory_recursive(const std::string &path) {
// Create hash state
XXH64_state_t* const state = XXH64_createState();
if (state == nullptr) {
error << "Failed to create hash state" << std::endl;
return 0;
}
// Initialize state with seed 0
XXH64_hash_t const seed = 0; /* or any other value */
if (XXH64_reset(state, seed) == XXH_ERROR) {
error << "Failed to reset hash state" << std::endl;
XXH64_freeState(state);
return 0;
}
try {
// Iterate through all files in directory recursively
for (const auto& entry : std::filesystem::recursive_directory_iterator(path)) {
if (entry.is_regular_file()) {
// Get file hash
XXH64_hash_t file_hash = hash_file(entry.path().string());
XXH64_update(state, &file_hash, sizeof(file_hash));
}
}
} catch (const std::filesystem::filesystem_error& e) {
error << "Filesystem error: " << e.what() << std::endl;
XXH64_freeState(state);
return 0;
}
// Get final hash
XXH64_hash_t hash = XXH64_digest(state);
XXH64_freeState(state);
return hash;
}
uint64_t hash_path(const std::string &path) {
if (!std::filesystem::exists(path)) {
error << "Path does not exist: " << path << std::endl;
return 0;
}
if (std::filesystem::is_directory(path)) {
return hash_directory_recursive(path);
} else if (std::filesystem::is_regular_file(path)) {
return hash_file(path);
} else {
error << "Path is neither a file nor a directory: " << path << std::endl;
return 0;
}
}
void hash_demo(const std::string & path)
{
info << "Hashing path: " << path << std::endl;
auto start = std::chrono::high_resolution_clock::now();
XXH64_hash_t hash = hash_path(path);
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
info << "Hash: " << hash << " (took " << duration.count() << "ms)" << std::endl;
}
int hash_demo_raw(const std::string & path)
{
if (!std::filesystem::exists(path)) {
info << 0 <<std::endl; return 1;
}
XXH64_hash_t hash = hash_path(path);
info << hash << std::endl;
return 0;
}
} // namespace dropshell

22
getpkg/src/hash.hpp Normal file
View File

@ -0,0 +1,22 @@
#ifndef HASH_HPP
#define HASH_HPP
#include <string>
#include <cstdint>
namespace dropshell {
uint64_t hash_file(const std::string &path);
uint64_t hash_directory_recursive(const std::string &path);
uint64_t hash_path(const std::string &path);
void hash_demo(const std::string & path);
int hash_demo_raw(const std::string & path);
} // namespace dropshell
#endif

View File

@ -59,6 +59,7 @@
#include "DropshellScriptManager.hpp"
#include "GetbinClient.hpp"
#include "ArchiveManager.hpp"
#include "hash.hpp"
#include <iostream>
#include <string>
#include <vector>
@ -385,6 +386,23 @@ int create_tool(int argc, char* argv[]) {
return 0;
}
int hash_command(int argc, char* argv[]) {
if (argc < 3) {
std::cerr << "Usage: getpkg hash <file_or_directory>" << std::endl;
return 1;
}
std::string path = argv[2];
if (!std::filesystem::exists(path)) {
std::cerr << "Error: Path does not exist: " << path << std::endl;
return 1;
}
uint64_t hash = dropshell::hash_path(path);
std::cout << hash << std::endl;
return 0;
}
int uninstall_tool(int argc, char* argv[]) {
if (argc < 3) {
std::cerr << "Usage: getpkg uninstall <tool_name>" << std::endl;
@ -455,6 +473,9 @@ void show_help() {
std::cout << " create <tool_name> <directory> Create a new tool project" << std::endl;
std::cout << " Creates directory structure and setup script" << std::endl;
std::cout << std::endl;
std::cout << " hash <file_or_directory> Calculate hash of file or directory" << std::endl;
std::cout << " Outputs raw hash value to stdout" << std::endl;
std::cout << std::endl;
std::cout << " version Show getpkg version" << std::endl;
std::cout << std::endl;
std::cout << " help Show this help message" << std::endl;
@ -500,12 +521,15 @@ publish
update
version
create
hash
help
)";
} else if (command == "version") {
std::cout << dropshell::VERSION << std::endl;
} else if (command == "create") {
return create_tool(argc, argv);
} else if (command == "hash") {
return hash_command(argc, argv);
} else if (command == "help") {
show_help();
} else {

133
getpkg/src/output.cpp Normal file
View File

@ -0,0 +1,133 @@
#include "output.hpp"
#include <iostream>
#include <mutex>
namespace dropshell
{
// Mutex to synchronize output
std::mutex output_mutex;
// ANSI colour codes
constexpr const char *GREY = "\033[90m";
constexpr const char *RESET = "\033[0m";
constexpr const char *DEBUG_COLOUR = "\033[36m"; // Cyan
// constexpr const char *INFO_COLOUR = "\033[32m"; // Green
constexpr const char *INFO_COLOUR = "\033[37m"; // White
constexpr const char *WARNING_COLOUR = "\033[33m"; // Yellow
constexpr const char *ERROR_COLOUR = "\033[31m"; // Red
// Tag and colour for each stream
struct StreamInfo
{
const char *tag;
const char *colour;
};
const StreamInfo stream_infos[] = {
{"[DBG]", DEBUG_COLOUR},
{"[INF]", INFO_COLOUR},
{"[WRN]", WARNING_COLOUR},
{"[ERR]", ERROR_COLOUR}};
// Custom streambuf to prefix and colour each line
class PrefixStreambuf : public std::streambuf
{
public:
PrefixStreambuf(std::ostream &dest, const char *tag, const char *colour)
: dest_(dest), tag_(tag), colour_(colour), at_line_start_(true) {}
protected:
int overflow(int c) override
{
std::lock_guard<std::mutex> lock(output_mutex);
if (c == EOF)
return !EOF;
if (at_line_start_) // && c != '\n')
{
dest_ << GREY << tag_ << RESET << ' ' << colour_;
at_line_start_ = false;
}
dest_.put(static_cast<char>(c));
if (c == '\n')
{
dest_ << RESET;
at_line_start_ = true;
}
return c;
}
private:
std::ostream &dest_;
const char *tag_;
const char *colour_;
bool at_line_start_;
};
PrefixStreambuf debug_buf(std::clog, stream_infos[0].tag, stream_infos[0].colour);
PrefixStreambuf info_buf(std::clog, stream_infos[1].tag, stream_infos[1].colour);
PrefixStreambuf warning_buf(std::clog, stream_infos[2].tag, stream_infos[2].colour);
PrefixStreambuf error_buf(std::cerr, stream_infos[3].tag, stream_infos[3].colour);
std::ostream debug_stream(&debug_buf);
std::ostream info_stream(&info_buf);
std::ostream warning_stream(&warning_buf);
std::ostream error_stream(&error_buf);
std::ostream &debug = debug_stream;
std::ostream &info = info_stream;
std::ostream &warning = warning_stream;
std::ostream &error = error_stream;
std::ostream &rawout = std::cout;
std::ostream &rawerr = std::cerr;
std::ostream &colourstream(sColour colour)
{
switch (colour)
{
case sColour::DEBUG:
return debug_stream;
case sColour::INFO:
return info_stream;
case sColour::WARNING:
return warning_stream;
case sColour::ERROR:
return error_stream;
default:
return info_stream;
}
}
void SetColour(sColour colour, std::ostream &os)
{
switch (colour)
{
case sColour::RESET:
os << RESET;
break;
case sColour::DEBUG:
os << DEBUG_COLOUR;
break;
case sColour::INFO:
os << INFO_COLOUR;
break;
case sColour::WARNING:
os << WARNING_COLOUR;
break;
case sColour::ERROR:
os << ERROR_COLOUR;
break;
}
}
SwitchColour::SwitchColour(sColour colour, std::ostream &os) : os_(os), colour_(colour)
{
SetColour(colour_, os_);
}
SwitchColour::~SwitchColour()
{
SetColour(sColour::RESET, os_);
}
} // namespace dropshell

87
getpkg/src/output.hpp Normal file
View File

@ -0,0 +1,87 @@
#ifndef OUTPUT_HPP
#define OUTPUT_HPP
#include <iostream>
#include <string>
#include <vector>
#include <ostream>
namespace dropshell {
/*
output.hpp and output.cpp - simple output helpers.
Defines ostreams:
debug, info, warning, error.
These ostreams can be used with C++23 print and println, e.g.
std::println(debug, "funny variable: {}={}","my_var",my_var);
Also defines a few helper functions:
PrintDebug(const std::string& msg); // equivalent to std::println(debug, msg);
PrintInfo(const std::string& msg); // equivalent to std::println(info, msg);
PrintWarning(const std::string& msg); // equivalent to std::println(warning, msg);
PrintError(const std::string& msg); // equivalent to std::println(error, msg);
Output for these streams for each line is formatted as:
[DBG] <message>
[INF] <message>
[WRN] <message>
[ERR] <message>
The output is coloured, and the tag is printed in grey.
In addition, when not using any of the above, helper routines for coloring the output of cout and cerr are provided.
SetColour(std::ostream& os, sColour colour);
Where sColour is an enum:
enum class sColour {
RESET,
DEBUG,
INFO,
WARNING,
ERROR
};
*/
// Output streams for different log levels
extern std::ostream& debug;
extern std::ostream& info;
extern std::ostream& warning;
extern std::ostream& error;
extern std::ostream& rawout;
extern std::ostream& rawerr;
// Enum for colours
enum class sColour {
RESET,
DEBUG,
INFO,
WARNING,
ERROR
};
std::ostream& colourstream(sColour colour);
// Set colour for a stream
void SetColour(sColour colour, std::ostream& os = std::cerr);
class SwitchColour
{
public:
SwitchColour(sColour colour, std::ostream& os = std::cerr);
~SwitchColour();
private:
std::ostream& os_;
sColour colour_;
};
} // namespace dropshell
#endif // OUTPUT_HPP

7343
getpkg/src/xxhash.hpp Normal file

File diff suppressed because it is too large Load Diff

1
getpkg/temp_test.txt Normal file
View File

@ -0,0 +1 @@
test

View File

@ -120,8 +120,95 @@ else
print_test_result "Autocomplete command output" 1
fi
# Test 4: Create command
echo -e "\nTest 4: Create command"
# Test 4: Hash command
echo -e "\nTest 4: Hash command"
# Test 4a: Hash command with missing argument
echo "Test 4a: Hash command error handling"
HASH_ERROR_OUTPUT=$("$GETPKG" hash 2>&1) || true
if [[ "$HASH_ERROR_OUTPUT" =~ "Usage: getpkg hash" ]]; then
print_test_result "Hash command error handling (missing argument)" 0
else
print_test_result "Hash command error handling (missing argument)" 1
fi
# Test 4b: Hash command with nonexistent file
echo "Test 4b: Hash command with nonexistent file"
HASH_NONEXISTENT_OUTPUT=$("$GETPKG" hash nonexistent_file.txt 2>&1) || true
if [[ "$HASH_NONEXISTENT_OUTPUT" =~ "Error: Path does not exist" ]]; then
print_test_result "Hash command error handling (nonexistent file)" 0
else
print_test_result "Hash command error handling (nonexistent file)" 1
fi
# Test 4c: Hash command with test file
echo "Test 4c: Hash command with test file"
TEST_FILE="${TEST_DIR}/test_hash_file.txt"
echo "test content for hashing" > "$TEST_FILE"
HASH_FILE_OUTPUT=$("$GETPKG" hash "$TEST_FILE" 2>&1) || HASH_FILE_OUTPUT=""
if [[ "$HASH_FILE_OUTPUT" =~ ^[0-9]+$ ]]; then
print_test_result "Hash command with file (numeric output)" 0
# Test that the hash is consistent
HASH_FILE_OUTPUT2=$("$GETPKG" hash "$TEST_FILE" 2>&1) || HASH_FILE_OUTPUT2=""
if [ "$HASH_FILE_OUTPUT" = "$HASH_FILE_OUTPUT2" ]; then
print_test_result "Hash command consistency (same file, same hash)" 0
else
print_test_result "Hash command consistency (same file, same hash)" 1
fi
else
print_test_result "Hash command with file (numeric output)" 1
print_test_result "Hash command consistency (same file, same hash)" 1
fi
# Test 4d: Hash command with directory
echo "Test 4d: Hash command with directory"
TEST_HASH_DIR="${TEST_DIR}/test_hash_dir"
mkdir -p "$TEST_HASH_DIR"
echo "dir content 1" > "$TEST_HASH_DIR/file1.txt"
echo "dir content 2" > "$TEST_HASH_DIR/file2.txt"
HASH_DIR_OUTPUT=$("$GETPKG" hash "$TEST_HASH_DIR" 2>&1) || HASH_DIR_OUTPUT=""
if [[ "$HASH_DIR_OUTPUT" =~ ^[0-9]+$ ]]; then
print_test_result "Hash command with directory (numeric output)" 0
# Test that directory hash is different from file hash
if [ "$HASH_DIR_OUTPUT" != "$HASH_FILE_OUTPUT" ]; then
print_test_result "Hash command different for file vs directory" 0
else
print_test_result "Hash command different for file vs directory" 1
fi
else
print_test_result "Hash command with directory (numeric output)" 1
print_test_result "Hash command different for file vs directory" 1
fi
# Test 4e: Hash command compatibility with tr (sos script format)
echo "Test 4e: Hash command compatibility with tr command"
LOCALHASH=$("$GETPKG" hash "$TEST_FILE" | tr -d '[:space:]') || LOCALHASH=""
if [[ "$LOCALHASH" =~ ^[0-9]+$ ]] && [ ${#LOCALHASH} -gt 0 ]; then
print_test_result "Hash command compatible with tr -d '[:space:]'" 0
else
print_test_result "Hash command compatible with tr -d '[:space:]'" 1
fi
# Test 4f: Hash command appears in autocomplete
echo "Test 4f: Hash command in autocomplete"
if [[ "$AUTOCOMPLETE_OUTPUT" =~ hash ]]; then
print_test_result "Hash command appears in autocomplete" 0
else
print_test_result "Hash command appears in autocomplete" 1
fi
# Test 4g: Hash command appears in help
echo "Test 4g: Hash command in help"
if [[ "$HELP_OUTPUT" =~ hash.*file_or_directory ]] && [[ "$HELP_OUTPUT" =~ "Outputs raw hash value to stdout" ]]; then
print_test_result "Hash command appears in help" 0
else
print_test_result "Hash command appears in help" 1
fi
# Test 5: Create command
echo -e "\nTest 5: Create command"
CREATE_DIR="${TEST_DIR}/${TEST_TOOL_NAME}"
timeout 3 "$GETPKG" create "$TEST_TOOL_NAME" "$CREATE_DIR" >/dev/null 2>&1 || true
if [ -d "$CREATE_DIR" ] && [ -f "$CREATE_DIR/setup_script.sh" ]; then
@ -130,8 +217,8 @@ else
print_test_result "Create tool directory" 1
fi
# Test 5: Create test tool binary
echo -e "\nTest 5: Create test tool"
# Test 6: Create test tool binary
echo -e "\nTest 6: Create test tool"
cat > "$CREATE_DIR/${TEST_TOOL_NAME}" << 'EOF'
#!/bin/bash
case "$1" in
@ -156,15 +243,15 @@ else
print_test_result "Create test tool binary" 1
fi
# Test 5b: Test basic publish functionality
echo -e "\nTest 5b: Testing basic publish command"
# Test 6b: Test basic publish functionality
echo -e "\nTest 6b: Testing basic publish command"
# Test with a dummy token to see error message
DUMMY_OUTPUT=$(timeout 3 "$GETPKG" publish "dummy:x86_64" "$CREATE_DIR" 2>&1 <<< "") || true
echo "Dummy publish output: $DUMMY_OUTPUT"
# Test 6: Publish command (requires SOS_WRITE_TOKEN)
# Test 7: Publish command (requires SOS_WRITE_TOKEN)
if [ -n "${SOS_WRITE_TOKEN:-}" ]; then
echo -e "\nTest 6: Publish command with ARCH"
echo -e "\nTest 7: Publish command with ARCH"
echo "SOS_WRITE_TOKEN is set: ${#SOS_WRITE_TOKEN} characters"
echo "Publishing ${TEST_TOOL_NAME}:${TEST_ARCH} from $CREATE_DIR"
echo "Directory contents:"
@ -190,8 +277,8 @@ if [ -n "${SOS_WRITE_TOKEN:-}" ]; then
PUBLISHED_HASH=$(echo "$PUBLISH_OUTPUT" | grep "Hash:" | cut -d' ' -f2)
echo "Published hash: $PUBLISHED_HASH"
# Test 7: Check if published tool exists
echo -e "\nTest 7: Check published tool exists"
# Test 8: Check if published tool exists
echo -e "\nTest 8: Check published tool exists"
EXISTS_CHECK=$(curl -s "https://getpkg.xyz/exists/${TEST_TOOL_NAME}:${TEST_ARCH}" 2>/dev/null || echo "error")
if [[ "$EXISTS_CHECK" != "error" ]] && [[ "$EXISTS_CHECK" != "false" ]]; then
print_test_result "Published tool exists on server" 0
@ -199,30 +286,30 @@ if [ -n "${SOS_WRITE_TOKEN:-}" ]; then
print_test_result "Published tool exists on server" 1
fi
# Test 8: Install command
echo -e "\nTest 8: Install command"
# Test 9: Install command
echo -e "\nTest 9: Install command"
INSTALL_OUTPUT=$(timeout 3 "$GETPKG" install "$TEST_TOOL_NAME" 2>&1) || INSTALL_OUTPUT=""
if [[ "$INSTALL_OUTPUT" =~ Installed\ ${TEST_TOOL_NAME}\ successfully ]] || [[ "$INSTALL_OUTPUT" =~ ${TEST_TOOL_NAME}\ is\ already\ up\ to\ date ]]; then
print_test_result "Install tool from getpkg.xyz" 0
# Test 9: Check installed files
echo -e "\nTest 9: Check installed files"
# Test 10: Check installed files
echo -e "\nTest 10: Check installed files"
if [ -f ~/.config/getpkg/"${TEST_TOOL_NAME}.json" ] && [ -d ~/.local/bin/getpkg/"${TEST_TOOL_NAME}" ]; then
print_test_result "Tool files installed correctly" 0
else
print_test_result "Tool files installed correctly" 1
fi
# Test 10: Check bashrc_getpkg modifications
echo -e "\nTest 10: Check bashrc modifications"
# Test 11: Check bashrc_getpkg modifications
echo -e "\nTest 11: Check bashrc modifications"
if [ -f ~/.bashrc_getpkg ] && grep -q "${TEST_TOOL_NAME}" ~/.bashrc_getpkg; then
print_test_result "Bashrc modifications for PATH and autocomplete" 0
else
print_test_result "Bashrc modifications for PATH and autocomplete" 1
fi
# Test 11: Direct tool name install (shortcut syntax)
echo -e "\nTest 11: Direct tool install syntax"
# Test 12: Direct tool name install (shortcut syntax)
echo -e "\nTest 12: Direct tool install syntax"
# First remove the tool
rm -rf ~/.local/bin/getpkg/"${TEST_TOOL_NAME}"
rm -f ~/.config/getpkg/"${TEST_TOOL_NAME}.json"
@ -234,8 +321,8 @@ if [ -n "${SOS_WRITE_TOKEN:-}" ]; then
print_test_result "Direct tool name install syntax" 1
fi
# Test 12: Update already installed tool (should say up to date)
echo -e "\nTest 12: Update check for installed tool"
# Test 13: Update already installed tool (should say up to date)
echo -e "\nTest 13: Update check for installed tool"
UPDATE_OUTPUT=$(timeout 3 "$GETPKG" install "$TEST_TOOL_NAME" 2>&1) || UPDATE_OUTPUT=""
if [[ "$UPDATE_OUTPUT" =~ ${TEST_TOOL_NAME}\ is\ already\ up\ to\ date ]]; then
print_test_result "Update check recognizes up-to-date tool" 0
@ -263,8 +350,8 @@ if [ -n "${SOS_WRITE_TOKEN:-}" ]; then
print_test_result "Update check recognizes up-to-date tool" 1
fi
# Test 12b: Publish without ARCH (for cross-platform tools)
echo -e "\nTest 12b: Publish without ARCH"
# Test 13b: Publish without ARCH (for cross-platform tools)
echo -e "\nTest 13b: Publish without ARCH"
TEST_TOOL_NOARCH="${TEST_TOOL_NAME}-noarch"
mkdir -p "${TEST_DIR}/${TEST_TOOL_NOARCH}"
cat > "${TEST_DIR}/${TEST_TOOL_NOARCH}/${TEST_TOOL_NOARCH}" << 'EOF'
@ -293,8 +380,8 @@ EOF
print_test_result "Publish tool without ARCH" 1
fi
# Test 12c: Install universal tool (arch fallback)
echo -e "\nTest 12c: Install universal tool (arch fallback)"
# Test 13c: Install universal tool (arch fallback)
echo -e "\nTest 13c: Install universal tool (arch fallback)"
rm -rf ~/.config/getpkg/"${TEST_TOOL_NOARCH}.json" ~/.local/bin/getpkg/"${TEST_TOOL_NOARCH}" 2>/dev/null || true
FALLBACK_INSTALL_OUTPUT=$(timeout 3 "$GETPKG" install "${TEST_TOOL_NOARCH}" 2>&1) || FALLBACK_INSTALL_OUTPUT=""
if [[ "$FALLBACK_INSTALL_OUTPUT" =~ Arch-specific\ version\ not\ found,\ trying\ universal\ version ]] && [[ "$FALLBACK_INSTALL_OUTPUT" =~ Installed\ ${TEST_TOOL_NOARCH}\ successfully ]]; then
@ -316,8 +403,8 @@ else
echo "To run full tests, set SOS_WRITE_TOKEN environment variable"
fi
# Test 13: Invalid tool name validation
echo -e "\nTest 13: Invalid tool name validation"
# Test 14: Invalid tool name validation
echo -e "\nTest 14: Invalid tool name validation"
INVALID_OUTPUT=$(timeout 3 "$GETPKG" install "../evil-tool" 2>&1)
INVALID_EXIT_CODE=$?
echo "Invalid tool output: $INVALID_OUTPUT"
@ -328,9 +415,9 @@ else
print_test_result "Invalid tool name rejection" 1
fi
# Test 14: Update command (if we have tools installed)
# Test 15: Update command (if we have tools installed)
if [ -d ~/.config/getpkg ] && [ "$(find ~/.config/getpkg -name "*.json" -type f 2>/dev/null | wc -l)" -gt 0 ]; then
echo -e "\nTest 14: Update command"
echo -e "\nTest 15: Update command"
UPDATE_ALL_OUTPUT=$(timeout 30 "$GETPKG" update 2>&1) || UPDATE_ALL_OUTPUT=""
if [[ "$UPDATE_ALL_OUTPUT" =~ Update\ complete ]]; then
print_test_result "Update all tools command" 0

11
sos/sos
View File

@ -2,13 +2,13 @@
set -euo pipefail
# get dropshell
# get getpkg
TEMP_DIR=$(mktemp -d)
ARCH=$(uname -m)
curl -L -s -o "${TEMP_DIR}/dropshell" "https://getbin.xyz/dropshell.${ARCH}" || die "Failed to download dropshell"
chmod +x "${TEMP_DIR}/dropshell"
curl -L -s -o "${TEMP_DIR}/getpkg" "https://getbin.xyz/getpkg:latest-${ARCH}" || die "Failed to download getpkg"
chmod +x "${TEMP_DIR}/getpkg"
trap 'rm -rf "${TEMP_DIR}"' EXIT
DROPSHELL="${TEMP_DIR}/dropshell"
GETPKG="${TEMP_DIR}/getpkg"
function show_help() {
@ -42,7 +42,6 @@ function datetime() {
date -u +"%Y.%m%d.%H%M"
}
function upload() {
if [ "$#" -lt 3 ]; then
echo "Usage: sos upload <server> <file> <label:tag> [label:tag ...]"
@ -78,7 +77,7 @@ function upload() {
LABELTAGS_JSON="[${LABELTAGS_JSON%,}]"
# trip whitespace from the file path
LOCALHASH=$("${DROPSHELL}" hash "${file}" | tr -d '[:space:]')
LOCALHASH=$("${GETPKG}" hash "${file}" | tr -d '[:space:]')
echo "Local hash: $LOCALHASH"