Compare commits

...

8 Commits

Author SHA1 Message Date
Your Name
9d4e5f76ce 'Generic Commit'
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 3m12s
2025-06-15 21:37:21 +12:00
Your Name
366f5c2d0e 'Generic Commit'
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m57s
2025-06-02 00:44:23 +12:00
Your Name
0b0f3df59c 'Generic Commit'
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 3m20s
2025-06-01 23:38:58 +12:00
Your Name
f48302c05e 'Generic Commit'
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
2025-06-01 23:37:34 +12:00
Your Name
7f341699c1 'Generic Commit'
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m52s
2025-06-01 23:34:31 +12:00
Your Name
18c53acd71 'Generic Commit'
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 3m21s
2025-06-01 23:16:42 +12:00
Your Name
eb632c010c 'Generic Commit'
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 3m27s
2025-06-01 23:06:14 +12:00
Your Name
964e8598b1 'Generic Commit'
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 3m27s
2025-06-01 18:33:37 +12:00
12 changed files with 197 additions and 163 deletions

View File

@ -14,14 +14,26 @@ jobs:
uses: actions/checkout@v4
- name: Install build dependencies
run: |
cd ${{ gitea.workspace }}/source
cd source
./install_build_prerequisites.sh
- name: Build
- name: Build Native
run: |
cd ${{ gitea.workspace }}/source
./multibuild.sh
cd source
./build_native.sh
- name: Test
run: |
cd ${{ gitea.workspace }}/source/output
./dropshell_x86_64 list
./dropshell_x86_64 help
cd source
./test.sh
- name: Build Production
run: |
cd source
./build_production.sh
- name: Test
run: |
cd source
./test.sh
- name: Publish
run: |
cd source
./publish.sh

22
dropshell-install.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
set -euo pipefail
# download and install dropshell
# 1. Determine architecture
# -----------------------------------------------------------------------------
ARCH=$(uname -m)
TARGET_PATH="${HOME}/.local/bin/dropshell"
[ ! -f "${TARGET_PATH}" ] || rm -f "${TARGET_PATH}"
mkdir -p "$(dirname "${TARGET_PATH}")"
curl -L -s -o "${TARGET_PATH}" "https://getbin.xyz/dropshell.${ARCH}" || die "Failed to download dropshell for ${ARCH}"
chmod +x "${TARGET_PATH}"
echo "dropshell installed successfully to $TARGET_PATH"
echo " "
echo "Please:"
echo "1. run '${TARGET_PATH} edit' to edit the configuration."
echo "2. run '${TARGET_PATH} install' to install dropshell components on this computer."
echo "3. run 'source ~/.bashrc' to add to your path and autocomplete for the current shell."

View File

