init: initial commit of packager

This commit is contained in:
Didier Slof 2023-07-13 00:11:44 +02:00
commit 7964bb84fd
Signed by: didier
GPG key ID: 01E71F18AA4398E5
25 changed files with 478 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
**/target
**/Cargo.lock

8
.idea/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

7
.idea/discord.xml Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pkgr.iml" filepath="$PROJECT_DIR$/.idea/pkgr.iml" />
</modules>
</component>
</project>

17
.idea/pkgr.iml Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/bootpkg/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/manifest/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/pkgr/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/pkgfile/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/bootpkg/target" />
<excludeFolder url="file://$MODULE_DIR$/manifest/target" />
<excludeFolder url="file://$MODULE_DIR$/pkgr/target" />
<excludeFolder url="file://$MODULE_DIR$/pkgfile/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

8
README.md Normal file
View file

@ -0,0 +1,8 @@
# Packager
> "A package manager and builder but like rust."
> -- Gandhi (2050)
> ***not even close to done*** :)
Packager is a simple yet powerful package manager

12
bootpkg/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
[package]
name = "bootpkg"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
manifest = { path = "../manifest" }
pkgfile = { path = "../pkgfile" }
regex = "1.9.1"
reqwest = { version = "0.11.18", features = ["blocking"] }

29
bootpkg/src/args.rs Normal file
View file

@ -0,0 +1,29 @@
pub enum Command {
Strap,
Unpack,
None
}
impl From<String> for Command {
fn from(value: String) -> Self {
match value.to_lowercase().as_str() {
"strap" => Command::Strap,
"unpack" => Command::Unpack,
_ => Command::None
}
}
}
pub struct Args {
pub command: Command,
pub args: Vec<String>,
}
impl From<Vec<String>> for Args {
fn from(value: Vec<String>) -> Self {
Args {
command: Command::from(value[0].to_owned()),
args: value[1..].to_owned()
}
}
}

51
bootpkg/src/main.rs Normal file
View file

@ -0,0 +1,51 @@
use std::env;
use std::process::exit;
use pkgfile::PKGFile;
use crate::args::{Args, Command};
mod prelude;
mod args;
fn main() {
let args = Args::from(env::args().collect::<Vec<String>>()[1..].to_owned());
match args.command {
Command::Strap => {
if args.args.len() == 0 {
println!("no path/uri");
exit(0);
}
let uri = &args.args[0];
println!("!! Got package: \"{}\"", uri);
let re = r"[A-z]+://.+";
let data = if regex::Regex::new(re).unwrap().is_match(uri) {
println!("** detected uri.");
reqwest::blocking::get(uri)
.expect("Could not request file.")
.bytes()
.expect("Could not turn file into bytes.")
.to_vec()
} else {
if let Ok(d) = std::fs::read(uri) {
d
} else {
println!("Could not read file!");
exit(1);
}
};
let p = match PKGFile::try_from(data) {
Ok(p) => p,
Err(_) => {
println!("!! Could not interpret PKGFile...");
exit(1);
}
};
},
Command::Unpack => todo!(),
_ => {
println!("Unsupported command, allowed commands: strap/unpack.");
exit(1);
}
}
}

22
bootpkg/src/prelude.rs Normal file
View file

@ -0,0 +1,22 @@
use std::collections::HashMap;
use manifest::Manifest;
pub struct PKGR {
pub bootstrap: Option<Bootstrap>,
}
pub struct Bootstrap {}
pub fn def_manifest() {
Manifest::<Option<PKGR>> {
package: manifest::package::Package::default(),
bin: None,
build: None,
dependencies: HashMap::default(),
fs: manifest::fs::FS {
config: None,
data: None,
},
pkgr: Some(PKGR { bootstrap: None }),
};
}

14
build-pkg.toml Normal file
View file

@ -0,0 +1,14 @@
[project]
package_file = "./package.toml"
package_dir = "./pkg"
increment_version = false
[mappings.source]
ignore = ["target/"]
[mappings.source.map]
"." = "/src"
[mappings.bin.map]
"target/release/bin/pkgr" = "/bin/pkgr"

10
manifest/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "manifest"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
toml = "0.7.6"
serde = { version = "1.0.171", features = ["derive"] }

7
manifest/src/bin.rs Normal file
View file

@ -0,0 +1,7 @@
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Bin {
pub root: String,
}

10
manifest/src/build.rs Normal file
View file

@ -0,0 +1,10 @@
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Build {
build_script: String,
install_script: String,
dependencies: HashMap<String, String>
}

16
manifest/src/fs.rs Normal file
View file

@ -0,0 +1,16 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct FS {
pub config: Option<String>,
pub data: Option<String>,
}
impl Default for FS {
fn default() -> Self {
FS {
config: None,
data: None,
}
}
}

32
manifest/src/lib.rs Normal file
View file

@ -0,0 +1,32 @@
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub mod package;
pub mod fs;
pub mod bin;
pub mod build;
pub mod pkgr;
#[derive(Serialize, Deserialize)]
#[serde(default)]
pub struct Manifest<P = Option<pkgr::PKGR>> {
pub package: package::Package,
pub dependencies: HashMap<String, String>,
pub fs: fs::FS,
pub bin: Option<bin::Bin>,
pub build: Option<build::Build>,
pub pkgr: P
}
impl Default for Manifest {
fn default() -> Self {
Manifest {
package: package::Package::default(),
dependencies: HashMap::default(),
fs: fs::FS::default(),
bin: None,
build: None,
pkgr: None
}
}
}

