Compare commits

...

7 Commits
v6 ... main

Author SHA1 Message Date
Your Name
c51f0da8e5 dehydrate release v11 2025-05-25 18:29:40 +12:00
Your Name
6d400e3751 Tidy 2025-05-25 18:29:12 +12:00
Your Name
d9a082bc3f dehydrate release v10 2025-05-21 21:37:42 +12:00
Your Name
fba807a958 dehydrate release v9 2025-05-21 21:35:13 +12:00
Your Name
8bab3d0426 dehydrate release v8 2025-05-21 21:29:19 +12:00
Your Name
80c62d827a dehydrate release v7 2025-05-17 11:54:39 +12:00
Your Name
e641e02478 Ensure permissions are written. 2025-05-17 11:54:07 +12:00
5 changed files with 53 additions and 38 deletions

View File

@ -4,11 +4,11 @@
Automated system-wide installation:
```
curl -fsSL https://gitea.jde.nz/public/dehydrate/releases/download/latest/install.sh | bash
curl -fsSL https://gitea.jde.nz/public/dehydrate/releases/download/latest/install.sh | sudo bash
```
To download just the dehydrate executable:
```
curl -fsSL -o dehydrate https://gitea.jde.nz/public/dehydrate/releases/download/latest/dehydrate.amd64 && chmod a+x bb64
curl -fsSL -o dehydrate https://gitea.jde.nz/public/dehydrate/releases/download/latest/dehydrate.amd64 && chmod a+x dehydrate
```
## How it Works

View File

@ -1 +1 @@
static const char *VERSION = "6";
static const char *VERSION = "11";

View File

@ -3,24 +3,23 @@ set -e
PROJECT="dehydrate"
# RUN AS ROOT
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" >&2
exit 1
fi
# 0. see if we were passed a folder to install to
# -----------------------------------------------------------------------------
INSTALL_DIR="$1"
if [[ -z "$INSTALL_DIR" ]]; then
INSTALL_DIR="/usr/local/bin"
else
echo "Installing $PROJECT to $INSTALL_DIR"
if [[ ! -d "$INSTALL_DIR" ]]; then
mkdir -p "$INSTALL_DIR"
fi
fi
# 0. see if we were passed a user to chown to
# -----------------------------------------------------------------------------
CHOWN_USER="$2"
if [[ -z "$CHOWN_USER" ]]; then
CHOWN_USER=$(id -u)
fi
echo "Installing $PROJECT to $INSTALL_DIR"
# 1. Determine architecture
# -----------------------------------------------------------------------------
@ -35,27 +34,18 @@ else
exit 1
fi
# 3. Download the appropriate binary to a temp directory
# 3. Download the appropriate binary
# -----------------------------------------------------------------------------
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
URL="https://gitea.jde.nz/public/$PROJECT/releases/download/latest/$BIN"
echo "Downloading $BIN from $URL..."
curl -fsSL -o "$TMPDIR/$PROJECT" "$URL"
URL="https://gitea.jde.nz/public/$PROJECT/releases/download/latest/$BIN"
echo "Downloading $BIN from $URL to $TMPDIR..."
curl -fsSL -o "$INSTALL_DIR/$PROJECT" "$URL"
# 4. Make it executable
# -----------------------------------------------------------------------------
chmod +x "$TMPDIR/$PROJECT"
# 5. Move to /usr/local/bin
# -----------------------------------------------------------------------------
docker run --rm -v "$TMPDIR:/tmp" -v "$INSTALL_DIR:/target" alpine sh -c "cp /tmp/$PROJECT /target/$PROJECT; chown $CHOWN_USER /target/$PROJECT"
rm "$TMPDIR/$PROJECT"
chmod +x "$INSTALL_DIR/$PROJECT"
# 6. Print success message
# -----------------------------------------------------------------------------
echo "$PROJECT installed successfully to $INSTALL_DIR/$PROJECT (arch $ARCH)"
echo " "
echo "Update $PROJECT in future with:"
echo " $PROJECT -u"

View File

