'Generic Commit'
Some checks failed
Build-Test-Publish / build (linux/amd64) (push) Failing after 18s
Build-Test-Publish / build (linux/arm64) (push) Failing after 28s

This commit is contained in:
Your Name 2025-06-22 11:26:39 +12:00
parent ba5047db02
commit 6b781fdc34
5 changed files with 90 additions and 41 deletions

View File

@ -1,6 +1,6 @@
# getpkg - Package Manager for Dropshell Tools # getpkg - Package Manager for Dropshell Tools
getpkg is a command-line package manager that simplifies tool installation, management, and publishing for the dropshell ecosystem. Tools are installed to `~/.local/bin/getpkg/` and automatically added to your PATH with bash completion. getpkg is a command-line package manager that simplifies tool installation, management, and publishing for the dropshell ecosystem. Tools are installed to `~/.getpkg/` with executable symlinks in `~/.local/bin/getpkg/` and automatically added to your PATH with bash completion.
## Installation ## Installation
@ -75,11 +75,12 @@ getpkg version
When you install a tool, getpkg: When you install a tool, getpkg:
1. **Downloads** the tool archive from getpkg.xyz 1. **Downloads** the tool archive from getpkg.xyz
2. **Extracts** it to `~/.local/bin/getpkg/<tool_name>/` 2. **Extracts** it to `~/.getpkg/<tool_name>/`
3. **Updates PATH** by modifying `~/.bashrc_getpkg` 3. **Creates symlinks** for all executables in `~/.local/bin/getpkg/`
4. **Enables completion** for the tool 4. **Ensures PATH** includes `~/.local/bin/getpkg` (one-time setup)
5. **Runs setup** if a `setup_script.sh` exists 5. **Enables completion** for the tool
6. **Stores metadata** in `~/.config/getpkg/<tool_name>.json` 6. **Runs setup** if a `setup_script.sh` exists
7. **Stores metadata** in `~/.config/getpkg/<tool_name>.json`
### Architecture Support ### Architecture Support
@ -92,7 +93,8 @@ Tools are automatically downloaded for your architecture, with fallback to unive
### File Locations ### File Locations
- **Installed tools**: `~/.local/bin/getpkg/<tool_name>/` - **Tool files**: `~/.getpkg/<tool_name>/` (actual tool installation)
- **Executable symlinks**: `~/.local/bin/getpkg/` (in your PATH)
- **Configuration**: `~/.config/getpkg/` - **Configuration**: `~/.config/getpkg/`
- **PATH setup**: `~/.bashrc_getpkg` (sourced by `~/.bashrc`) - **PATH setup**: `~/.bashrc_getpkg` (sourced by `~/.bashrc`)

View File

@ -78,6 +78,7 @@ namespace dropshelltool
} }
infile.close(); infile.close();
lines.push_back(BLOCK_START); lines.push_back(BLOCK_START);
lines.push_back("export PATH=\"$HOME/.local/bin/getpkg:$PATH\"");
lines.push_back("source \"" + DROPSHELL_RC_PATH.string() + "\""); lines.push_back("source \"" + DROPSHELL_RC_PATH.string() + "\"");
lines.push_back(BLOCK_END); lines.push_back(BLOCK_END);
std::ofstream outfile(BASHRC_PATH, std::ios::trunc); std::ofstream outfile(BASHRC_PATH, std::ios::trunc);

View File