45
manifest/src/package.rs Normal file
View file

@ -0,0 +1,45 @@
use std::str::FromStr;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
pub enum PackageType {
#[serde(rename = "application")]
Application,
#[serde(rename = "library")]
Library,
#[serde(rename = "meta")]
Meta
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(default)]
pub struct Package {
pub name: String,
pub description: String,
pub package_type: PackageType,
pub version: u64,
pub tags: Vec<String>,
pub arch: String
}
impl Default for Package {
fn default() -> Self {
Package {
name: String::default(),
description: String::default(),
package_type: PackageType::Application,
version: 0,
tags: Vec::default(),
arch: std::env::consts::ARCH.to_string()
}
}
}
impl FromStr for Package {
type Err = toml::de::Error;
fn from_str(s: &str) -> Result<Package, toml::de::Error> {
toml::from_str(s)
}
}

4
manifest/src/pkgr.rs Normal file
View file

@ -0,0 +1,4 @@
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct PKGR {}

110
package.toml Normal file
View file

@ -0,0 +1,110 @@
#* = required.
[package]
name = "packager" #*
description = "A package installation tool" #*
## package.version
# needs to be an int and be incremented every time
# if you use a custom version system and want to use that, you can use the tag system!
# the highest package.version on the server will be given the tag "latest"
version = 1 # this can automatically be incremented when publishing by running `pkgr publish -i ...`
## package.tags
# you can add tags to a package to specify kinds
# there are some special tags:
# - latest
# automatically set on the last published version
# previous version will lose this tag
# - oldest
# assigned to the first version.
tags = [
"prod",
"pkgr-spec-1"
]
## package.type
# Supported types:
# - application
# this type specifies that this package is an application.
# - library
# this type specifies that this package is a library.
# - meta
# this type specifies that this package does not install anything upon the system except for dependencies.
type = "application"
arch = "x86_64" # this is automatically filled by `pkgr publish ...`
## dependencies
# you may use the following syntax
# "<version/tag>" or "<version/tag>,<version/tag>,..."
[dependencies]
example = { arch = "x86_64", tags = [ "stable" ], version = "v1" }
exnmbr2 = "v1,stable"
## fs
# specify some directories for ease of use
[fs]
## fs.config
# specifiy the config path
config = "/etc/packager"
## fs.data
# specify the data path
data = "/var/lib/packager"
## replace "pacakger" with your package name to find the default value.
## bin
# Used for systems that don't want to build pkgs.
[bin] # binary files root
## bin.root
# ** RELATIVE TO PACKAGE ROOT **
# bin.root specifies the root of the installed tree.
# anything in here will be overlayed on top of the system.
root = "/root" #*
## bin.checksums
# ** KEYS are relative to BIN.ROOT **
# ** VALUES are relative to PKG ROOT **
# checksums is used to perform checksums before install
# values may be paths or a uri. You may include variables.
# supported variables:
# - @name
# - @version
# - @display_version
[bin.checksums]
"/usr/bin/pkgr" = "https://ixvd.net/checksums/packager/@version"
## build
# Scripts will be copied to a custom root.
# After the pacakge is built, the install script is ran.
# After the install script the build directory will be deleted and an CTREE (changed tree) will be generated.
# Then the CTREE will be used to copy the files over.
[build]
build_script = "/scripts/build" # relative to pkg
install_script = "/scripts/install" # relative to pkg
[build.dependencies]
base = "latest,stable" # selected by default
## pkgr.*
# packager is the official client but you may use other clients supporting the "pkgr v1 spec".
# other clients may offer extra functionality this must be put under "pkgr.*"
[pkgr]
## pkgr.bootstrap
# This section is used for bootpkg. An edition of packager that bootstraps the full version.
# This exists so that packager is easy to install on anything!
# and only 1 release channel for pkgr
[pkgr.bootstrap]
# any non-zero = installed
check_installed_commands = [
"/scripts/check_installed"
]
# any non-zero = fail
commands = [
"/scripts/bootstrap/download_latest @version /tmp/pkgr.pkg",
"/scripts/bootstrap/dirty_install /tmp/pkgr.pkg",
"/scripts/bootstrap/check_install"
]

10
pkgfile/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "pkgfile"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
manifest = { path = "../manifest" }
tar = "0.4.38"

3
pkgfile/pkgfile.txt Normal file
View file

@ -0,0 +1,3 @@
[pkgfile version (1 byte)][size manifest x256 (1 byte)][size manifest x1 (1 byte)]
[manifest]
[tar file]

36
pkgfile/src/lib.rs Normal file
View file

@ -0,0 +1,36 @@
pub struct PKGFile {
pub manifest: String,
pub data: Vec<u8>,
}
impl TryFrom<Vec<u8>> for PKGFile {
type Error = ();
fn try_from(value: Vec<u8>) -> Result<Self, ()> {
match value[0] {
1 => {
let header: Vec<u32> = value[..3]
.iter()
.map(|v| u32::from(*v))
.collect();
let manifest_size: u32 = ((header[1] << 8) | header[2]);
if manifest_size > value.len() as u32 {
return Err(());
}
Ok(PKGFile {
manifest: match String::from_utf8(
value[
3..(manifest_size as usize)
].to_vec()
)
{
Ok(s) => s,
_ => return Err(())
},
data: value[(manifest_size as usize)..].to_vec(),
})
}
_ => Err(())
}
}
}

9
pkgr/Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "pkgr"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
manifest = { path = "../manifest" }

2
pkgr/src/main.rs Normal file
View file

@ -0,0 +1,2 @@
fn main() {
}