@ -87,30 +87,53 @@ static void base64_decode(const char* encoded_data, size_t encoded_len, unsigned
// Utility function to recreate a file with proper permissions
static bool _recreate_file_(const std::filesystem::path& outpath, uint64_t file_hash, std::filesystem::perms file_perms, const unsigned char* filedata, size_t filedata_len) {
namespace fs = std::filesystem;
uint64_t existing_hash = 0;
bool needs_write = false;
// Check if file exists and has correct hash
if (fs::exists(outpath)) {
// Check content hash
std::ifstream in(outpath, std::ios::binary);
std::ostringstream oss;
oss << in.rdbuf();
std::string data = oss.str();
existing_hash = fnv1a_64(data.data(), data.size());
uint64_t existing_hash = fnv1a_64(data.data(), data.size());
needs_write = existing_hash != file_hash;
} else {
needs_write = true; // File doesn't exist, need to create it
}
bool needs_write = !fs::exists(outpath) || existing_hash != file_hash;
bool needs_permission_update = true;
if (!needs_write) { // we always update permissions if the file is written or changed. Othewise we check.
fs::perms current_perms = fs::status(outpath).permissions();
needs_permission_update = current_perms != file_perms;
}
if (needs_write) {
bool existed = fs::exists(outpath);
fs::create_directories(outpath.parent_path());
std::ofstream out(outpath, std::ios::binary);
out.write(reinterpret_cast<const char*>(filedata), filedata_len);
out.close();
// Set the file permissions
fs::permissions(outpath, file_perms);
if (!existed) {
std::cout << "[dehydrate] " << outpath.filename() << ": created\n";
} else {
std::cout << "[dehydrate] " << outpath.filename() << ": updated (hash changed)\n";
}
return true;
}
if (needs_permission_update) {
// Update only permissions
fs::permissions(outpath, file_perms);
std::cout << "[dehydrate] " << outpath.filename() << ": updated (permissions changed)\n";
return true;
}
if (!fs::exists(outpath)) {
std::cout << "[dehydrate] " << outpath.filename() << ": created\n";
} else if (needs_write) {
std::cout << "[dehydrate] " << outpath.filename() << ": updated (hash changed)\n";
}
return needs_write;
return false;
}
)cpp";
}
@ -122,6 +145,7 @@ void generate_file_code(const std::string& source, const std::string& destfolder
std::string ns = "recreate_" + sanitize(src.stem().string());
std::string cppname = "_" + src.stem().string() + ".cpp";
std::string hppname = "_" + src.stem().string() + ".hpp";
std::string bothname = "_" + src.stem().string() + ".{cpp,hpp}";
fs::create_directories(dest);
std::ifstream in(source, std::ios::binary);
std::ostringstream oss;
@ -198,7 +222,7 @@ bool recreate_file(std::string destination_folder) {
cpp << "}\n";
if (!silent) {
std::cout << "[dehydrate] Generated: " << (dest / cppname) << ", " << (dest / hppname) << std::endl;
std::cout << "[dehydrate] Generated: " << (dest / bothname) << std::endl;
}
}
@ -217,6 +241,7 @@ void generate_folder_code(const std::string& source, const std::string& destfold
std::string ns = "recreate_" + sanitize(src.stem().string());
std::string cppname = "_" + src.stem().string() + ".cpp";
std::string hppname = "_" + src.stem().string() + ".hpp";
std::string bothname = "_" + src.stem().string() + ".{cpp,hpp}";
fs::create_directories(dest);
// Collect all files
std::vector<fs::path> files;
@ -342,6 +367,6 @@ bool recreate_tree(std::string destination_folder) {
cpp << "}\n";
if (!silent) {
std::cout << "[dehydrate] Generated: " << (dest / cppname) << ", " << (dest / hppname) << std::endl;
std::cout << "[dehydrate] Generated: " << (dest / bothname) << std::endl;
}
}

View File

@ -38,7 +38,7 @@ $TEST_DIR/testexe
# third time just two files changed
echo "----------------------------------------"
echo "Should be two changes: generator.cpp and hash.cpp"
echo "Should see: hash.cpp - updated, and generator.cpp - created."
rm $TEST_DIR/temp/generator.cpp
echo "whee!" >> $TEST_DIR/temp/hash.cpp