@ -31,41 +31,13 @@ void DropshellScriptManager::ensureExists() const {
} }
void DropshellScriptManager::addToolEntry(const std::string& toolName, const std::string& toolDir) { void DropshellScriptManager::addToolEntry(const std::string& toolName, const std::string& toolDir) {
ensureExists(); // Create symlinks instead of adding to PATH
std::ifstream infile(dropshelltool::DROPSHELL_RC_PATH); createSymlinks(toolName, toolDir);
std::vector<std::string> lines;
std::string line;
std::string exportLine = "export PATH=\"" + toolDir + ":$PATH\" # getpkg:" + toolName;
bool found = false;
while (std::getline(infile, line)) {
if (line.find("# getpkg:" + toolName) != std::string::npos) {
found = true;
lines.push_back(exportLine);
} else {
lines.push_back(line);
}
}
infile.close();
if (!found) lines.push_back(exportLine);
std::ofstream outfile(dropshelltool::DROPSHELL_RC_PATH, std::ios::trunc);
for (const auto& l : lines) outfile << l << "\n";
outfile.close();
} }
void DropshellScriptManager::removeToolEntry(const std::string& toolName) { void DropshellScriptManager::removeToolEntry(const std::string& toolName) {
ensureExists(); // Remove symlinks instead of PATH entries
std::ifstream infile(dropshelltool::DROPSHELL_RC_PATH); removeSymlinks(toolName);
std::vector<std::string> lines;
std::string line;
while (std::getline(infile, line)) {
if (line.find("# getpkg:" + toolName) == std::string::npos) {
lines.push_back(line);
}
}
infile.close();
std::ofstream outfile(dropshelltool::DROPSHELL_RC_PATH, std::ios::trunc);
for (const auto& l : lines) outfile << l << "\n";
outfile.close();
} }
void DropshellScriptManager::addAutocomplete(const std::string& toolName) { void DropshellScriptManager::addAutocomplete(const std::string& toolName) {
@ -156,3 +128,75 @@ void DropshellScriptManager::removeAutocomplete(const std::string& toolName) {
for (const auto& l : lines) outfile << l << "\n"; for (const auto& l : lines) outfile << l << "\n";
outfile.close(); outfile.close();
} }
void DropshellScriptManager::createSymlinks(const std::string& toolName, const std::string& toolDir) {
std::string home = std::getenv("HOME");
std::filesystem::path getpkgBinDir = std::filesystem::path(home) / ".local/bin/getpkg";
// Ensure the getpkg bin directory exists
std::filesystem::create_directories(getpkgBinDir);
// Remove existing symlinks for this tool first
removeSymlinks(toolName);
// Find all executable files in the tool directory
if (std::filesystem::exists(toolDir)) {
for (const auto& entry : std::filesystem::directory_iterator(toolDir)) {
if (entry.is_regular_file()) {
auto perms = std::filesystem::status(entry).permissions();
// Check if the file is executable (any execute bit set)
if ((perms & std::filesystem::perms::owner_exec) != std::filesystem::perms::none ||
(perms & std::filesystem::perms::group_exec) != std::filesystem::perms::none ||
(perms & std::filesystem::perms::others_exec) != std::filesystem::perms::none) {
std::string fileName = entry.path().filename().string();
std::filesystem::path symlinkPath = getpkgBinDir / fileName;
// Skip if a directory already exists with that name (tool installation directory)
if (std::filesystem::exists(symlinkPath) && std::filesystem::is_directory(symlinkPath)) {
continue;
}
// Remove existing symlink if it exists
if (std::filesystem::exists(symlinkPath) && std::filesystem::is_symlink(symlinkPath)) {
std::filesystem::remove(symlinkPath);
}
// Create symlink
try {
std::filesystem::create_symlink(entry.path(), symlinkPath);
std::cout << "Created symlink: " << symlinkPath << " -> " << entry.path() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Warning: Failed to create symlink " << symlinkPath << ": " << e.what() << std::endl;
}
}
}
}
}
}
void DropshellScriptManager::removeSymlinks(const std::string& toolName) {
std::string home = std::getenv("HOME");
std::filesystem::path getpkgBinDir = std::filesystem::path(home) / ".local/bin/getpkg";
std::filesystem::path toolDir = std::filesystem::path(home) / ".getpkg" / toolName;
if (!std::filesystem::exists(getpkgBinDir)) {
return;
}
// Remove symlinks that point to files in the tool directory
for (const auto& entry : std::filesystem::directory_iterator(getpkgBinDir)) {
if (entry.is_symlink()) {
try {
std::filesystem::path target = std::filesystem::read_symlink(entry.path());
// Check if the symlink points to something in the tool directory
if (target.string().find(toolDir.string()) == 0) {
std::filesystem::remove(entry.path());
std::cout << "Removed symlink: " << entry.path() << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Warning: Failed to process symlink " << entry.path() << ": " << e.what() << std::endl;
}
}
}
}

View File

@ -10,4 +10,6 @@ public:
void removeToolEntry(const std::string& toolName); void removeToolEntry(const std::string& toolName);
void addAutocomplete(const std::string& toolName); void addAutocomplete(const std::string& toolName);
void removeAutocomplete(const std::string& toolName); void removeAutocomplete(const std::string& toolName);
void createSymlinks(const std::string& toolName, const std::string& toolDir);
void removeSymlinks(const std::string& toolName);
}; };

View File

@ -144,7 +144,7 @@ int install_tool(int argc, char* argv[]) {
std::string arch = get_arch(); std::string arch = get_arch();
std::string home = get_home(); std::string home = get_home();
std::filesystem::path configDir = std::filesystem::path(home) / ".config/getpkg"; std::filesystem::path configDir = std::filesystem::path(home) / ".config/getpkg";
std::filesystem::path binDir = std::filesystem::path(home) / ".local/bin/getpkg" / toolName; std::filesystem::path binDir = std::filesystem::path(home) / ".getpkg" / toolName;
std::filesystem::path archivePath = configDir / (toolName + ".tgz"); std::filesystem::path archivePath = configDir / (toolName + ".tgz");
std::filesystem::path toolInfoPath = configDir / (toolName + ".json"); std::filesystem::path toolInfoPath = configDir / (toolName + ".json");
@ -501,7 +501,7 @@ int uninstall_tool(int argc, char* argv[]) {
std::string home = get_home(); std::string home = get_home();
std::filesystem::path configDir = std::filesystem::path(home) / ".config/getpkg"; std::filesystem::path configDir = std::filesystem::path(home) / ".config/getpkg";
std::filesystem::path binDir = std::filesystem::path(home) / ".local/bin/getpkg" / toolName; std::filesystem::path binDir = std::filesystem::path(home) / ".getpkg" / toolName;
std::filesystem::path toolInfoPath = configDir / (toolName + ".json"); std::filesystem::path toolInfoPath = configDir / (toolName + ".json");
// Check if tool is installed // Check if tool is installed