Compare commits
6 Commits
v2025.0630
...
v2025.0719
Author | SHA1 | Date | |
---|---|---|---|
f5ba2e719b | |||
73c94f34f6 | |||
af4cbbcab0 | |||
a415eb0f91 | |||
83d6cf1603 | |||
fbaa3a4089 |
23
.kiro/steering/product.md
Normal file
23
.kiro/steering/product.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Product Overview
|
||||||
|
|
||||||
|
This repository contains **getpkg** - a command-line package manager for the dropshell ecosystem, along with a collection of developer tools.
|
||||||
|
|
||||||
|
## Core Product
|
||||||
|
- **getpkg**: Package manager that installs tools to `~/.getpkg/` with symlinks in `~/.local/bin/getpkg/`
|
||||||
|
- Supports multiple architectures (x86_64, aarch64, universal)
|
||||||
|
- Tools are published to and downloaded from `getpkg.xyz`
|
||||||
|
|
||||||
|
## Tool Collection
|
||||||
|
The repository includes several utility tools:
|
||||||
|
- **bb64**: Bash-compatible base64 encoder/decoder with custom character set
|
||||||
|
- **dehydrate**: Converts files/directories to C++ source code for embedding
|
||||||
|
- **whatsdirty**: Git repository status checker
|
||||||
|
- **sos**: Simple object storage client
|
||||||
|
- **gp**: Git push utility
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
- Cross-platform tool distribution
|
||||||
|
- Automated installation with PATH setup
|
||||||
|
- Bash completion support
|
||||||
|
- Architecture-aware downloads with fallbacks
|
||||||
|
- Publishing system with authentication tokens
|
72
.kiro/steering/structure.md
Normal file
72
.kiro/steering/structure.md
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# Project Structure
|
||||||
|
|
||||||
|
## Repository Layout
|
||||||
|
```
|
||||||
|
├── buildtestpublish_all.sh # Master build script for all projects
|
||||||
|
├── clean.sh # Global cleanup script
|
||||||
|
├── README.md # Main project documentation
|
||||||
|
└── <tool-name>/ # Individual tool directories
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tool Directory Structure
|
||||||
|
|
||||||
|
### C++ Projects (CMake-based)
|
||||||
|
```
|
||||||
|
<tool-name>/
|
||||||
|
├── CMakeLists.txt # CMake configuration
|
||||||
|
├── build.sh # Build script
|
||||||
|
├── test.sh # Test script
|
||||||
|
├── clean.sh # Cleanup script
|
||||||
|
├── publish.sh # Publishing script
|
||||||
|
├── install.sh # Installation script
|
||||||
|
├── README.md # Tool documentation
|
||||||
|
├── Dockerfile.dropshell-build # Docker build configuration
|
||||||
|
├── src/ # Source code
|
||||||
|
│ ├── <tool>.cpp # Main source file
|
||||||
|
│ ├── version.hpp.in # Version template
|
||||||
|
│ └── ... # Additional sources
|
||||||
|
├── build/ # Build artifacts (generated)
|
||||||
|
├── output/ # Final executables (generated)
|
||||||
|
└── .vscode/ # VS Code configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
### Shell Script Projects
|
||||||
|
```
|
||||||
|
<tool-name>/
|
||||||
|
├── <tool-name> # Executable shell script
|
||||||
|
├── build.sh # Build script (may be no-op)
|
||||||
|
├── test.sh # Test script
|
||||||
|
├── clean.sh # Cleanup script
|
||||||
|
├── publish.sh # Publishing script
|
||||||
|
└── setup_script.sh # Post-install setup (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Standard Files
|
||||||
|
|
||||||
|
### Required Scripts
|
||||||
|
- **build.sh**: Builds the project (Docker for C++, no-op for shell)
|
||||||
|
- **test.sh**: Runs project tests
|
||||||
|
- **clean.sh**: Removes build artifacts
|
||||||
|
- **publish.sh**: Publishes to getpkg.xyz registry
|
||||||
|
|
||||||
|
### Optional Files
|
||||||
|
- **install.sh**: System-wide installation script
|
||||||
|
- **setup_script.sh**: Post-install setup for getpkg
|
||||||
|
- **cmake_prebuild.sh**: Pre-build setup for CMake projects
|
||||||
|
|
||||||
|
### Generated Directories
|
||||||
|
- **build/**: CMake build artifacts (C++ projects)
|
||||||
|
- **output/**: Final executables ready for distribution
|
||||||
|
- **test_*/**: Test-specific directories
|
||||||
|
|
||||||
|
## Naming Conventions
|
||||||
|
- Tool directories match executable names
|
||||||
|
- C++ source files typically match project name
|
||||||
|
- Version templates use `.hpp.in` extension
|
||||||
|
- Docker files use `Dockerfile.dropshell-build` pattern
|
||||||
|
- Test directories prefixed with `test_`
|
||||||
|
|
||||||
|
## Configuration Files
|
||||||
|
- **.gitignore**: Standard ignore patterns for build artifacts
|
||||||
|
- **.vscode/**: VS Code workspace settings
|
||||||
|
- **CMakeLists.txt**: Follows standard template with PROJECT_NAME parameter
|
70
.kiro/steering/tech.md
Normal file
70
.kiro/steering/tech.md
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# Technology Stack
|
||||||
|
|
||||||
|
## Build System
|
||||||
|
- **CMake 3.16+** with Ninja generator for C++ projects
|
||||||
|
- **Docker** containerized builds using `gitea.jde.nz/public/dropshell-build-base:latest`
|
||||||
|
- **Static linking** for all C++ executables (`-static` flag)
|
||||||
|
|
||||||
|
## Languages & Standards
|
||||||
|
- **C++23** standard for all C++ projects
|
||||||
|
- **Bash** for shell scripts and simple tools
|
||||||
|
- **Shell scripts** follow `set -euo pipefail` pattern
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- **nlohmann_json** for JSON handling in C++ projects
|
||||||
|
- **CPR (static)** for HTTP requests in getpkg
|
||||||
|
- Custom modules in `/usr/local/share/cmake/Modules`
|
||||||
|
|
||||||
|
## Common Build Patterns
|
||||||
|
|
||||||
|
### C++ Projects (CMake)
|
||||||
|
```bash
|
||||||
|
# Standard build command
|
||||||
|
cmake -G Ninja -S . -B ./build -DCMAKE_BUILD_TYPE=Debug -DPROJECT_NAME=<project>
|
||||||
|
cmake --build ./build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Build (for C++ tools)
|
||||||
|
```bash
|
||||||
|
# Uses Dockerfile.dropshell-build pattern
|
||||||
|
docker build -t <project>-build -f Dockerfile.dropshell-build --build-arg PROJECT=<project> --output ./output .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Shell Tools
|
||||||
|
- No build step required
|
||||||
|
- Executable shell scripts with proper shebang
|
||||||
|
- Use `chmod +x` for permissions
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
### Build
|
||||||
|
```bash
|
||||||
|
./build.sh # Build individual project
|
||||||
|
./buildtestpublish_all.sh # Build all projects
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test
|
||||||
|
```bash
|
||||||
|
./test.sh # Run tests for individual project
|
||||||
|
```
|
||||||
|
|
||||||
|
### Clean
|
||||||
|
```bash
|
||||||
|
./clean.sh # Clean build artifacts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Publish
|
||||||
|
```bash
|
||||||
|
./publish.sh # Publish to getpkg.xyz (requires SOS_WRITE_TOKEN)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version Management
|
||||||
|
- Automatic timestamp-based versioning: `YYYY.MMDD.HHMM`
|
||||||
|
- Version configured via `version.hpp.in` template files
|
||||||
|
- Pre-build scripts (`cmake_prebuild.sh`) for additional setup
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
- `CMAKE_BUILD_TYPE`: Debug/Release (default: Debug)
|
||||||
|
- `SOS_WRITE_TOKEN`: Authentication for publishing
|
||||||
|
- `NO_CACHE`: Skip Docker cache when set to "true"
|
||||||
|
- `PROJECT`: Project name for build scripts
|
@ -109,7 +109,7 @@ function buildtestpublish() {
|
|||||||
# Add to projects list
|
# Add to projects list
|
||||||
PROJECTS+=("$TOOLNAME")
|
PROJECTS+=("$TOOLNAME")
|
||||||
|
|
||||||
#cd "$dir" || echo "Failed to cd to $dir"
|
cd "$dir" || echo "Failed to cd to $dir"
|
||||||
|
|
||||||
subtitle "🔨 BUILDING $TOOLNAME_UPPER 🔨"
|
subtitle "🔨 BUILDING $TOOLNAME_UPPER 🔨"
|
||||||
if dothis build "$dir" "$TOOLNAME"; then
|
if dothis build "$dir" "$TOOLNAME"; then
|
||||||
|
@ -3,7 +3,7 @@ set -euo pipefail
|
|||||||
|
|
||||||
# Get script directory - handle different execution contexts
|
# Get script directory - handle different execution contexts
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
PROJECT="$(basename "$(dirname "${SCRIPT_DIR}")")"
|
PROJECT="$(basename "${SCRIPT_DIR}")"
|
||||||
|
|
||||||
# Debug output for CI
|
# Debug output for CI
|
||||||
echo "${PROJECT} build script running from: ${SCRIPT_DIR}"
|
echo "${PROJECT} build script running from: ${SCRIPT_DIR}"
|
||||||
|
@ -59,6 +59,10 @@ echo -e "${YELLOW}Running dehydrate tests...${NC}\n"
|
|||||||
|
|
||||||
# Debug output
|
# Debug output
|
||||||
echo "Looking for dehydrate at: $DEHYDRATE"
|
echo "Looking for dehydrate at: $DEHYDRATE"
|
||||||
|
echo "Workspace structure:"
|
||||||
|
ls -la "${GITHUB_WORKSPACE}" 2>/dev/null || echo "Workspace not found"
|
||||||
|
echo "Dehydrate directory contents:"
|
||||||
|
ls -la "${GITHUB_WORKSPACE}/dehydrate" 2>/dev/null || echo "Dehydrate directory not found"
|
||||||
echo "Output directory contents:"
|
echo "Output directory contents:"
|
||||||
ls -la "$OUTPUT_DIR" 2>/dev/null || echo "Output directory not found"
|
ls -la "$OUTPUT_DIR" 2>/dev/null || echo "Output directory not found"
|
||||||
|
|
||||||
@ -66,6 +70,18 @@ ls -la "$OUTPUT_DIR" 2>/dev/null || echo "Output directory not found"
|
|||||||
if [ ! -f "$DEHYDRATE" ]; then
|
if [ ! -f "$DEHYDRATE" ]; then
|
||||||
echo -e "${RED}Error: dehydrate binary not found at $DEHYDRATE${NC}"
|
echo -e "${RED}Error: dehydrate binary not found at $DEHYDRATE${NC}"
|
||||||
echo "Please run ./build.sh first to build dehydrate"
|
echo "Please run ./build.sh first to build dehydrate"
|
||||||
|
|
||||||
|
if [ -n "${GITEA_CONTAINER_NAME:-}" ]; then
|
||||||
|
echo "Checking if build directory exists..."
|
||||||
|
BUILD_DIR="${GITHUB_WORKSPACE}/dehydrate/build"
|
||||||
|
if [ -d "$BUILD_DIR" ]; then
|
||||||
|
echo "Build directory exists, checking contents:"
|
||||||
|
ls -la "$BUILD_DIR"
|
||||||
|
else
|
||||||
|
echo "Build directory $BUILD_DIR does not exist"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ set -euo pipefail
|
|||||||
|
|
||||||
# Get script directory - handle different execution contexts
|
# Get script directory - handle different execution contexts
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
PROJECT="$(basename "$(dirname "${SCRIPT_DIR}")")"
|
PROJECT="$(basename "${SCRIPT_DIR}")"
|
||||||
|
|
||||||
# Debug output for CI
|
# Debug output for CI
|
||||||
echo "${PROJECT} build script running from: ${SCRIPT_DIR}"
|
echo "${PROJECT} build script running from: ${SCRIPT_DIR}"
|
||||||
|
@ -1150,6 +1150,85 @@ void show_help() {
|
|||||||
std::cout << " ~/.local/bin/getpkg/ Installed tool binaries" << std::endl;
|
std::cout << " ~/.local/bin/getpkg/ Installed tool binaries" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int autocomplete_command(int argc, char* argv[]) {
|
||||||
|
std::vector<std::string> args(argv + 2, argv + argc);
|
||||||
|
|
||||||
|
// If no arguments, return all commands
|
||||||
|
if (args.empty()) {
|
||||||
|
std::cout << "install\n";
|
||||||
|
std::cout << "uninstall\n";
|
||||||
|
std::cout << "publish\n";
|
||||||
|
std::cout << "unpublish\n";
|
||||||
|
std::cout << "update\n";
|
||||||
|
std::cout << "version\n";
|
||||||
|
std::cout << "create\n";
|
||||||
|
std::cout << "hash\n";
|
||||||
|
std::cout << "list\n";
|
||||||
|
std::cout << "clean\n";
|
||||||
|
std::cout << "help\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& subcommand = args[0];
|
||||||
|
|
||||||
|
// Handle autocompletion for specific commands
|
||||||
|
if (subcommand == "install") {
|
||||||
|
// For install, we could suggest popular packages or recently published ones
|
||||||
|
// For now, just return empty (no specific completions)
|
||||||
|
return 0;
|
||||||
|
} else if (subcommand == "uninstall") {
|
||||||
|
// For uninstall, list installed tools
|
||||||
|
std::filesystem::path configDir = std::filesystem::path(std::getenv("HOME")) / ".config" / "getpkg";
|
||||||
|
if (std::filesystem::exists(configDir)) {
|
||||||
|
for (const auto& entry : std::filesystem::directory_iterator(configDir)) {
|
||||||
|
if (entry.path().extension() == ".json") {
|
||||||
|
std::string toolName = entry.path().stem().string();
|
||||||
|
std::cout << toolName << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else if (subcommand == "publish") {
|
||||||
|
// For publish, suggest architecture suffixes after tool name
|
||||||
|
if (args.size() >= 2) {
|
||||||
|
// If we have tool_name already, suggest architectures
|
||||||
|
std::cout << "x86_64\n";
|
||||||
|
std::cout << "aarch64\n";
|
||||||
|
std::cout << "universal\n";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else if (subcommand == "unpublish") {
|
||||||
|
// For unpublish, list installed tools (similar to uninstall)
|
||||||
|
std::filesystem::path configDir = std::filesystem::path(std::getenv("HOME")) / ".config" / "getpkg";
|
||||||
|
if (std::filesystem::exists(configDir)) {
|
||||||
|
for (const auto& entry : std::filesystem::directory_iterator(configDir)) {
|
||||||
|
if (entry.path().extension() == ".json") {
|
||||||
|
std::string toolName = entry.path().stem().string();
|
||||||
|
std::cout << toolName << "\n";
|
||||||
|
// Also suggest with architecture suffixes
|
||||||
|
std::cout << toolName << ":x86_64\n";
|
||||||
|
std::cout << toolName << ":aarch64\n";
|
||||||
|
std::cout << toolName << ":universal\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else if (subcommand == "create") {
|
||||||
|
// For create, no specific completions (tool name and directory are user-defined)
|
||||||
|
return 0;
|
||||||
|
} else if (subcommand == "hash") {
|
||||||
|
// For hash, suggest file extensions
|
||||||
|
if (args.size() >= 2) {
|
||||||
|
std::cout << "*.tgz\n";
|
||||||
|
std::cout << "*.tar.gz\n";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No specific completions for other commands
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
@ -1169,19 +1248,7 @@ int main(int argc, char* argv[]) {
|
|||||||
} else if (command == "update") {
|
} else if (command == "update") {
|
||||||
return update_tool(argc, argv);
|
return update_tool(argc, argv);
|
||||||
} else if (command == "autocomplete") {
|
} else if (command == "autocomplete") {
|
||||||
std::vector<std::string> args(argv + 2, argv + argc);
|
return autocomplete_command(argc, argv);
|
||||||
if (args.empty()) std::cout << R"(install
|
|
||||||
uninstall
|
|
||||||
publish
|
|
||||||
unpublish
|
|
||||||
update
|
|
||||||
version
|
|
||||||
create
|
|
||||||
hash
|
|
||||||
list
|
|
||||||
clean
|
|
||||||
help
|
|
||||||
)";
|
|
||||||
} else if (command == "version") {
|
} else if (command == "version") {
|
||||||
std::cout << dropshell::VERSION << std::endl;
|
std::cout << dropshell::VERSION << std::endl;
|
||||||
} else if (command == "create") {
|
} else if (command == "create") {
|
||||||
|
@ -25,6 +25,7 @@ GETPKG="${SCRIPT_DIR}/../getpkg/output/getpkg"
|
|||||||
TOOLDIR="${SCRIPT_DIR}/tool"
|
TOOLDIR="${SCRIPT_DIR}/tool"
|
||||||
mkdir -p "${TOOLDIR}"
|
mkdir -p "${TOOLDIR}"
|
||||||
cp "${SCRIPT_DIR}/whatsdirty" "${TOOLDIR}/whatsdirty"
|
cp "${SCRIPT_DIR}/whatsdirty" "${TOOLDIR}/whatsdirty"
|
||||||
|
cp "${SCRIPT_DIR}/setup_script.sh" "${TOOLDIR}/"
|
||||||
|
|
||||||
# publish universal tool.
|
# publish universal tool.
|
||||||
"${GETPKG}" publish "whatsdirty" "${TOOLDIR}"
|
"${GETPKG}" publish "whatsdirty" "${TOOLDIR}"
|
||||||
|
Reference in New Issue
Block a user