@ -1,49 +0,0 @@
#!/bin/bash
set -e
# download and install dropshell
# 1. Determine architecture
# -----------------------------------------------------------------------------
ARCH=$(uname -m)
if [[ "$ARCH" == "x86_64" ]]; then
BIN=dropshell.x86_64
elif [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
BIN=dropshell.aarch64
else
echo "Unsupported architecture: $ARCH" >&2
exit 1
fi
# 2. Download the appropriate binary to a temp directory
# -----------------------------------------------------------------------------
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
URL="https://gitea.jde.nz/public/dropshell/releases/download/latest/$BIN"
echo "Downloading $BIN from $URL..."
TARGET_PATH="${HOME}/.local/bin/dropshell"
mkdir -p "${HOME}/.local/bin"
curl -fsSL -o "$TARGET_PATH" "$URL"
if [ ! -f "$TARGET_PATH" ]; then
echo "Failed to download dropshell" >&2
exit 1
fi
chmod +x "$TARGET_PATH"
if [ ! -f "${HOME}/.local/bin/ds" ]; then
ln -s "$TARGET_PATH" "${HOME}/.local/bin/ds"
fi
echo "dropshell installed successfully to $TARGET_PATH"
echo "Please:"
echo "1. run '${TARGET_PATH} edit' to edit the configuration."
echo "2. run '${TARGET_PATH} install' to install dropshell components on this computer."
echo "3. run 'source ~/.bashrc' to add to your path and autocomplete for the current shell."

View File

@ -21,16 +21,13 @@ fi
_check_required_env_vars "AGENT_PATH"
function install_bb64() {
curl -fsSL "https://gitea.jde.nz/public/bb64/releases/download/latest/install.sh" | bash -s -- "$AGENT_PATH" "$(id -u $USER):$(id -g $USER)"
# test result code from curl
if [ $? -ne 0 ]; then
if ! curl -fsSL "https://gitea.jde.nz/public/bb64/releases/download/latest/install.sh" | \
bash -s -- "$AGENT_PATH" "$(id -u "$USER"):$(id -g "$USER")"; then
_die "Failed to install bb64. Curl returned non-zero exit code."
fi
# test if bb64 is installed
VER=$("$AGENT_PATH/bb64" -v)
if [ $? -ne 0 ]; then
if ! VER=$("$AGENT_PATH/bb64" -v); then
_die "bb64 did not install correctly."
fi

View File

@ -6,7 +6,14 @@ INSTALL_DIR=${HOME}/.local/bin
mkdir -p "${OUTPUT_DIR}"
# Exit on error
set -e
set -euo pipefail
ARCH=$(uname -m)
if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "aarch64" ]; then
echo "Unsupported architecture: $ARCH"
exit 1
fi
function build_native() {
local BUILDDIR=${SCRIPT_DIR}/build/native
@ -16,8 +23,8 @@ function build_native() {
mkdir -p "${BUILDDIR}"
cd "${SCRIPT_DIR}" || exit 1
CC="${HOME}/.musl-cross/x86_64-linux-musl-native/bin/x86_64-linux-musl-gcc"
CXX="${HOME}/.musl-cross/x86_64-linux-musl-native/bin/x86_64-linux-musl-g++"
CC="${HOME}/.musl-cross/${ARCH}-linux-musl-native/bin/${ARCH}-linux-musl-gcc"
CXX="${HOME}/.musl-cross/${ARCH}-linux-musl-native/bin/${ARCH}-linux-musl-g++"
cmake -B "${BUILDDIR}" -G Ninja \
@ -32,15 +39,15 @@ function build_native() {
ninja -j"$JOBS"
#upx ${BUILDDIR}/dropshell
cp "${BUILDDIR}/dropshell" "${OUTPUT_DIR}/dropshell.native"
cp "${BUILDDIR}/dropshell" "${OUTPUT_DIR}/dropshell.${ARCH}"
cd "${PREVDIR}" || exit 1
}
build_native
echo "Auto-installing dropshell locally..."
mkdir -p "${INSTALL_DIR}"
cp "${OUTPUT_DIR}/dropshell.native" "${INSTALL_DIR}/dropshell"
ds version
cp "${OUTPUT_DIR}/dropshell.${ARCH}" "${INSTALL_DIR}/dropshell"
echo "Build process completed!"

View File

@ -1,15 +1,15 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# Create output directory
mkdir -p ${SCRIPT_DIR}/output
mkdir -p "${SCRIPT_DIR}/output"
PREV_DIR=$(pwd)
cd "${SCRIPT_DIR}"
trap 'cd "${PREV_DIR}"' EXIT
function build_arch() {
local arch=$1
local PREVDIR=$PWD
cd ${SCRIPT_DIR}
if [ ! -f "${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-c++" ]; then
echo "Musl cross compiler for ${arch} not found. Please run install_build_prerequisites.sh first."
@ -20,16 +20,14 @@ function build_arch() {
CC="${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-gcc"
CXX="${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-g++"
BUILDDIR=${SCRIPT_DIR}/build/${arch}
mkdir -p ${BUILDDIR}
BUILDDIR="${SCRIPT_DIR}/build/${arch}"
mkdir -p "${BUILDDIR}"
cmake -B ${BUILDDIR} -G Ninja -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX}
cmake --build ${BUILDDIR}
cmake -B "${BUILDDIR}" -G Ninja -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" -DCMAKE_C_COMPILER="${CC}" -DCMAKE_CXX_COMPILER="${CXX}"
cmake --build "${BUILDDIR}"
upx ${BUILDDIR}/dropshell
cp ${BUILDDIR}/dropshell ${SCRIPT_DIR}/output/dropshell.${arch}
cd ${PREVDIR}
upx "${BUILDDIR}/dropshell"
cp "${BUILDDIR}/dropshell" "${SCRIPT_DIR}/output/dropshell.${arch}"
}
build_arch x86_64

View File

@ -9,74 +9,21 @@ echo "Script directory: $SCRIPT_DIR"
TOKEN="${GITEA_TOKEN_DEPLOY:-${GITEA_TOKEN}}"
[ -z "$TOKEN" ] && { echo "Neither GITEA_TOKEN_DEPLOY nor GITEA_TOKEN environment variable set!" >&2; exit 1; }
"$SCRIPT_DIR/multibuild.sh"
#BUILD_DIR=$SCRIPT_DIR/build
OLD_PWD="$PWD"
cd "$SCRIPT_DIR" || exit 1
TEMP_DIR=$(mktemp -d)
trap 'rm -rf "$TEMP_DIR" && cd "$OLD_PWD"' EXIT
# Check for required binaries
REQUIRED_BINARIES=("dropshell.x86_64" "dropshell.aarch64")
for binary in "${REQUIRED_BINARIES[@]}"; do
if [ ! -f "output/$binary" ]; then
echo "output/$binary not found!" >&2
echo "Please run multibuild.sh first." >&2
exit 1
fi
done
TAG=$("$SCRIPT_DIR/output/dropshell.x86_64" --version)
[ -z "$TAG" ] && echo "Failed to get version from dropshell.x86_64" >&2 && exit 1
ARCH=$(uname -m)
TAG=$("$SCRIPT_DIR/output/dropshell.${ARCH}" --version)
[ -z "$TAG" ] && echo "Failed to get version from dropshell.${ARCH}" >&2 && exit 1
echo "Publishing dropshell version $TAG"
# make sure we've commited.
git add "$SCRIPT_DIR/../" && git commit -m "dropshell release $TAG" && git push
# Find repo info from .git/config
REPO_URL=$(git config --get remote.origin.url)
if [[ ! $REPO_URL =~ gitea ]]; then
echo "Remote origin is not a Gitea repository: $REPO_URL" >&2
function die() {
echo "$@" >&2
exit 1
fi
# Extract base URL, owner, and repo
# Example: https://gitea.example.com/username/reponame.git
BASE_URL=$(echo "$REPO_URL" | sed -E 's#(https?://[^/]+)/.*#\1#')
OWNER=$(echo "$REPO_URL" | sed -E 's#.*/([^/]+)/[^/]+(\.git)?$#\1#')
REPO=$(echo "$REPO_URL" | sed -E 's#.*/([^/]+)(\.git)?$#\1#')
API_URL="$BASE_URL/api/v1/repos/$OWNER/$REPO"
# Create release
RELEASE_DATA=$(cat <<EOF
{
"tag_name": "$TAG",
"name": "$TAG",
"body": "dropshell release $TAG",
"draft": false,
"prerelease": false
}
EOF
)
# Capture stdout and stderr of the curl command
CURL_OUTPUT=$(curl -X POST "$API_URL/releases" \
-H "Content-Type: application/json" \
-H "Authorization: token $TOKEN" \
-d "$RELEASE_DATA" 2>&1)
# Extract the release ID from the captured output
RELEASE_ID=$(echo "$CURL_OUTPUT" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
if [ -z "$RELEASE_ID" ]; then
echo "Failed to create release on Gitea." >&2
echo "Release ID returned: $RELEASE_ID" >&2
echo "Curl Output/Error:" >&2
echo "$CURL_OUTPUT" >&2
exit 1
fi
# Function to find file in specified locations
find_file() {
@ -94,25 +41,17 @@ find_file() {
return 1
}
curl -L -s -o "${TEMP_DIR}/sos" "https://getbin.xyz/sos" || die "Failed to download sos"
chmod +x "${TEMP_DIR}/sos"
# Upload binaries and install.sh
for FILE in dropshell.x86_64 dropshell.aarch64 install.sh server_autosetup.sh; do
for FILE in dropshell.x86_64 dropshell.aarch64 dropshell-install.sh dropshell-server-autosetup.sh; do
# Pass the locations directly to the find_file function
filetoupload=$(find_file "$FILE" "output" "../" ".")
if [ -z "$filetoupload" ]; then
echo "File $FILE not found in expected locations!" >&2
continue
fi
[ -z "$filetoupload" ] && die "File $FILE not found in expected locations!"
# Auto-detect content type
ctype=$(file --mime-type -b "$filetoupload")
curl -X POST "$API_URL/releases/$RELEASE_ID/assets?name=$FILE" \
-H "Content-Type: $ctype" \
-H "Authorization: token $TOKEN" \
--data-binary @"$filetoupload"
echo "Uploaded $FILE to release $TAG as $ctype."
"${TEMP_DIR}/sos" upload getbin.xyz "$filetoupload" "$FILE:latest" "$FILE:TAG"
done
echo "Published dropshell version $TAG to $REPO_URL (tag $TAG) with binaries."
cd "$OLD_PWD" || exit 1
echo "Published dropshell $TAG to getbin.xyz"

View File

@ -0,0 +1,83 @@
#include "command_registry.hpp"
#include "config.hpp"
#include "utils/utils.hpp"
#include "utils/directories.hpp"
#include "shared_commands.hpp"
#include "version.hpp"
#include "hash.hpp"
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <sstream>
#include <filesystem>
#include <libassert/assert.hpp>
namespace dropshell {
void hash_autocomplete(const CommandContext& ctx);
int hash_handler(const CommandContext& ctx);
static std::vector<std::string> hash_name_list={"hash"};
// Static registration
struct HashCommandRegister {
HashCommandRegister() {
CommandRegistry::instance().register_command({
hash_name_list,
hash_handler,
hash_autocomplete,
false, // hidden
false, // requires_config
false, // requires_install
0, // min_args (after command)
1, // max_args (after command)
"hash [FILE|DIRECTORY]",
"Hash a file or directory.",
// heredoc
R"(
Hash a file or directory recursively.
)"
});
}
} hash_command_register;
void hash_autocomplete(const CommandContext& ctx) {
if (ctx.args.size() == 0) {
// list all files and directories in the current directory
for (const auto& entry : std::filesystem::directory_iterator(".")) {
rawout << entry.path().string() << std::endl;
}
}
return;
}
int hash_handler(const CommandContext& ctx) {
std::filesystem::path path = safearg(ctx.args, 0);
if (path.empty())
path=std::filesystem::current_path();
if (!std::filesystem::exists(path))
{
error << "Does not exist: " << path.string() << std::endl;
return 1;
}
if (std::filesystem::is_directory(path))
{
// hash the directory recursively
uint64_t hash = hash_directory_recursive(path.string());
std::cout << hash << std::endl;
}
else
{
// hash the file
uint64_t hash = hash_file(path.string());
std::cout << hash << std::endl;
}
return 0;
}
} // namespace dropshell

View File

@ -310,7 +310,7 @@ complete -F _dropshell_completions ds
std::filesystem::remove(exe_path.parent_path() / "dropshell.old");
// execute the new version
execlp("bash", "bash", "-c", (parent_path / "dropshell").c_str(), "install", (char *)nullptr);
execlp("bash", "bash", "-c", (exe_path.parent_path() / "dropshell").string() + "install", (char *)nullptr);
error << "Failed to execute new version of dropshell." << std::endl;
return -1;
}

View File

@ -650,11 +650,24 @@ bool file_replace_or_add_segment(std::string filepath, std::string segment)
return true;
}
bool legal_service_name(const std::string &service_name)
{
// legal characters are alphanumeric, and - and _
std::regex legal_chars("^[a-zA-Z0-9_-]+$");
return std::regex_match(service_name, legal_chars);
bool legal_service_name(const std::string &service_name) {
static bool initialized = false;
static bool legal_chars[256] = {false}; // Initialize all to false
// One-time initialization
if (!initialized) {
// Set true for valid characters
for (unsigned char c : "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"._-") {
legal_chars[c] = true;
}
initialized = true;
}
return std::all_of(service_name.begin(), service_name.end(),
[](unsigned char c) { return legal_chars[c]; });
}
} // namespace dropshell

12
source/test.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
ARCH=$(uname -m)
PREV_DIR=$(pwd)
trap 'cd "$PREV_DIR"' EXIT
"$SCRIPT_DIR/output/dropshell.${ARCH}" hash "${SCRIPT_DIR}/test.sh"
"$SCRIPT_DIR/output/dropshell.${ARCH}" help