Compare commits

5 Commits

23 changed files with 883 additions and 177 deletions

66
cmd/packets/cli.go Normal file
View File

@@ -0,0 +1,66 @@
package main
import (
"os"
"os/exec"
"time"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
var docStyle = lipgloss.NewStyle().Margin(1, 2)
type item struct {
title, desc string
}
func (i item) Title() string { return i.title }
func (i item) Description() string { return i.desc }
func (i item) FilterValue() string { return i.title }
type model struct {
list list.Model
}
func (m model) Init() tea.Cmd {
return nil
}
type vimMsg struct{}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
if msg.String() == "ctrl+c" || msg.String() == "q" {
return m, tea.Quit
}
if msg.String() == "enter" {
path := m.list.SelectedItem().(item).desc
tea.ExecProcess(openEditor("vim", path), nil)
return m, tea.Quit
}
case tea.WindowSizeMsg:
h, v := docStyle.GetFrameSize()
m.list.SetSize(msg.Width-h, msg.Height-v)
}
var cmd tea.Cmd
m.list, cmd = m.list.Update(msg)
return m, cmd
}
func (m model) View() string {
return docStyle.Render(m.list.View())
}
func openEditor(editor, path string) *exec.Cmd {
time.Sleep(1 * time.Second)
cmd := exec.Command(editor, path)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd
}

View File

@@ -1,91 +0,0 @@
package database
import (
"database/sql"
"time"
_ "github.com/mattn/go-sqlite3"
"github.com/roboogg133/packets/pkg/packet.lua.d"
)
const (
CreateInstructions = `CREATE TABLE installed_packges(
name TEXT NOT NULL,
id TEXT PRIMARY KEY,
version TEXT NOT NULL,
serial INTEGER NOT NULL,
maintainer TEXT NOT NULL,
verified INTEGER NOT NULL DEFAULT 0,
description TEXT NOT NULL,
upload_time TEXT NOT NULL,
installed_time TEXT NOT NULL,
image BLOB,
UNIQUE(name, signature),
UNIQUE(name, version),
UNIQUE(name, serial)
)
CREATE TABLE package_files(
package_id TEXT PRIMARY KEY,
filepath TEXT NOT NULL,
is_dir INTEGER NOT NULL DEFAULT 0,
UNIQUE(package_id, filepath)
)
CREATE TABLE dependencies(
package_id TEXT NOT NULL,
dependency_name TEXT NOT NULL,
constraint TEXT NOT NULL,
PRIMARY KEY (package_id, dependency_name)
)
CREATE TABLE build_dependencies(
package_id TEXT NOT NULL,
dependency_name TEXT NOT NULL,
constraint TEXT NOT NULL,
PRIMARY KEY (package_id, dependency_name)
)
CREATE TABLE conflicts(
package_id TEXT NOT NULL,
dependency_name TEXT NOT NULL,
constraint TEXT NOT NULL,
PRIMARY KEY (package_id, dependency_name)
)
CREATE TABLE package_flags(
package_id TEXT NOT NULL,
flag TEXT NOT NULL,
name TEXT NOT NULL,
path TEXT NOT NULL,
)
`
)
type DatabaseOptions struct {
// Add any additional options here
}
func MarkAsInstalled(pkg packet.PacketLua, db *sql.DB, image *[]byte) error {
if image != nil {
_, err := db.Exec("INSERT INTO installed_packages (name, id, version, installed_time, image) VALUES (?, ?, ?, ?, ?, ?, ?)", pkg.Name, pkg.Name+"@"+pkg.Version, pkg.Version, time.Now().UnixMilli(), image)
if err != nil {
return err
}
} else {
_, err := db.Exec("INSERT INTO installed_packages (name, id, version, installed_time, image) VALUES (?, ?, ?, ?, ?, ?, ?)", pkg.Name, pkg.Name+"@"+pkg.Version, pkg.Version, time.Now().UnixMilli(), []byte{1})
if err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,133 @@
package database
import (
"database/sql"
"fmt"
"strings"
"time"
_ "github.com/mattn/go-sqlite3"
"github.com/roboogg133/packets/internal/lua"
"github.com/roboogg133/packets/pkg/install"
"github.com/roboogg133/packets/pkg/packet.lua.d"
)
const (
CreateInstructions = `
CREATE TABLE IF NOT EXISTS installed_packages(
name TEXT NOT NULL,
id TEXT PRIMARY KEY,
version TEXT NOT NULL,
serial INTEGER NOT NULL,
maintainer TEXT NOT NULL,
verified INTEGER NOT NULL DEFAULT 0,
description TEXT NOT NULL,
upload_time TEXT NOT NULL,
installed_time INTEGER NOT NULL,
image BLOB,
UNIQUE(name, version),
UNIQUE(name, serial)
);
CREATE TABLE IF NOT EXISTS package_files(
package_id TEXT NOT NULL,
path TEXT NOT NULL,
is_dir INTEGER NOT NULL DEFAULT 0,
UNIQUE(package_id, path)
);
CREATE TABLE IF NOT EXISTS dependencies(
package_id TEXT NOT NULL,
dependency_name TEXT NOT NULL,
version_constraint TEXT NOT NULL,
PRIMARY KEY (package_id, dependency_name)
);
CREATE TABLE IF NOT EXISTS build_dependencies(
package_id TEXT NOT NULL,
dependency_name TEXT NOT NULL,
version_constraint TEXT NOT NULL,
PRIMARY KEY (package_id, dependency_name)
);
CREATE TABLE IF NOT EXISTS conflicts(
package_id TEXT NOT NULL,
dependency_name TEXT NOT NULL,
version_constraint TEXT NOT NULL,
PRIMARY KEY (package_id, dependency_name)
);
CREATE TABLE IF NOT EXISTS package_flags(
package_id TEXT NOT NULL,
flag TEXT NOT NULL,
name TEXT NOT NULL,
path TEXT NOT NULL
);
`
)
type DatabaseOptions struct {
// Add any additional options here
}
func MarkAsInstalled(pkg packet.PacketLua, files []install.BasicFileStatus, PACKETDIR string, flags []lua.Flag, db *sql.DB, image []byte, upload_time int64) error {
switch {
case upload_time == 0:
upload_time = time.Now().UnixMilli()
case image == nil:
image = []byte{1}
}
_, err := db.Exec("INSERT INTO installed_packages (name, id, version, installed_time, image, serial, maintainer, description, upload_time) VALUES (?, ?, ?, ?, ?, ?,?,?,?)", pkg.Name, pkg.Name+"@"+pkg.Version, pkg.Version, time.Now().UnixMilli(), image, pkg.Serial, pkg.Maintainer, pkg.Description, time.Now().UnixMilli())
if err != nil {
db.Exec("DELETE FROM installed_packages WHERE id = ?", pkg.Name+"@"+pkg.Version)
return err
}
for _, v := range files {
v.Filepath, _ = strings.CutPrefix(v.Filepath, PACKETDIR)
_, err = db.Exec("INSERT INTO package_files (package_id, path, is_dir) VALUES (?, ?, ?)", pkg.Name+"@"+pkg.Version, v.Filepath, v.IsDir)
if err != nil {
db.Exec("DELETE FROM installed_packages WHERE id = ?", pkg.Name+"@"+pkg.Version)
db.Exec("DELETE FROM package_files WHERE package_id = ?", pkg.Name+"@"+pkg.Version)
return err
}
}
for _, v := range flags {
_, err = db.Exec("INSERT INTO package_flags (package_id, flag, name, path) VALUES (?, ?, ?, ?)", pkg.Name+"@"+pkg.Version, v.FlagType, v.Name, v.Path)
if err != nil {
db.Exec("DELETE FROM installed_packages WHERE id = ?", pkg.Name+"@"+pkg.Version)
db.Exec("DELETE FROM package_files WHERE package_id = ?", pkg.Name+"@"+pkg.Version)
db.Exec("DELETE FROM package_flags WHERE package_id = ?", pkg.Name+"@"+pkg.Version)
return err
}
}
return nil
}
func MarkAsUninstalled(id string, db *sql.DB) error {
if _, err := db.Exec("DELETE FROM installed_packages WHERE id = ?", id); err != nil {
return err
}
if _, err := db.Exec("DELETE FROM package_files WHERE package_id = ?", id); err != nil {
return err
}
if _, err := db.Exec("DELETE FROM package_flags WHERE package_id = ?", id); err != nil {
return err
}
return nil
}
func PrepareDataBase(db *sql.DB) {
_, err := db.Exec(CreateInstructions)
if err != nil {
fmt.Println("Error preparing database:", err)
}
}

View File

@@ -0,0 +1,72 @@
package database
import (
"database/sql"
"strings"
"github.com/roboogg133/packets/internal/lua"
"github.com/roboogg133/packets/pkg/install"
"github.com/roboogg133/packets/pkg/packet.lua.d"
)
// this function will get from a package name an id based on installed packages
func GetPackageId(name string, db *sql.DB) (packet.PackageID, error) {
var id packet.PackageID
if strings.Contains(name, "@") {
id.ID = strings.SplitAfter(name, "@")[0]
return id, nil
}
err := db.QueryRow("SELECT id FROM installed_packages WHERE name = ?", name).Scan(&id.ID)
return id, err
}
func SearchIfIsInstalled(name string, db *sql.DB) (bool, error) {
var exists bool
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM installed_packages WHERE name = ?)", name).Scan(&exists)
return exists, err
}
func GetAllFromFlag(packageID packet.PackageID, flagType string, db *sql.DB) ([]lua.Flag, error) {
var flags []lua.Flag
rows, err := db.Query("SELECT name, path FROM package_flags WHERE package_id = ? AND flag = ?", packageID.ID, flagType)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var flag lua.Flag
if err := rows.Scan(&flag.Name, &flag.Path); err != nil {
return nil, err
}
flag.FlagType = flagType
flags = append(flags, flag)
}
return flags, nil
}
func GetPackageFiles(packageID packet.PackageID, db *sql.DB) ([]install.BasicFileStatus, error) {
var files []install.BasicFileStatus
rows, err := db.Query("SELECT path, is_dir FROM package_files WHERE package_id = ?", packageID.ID)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var file install.BasicFileStatus
if err := rows.Scan(&file.Filepath, &file.IsDir); err != nil {
return nil, err
}
files = append(files, file)
}
if err := rows.Err(); err != nil {
return nil, err
}
return files, nil
}

View File

@@ -43,40 +43,43 @@ func extractZipFile(file *zip.File, dest string) error {
return err return err
} }
func Decompress(data []byte, outputDir, filename string) error { func Decompress(data io.Reader, outputDir, filename string) error {
var reader io.Reader var reader io.Reader
switch { switch {
case strings.HasSuffix(filename, ".gz"): case strings.HasSuffix(filename, ".gz"):
var err error var err error
reader, err = gzip.NewReader(bytes.NewReader(data)) reader, err = gzip.NewReader(data)
if err != nil { if err != nil {
return err return err
} }
filename, _ = strings.CutSuffix(filename, ".gz") filename, _ = strings.CutSuffix(filename, ".gz")
case strings.HasSuffix(filename, ".xz"): case strings.HasSuffix(filename, ".xz"):
var err error var err error
reader, err = xz.NewReader(bytes.NewReader(data)) reader, err = xz.NewReader(data)
if err != nil { if err != nil {
return err return err
} }
filename, _ = strings.CutSuffix(filename, ".xz") filename, _ = strings.CutSuffix(filename, ".xz")
case strings.HasSuffix(filename, ".zst"): case strings.HasSuffix(filename, ".zst"), strings.HasSuffix(filename, ".pkt"):
var err error var err error
reader, err = zstd.NewReader(bytes.NewReader(data)) reader, err = zstd.NewReader(data)
if err != nil { if err != nil {
return err return err
} }
filename, _ = strings.CutSuffix(filename, ".zst") filename, _ = strings.CutSuffix(filename, ".zst")
case strings.HasSuffix(filename, ".bz2"): case strings.HasSuffix(filename, ".bz2"):
reader = bzip2.NewReader(bytes.NewReader(data)) reader = bzip2.NewReader(data)
filename, _ = strings.CutSuffix(filename, ".bz2") filename, _ = strings.CutSuffix(filename, ".bz2")
case strings.HasSuffix(filename, ".lz4"): case strings.HasSuffix(filename, ".lz4"):
reader = lz4.NewReader(bytes.NewReader(data)) reader = lz4.NewReader(data)
filename, _ = strings.CutSuffix(filename, ".lz4") filename, _ = strings.CutSuffix(filename, ".lz4")
case strings.HasSuffix(filename, ".zip"): case strings.HasSuffix(filename, ".zip"):
byteReader := bytes.NewReader(data) content, err := io.ReadAll(data)
reader, err := zip.NewReader(byteReader, int64(len(data))) if err != nil {
return err
}
reader, err := zip.NewReader(bytes.NewReader(content), int64(len(content)))
if err != nil { if err != nil {
return err return err
} }
@@ -93,8 +96,7 @@ func Decompress(data []byte, outputDir, filename string) error {
return nil return nil
} }
if strings.HasSuffix(filename, ".tar") { if strings.HasSuffix(filename, ".tar") || strings.HasSuffix(filename, ".pkt") {
tarReader := tar.NewReader(reader) tarReader := tar.NewReader(reader)
for { for {
@@ -121,7 +123,6 @@ func Decompress(data []byte, outputDir, filename string) error {
if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil { if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil {
return err return err
} }
outFile, err := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(header.Mode)) outFile, err := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(header.Mode))
if err != nil { if err != nil {
return err return err

77
cmd/packets/flags.go Normal file
View File

@@ -0,0 +1,77 @@
package main
import (
"database/sql"
"fmt"
"os"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/roboogg133/packets/cmd/packets/database"
"github.com/spf13/cobra"
)
var configCmd = &cobra.Command{
Use: "config {name or id}",
Short: "Show package configuration file",
Long: "Show package configuration file",
Args: cobra.RangeArgs(1, 1),
PreRun: func(cmd *cobra.Command, args []string) {
GrantPrivilegies()
},
Run: func(cmd *cobra.Command, args []string) {
insertedName := args[0]
db, err := sql.Open("sqlite3", InternalDB)
if err != nil {
fmt.Println("Error opening database:", err)
os.Exit(1)
}
defer db.Close()
database.PrepareDataBase(db)
id, err := database.GetPackageId(insertedName, db)
if err != nil {
if err == sql.ErrNoRows {
fmt.Printf("package %s not found\n", insertedName)
} else {
fmt.Println("Error getting package ID:", err)
}
os.Exit(1)
}
flags, err := database.GetAllFromFlag(id, "config", db)
if err != nil {
fmt.Println("Error getting flags:", err)
os.Exit(1)
}
if raw, _ := cmd.Flags().GetBool("raw"); raw {
for _, flag := range flags {
fmt.Printf("%s->%s\n", flag.Name, flag.Path)
}
return
}
var all []list.Item
for _, flag := range flags {
item := item{
title: flag.Name,
desc: flag.Path,
}
all = append(all, item)
}
m := model{list: list.New(all, list.NewDefaultDelegate(), 0, 0)}
m.list.Title = "Configuration files"
p := tea.NewProgram(m, tea.WithAltScreen())
if _, err := p.Run(); err != nil {
fmt.Println("Error running program:", err)
os.Exit(1)
}
},
}

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"os" "os"
"path" "path"
@@ -21,8 +22,10 @@ func DownloadSource(sources *[]packet.Source, configs *packet.Config) error {
if source.Method == "GET" || source.Method == "POST" { if source.Method == "GET" || source.Method == "POST" {
f := downloaded.([]byte) f := downloaded.([]byte)
buf := bytes.NewBuffer(f)
_ = os.MkdirAll(configs.SourcesDir, 0755) _ = os.MkdirAll(configs.SourcesDir, 0755)
if err := decompress.Decompress(f, configs.SourcesDir, path.Base(source.Url)); err != nil {
if err := decompress.Decompress(buf, configs.SourcesDir, path.Base(source.Url)); err != nil {
return fmt.Errorf("error: %s", err.Error()) return fmt.Errorf("error: %s", err.Error())
} }
} else { } else {

View File

@@ -1,17 +1,32 @@
package main package main
import ( import (
"archive/tar"
"database/sql"
"fmt" "fmt"
"io"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"github.com/klauspost/compress/zstd"
_ "github.com/mattn/go-sqlite3"
"github.com/roboogg133/packets/cmd/packets/database"
"github.com/roboogg133/packets/cmd/packets/decompress"
"github.com/roboogg133/packets/pkg/install" "github.com/roboogg133/packets/pkg/install"
"github.com/roboogg133/packets/pkg/packet.lua.d" "github.com/roboogg133/packets/pkg/packet.lua.d"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func GrantPrivilegies() {
if os.Geteuid() != 0 {
fmt.Println("error: this operation must be run as root")
os.Exit(1)
}
}
var Config *PacketsConfiguration var Config *PacketsConfiguration
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
@@ -22,25 +37,29 @@ var rootCmd = &cobra.Command{
var executeCmd = &cobra.Command{ var executeCmd = &cobra.Command{
Use: "execute {path}", Use: "execute {path}",
Short: "Installs a package from a given Packet.lua file", Short: "Installs a package from a given .pkt file",
Long: "Installs a package from a given Packet.lua file", Long: "Installs a package from a given .pkt file",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error { PreRunE: func(cmd *cobra.Command, args []string) error {
GrantPrivilegies()
return GetConfiguration() return GetConfiguration()
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
for _, v := range args { for _, v := range args {
if !strings.HasSuffix(v, ".lua") { var pkg packet.PacketLua
fmt.Printf("error: %s need to have .lua suffix\n", v)
if !strings.HasSuffix(v, ".pkt") {
fmt.Printf("error: %s is not a valid Packets packet file\n", v)
os.Exit(1) os.Exit(1)
} }
contentBlob, err := os.ReadFile(v)
contentBlob, err := os.Open(v)
if err != nil { if err != nil {
fmt.Printf("error: %s could not be read\n", v) fmt.Printf("error: %s could not be read\n", v)
os.Exit(1) os.Exit(1)
} }
pkg, err := packet.ReadPacket(contentBlob, &packet.Config{BinDir: Config.BinDir}) defer contentBlob.Close()
pkg, err = packet.ReadPacketFromZSTDF(contentBlob, &packet.Config{BinDir: Config.BinDir})
if err != nil { if err != nil {
fmt.Printf("error: %s", err.Error()) fmt.Printf("error: %s", err.Error())
os.Exit(1) os.Exit(1)
@@ -68,7 +87,33 @@ var executeCmd = &cobra.Command{
PacketDir: packetsdir, PacketDir: packetsdir,
} }
db, err := sql.Open("sqlite3", InternalDB)
if err != nil {
fmt.Printf("error: %s", err.Error())
os.Exit(1)
}
defer db.Close()
database.PrepareDataBase(db)
if installed, err := database.SearchIfIsInstalled(pkg.Name, db); err == nil {
if installed {
fmt.Printf("package %s is already installed", pkg.Name)
continue
}
} else {
fmt.Printf("error: %s", err.Error())
os.Exit(1)
}
backupDir, err := filepath.Abs(".")
_ = ChangeToNoPermission()
_ = os.MkdirAll(configs.RootDir, 0755) _ = os.MkdirAll(configs.RootDir, 0755)
contentBlob.Seek(0, io.SeekStart)
if err := decompress.Decompress(contentBlob, configs.RootDir, filepath.Base(v)); err != nil {
fmt.Printf("error: %s", err.Error())
os.Exit(1)
}
_ = os.MkdirAll(configs.SourcesDir, 0755) _ = os.MkdirAll(configs.SourcesDir, 0755)
_ = os.MkdirAll(configs.PacketDir, 0755) _ = os.MkdirAll(configs.PacketDir, 0755)
@@ -88,13 +133,15 @@ var executeCmd = &cobra.Command{
} }
} }
} }
backupDir, err := filepath.Abs(".")
if err != nil { if err != nil {
fmt.Printf("error: %s", err.Error()) fmt.Printf("error: %s", err.Error())
os.Exit(1) os.Exit(1)
} }
pkg.ExecuteBuild(configs) pkg.ExecuteBuild(configs)
pkg.ExecuteInstall(configs) pkg.ExecuteInstall(configs)
_ = ElevatePermission()
os.Chdir(backupDir) os.Chdir(backupDir)
files, err := install.GetPackageFiles(configs.PacketDir) files, err := install.GetPackageFiles(configs.PacketDir)
@@ -108,11 +155,166 @@ var executeCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
if err := database.MarkAsInstalled(pkg, files, configs.PacketDir, pkg.Flags, db, nil, 0); err != nil {
fmt.Printf("error: %s", err.Error())
os.Exit(1)
}
} }
}, },
} }
var removeCmd = &cobra.Command{
Use: "remove {name or id}",
Short: "Removes a package from the system",
Long: "Removes a package from the system",
Args: cobra.MinimumNArgs(1),
PreRun: func(cmd *cobra.Command, args []string) {
GrantPrivilegies()
},
Run: func(cmd *cobra.Command, args []string) {
for _, arg := range args {
db, err := sql.Open("sqlite3", InternalDB)
if err != nil {
fmt.Printf("error: %s\n", err.Error())
os.Exit(1)
}
defer db.Close()
id, err := database.GetPackageId(arg, db)
if err != nil {
if err == sql.ErrNoRows {
fmt.Printf("package %s not found\n", arg)
continue
}
fmt.Printf("error: %s\n", err.Error())
continue
}
files, err := database.GetPackageFiles(id, db)
if err != nil {
fmt.Printf("error: %s\n", err.Error())
continue
}
for _, file := range files {
if !file.IsDir {
if err := os.Remove(file.Filepath); err != nil {
fmt.Printf("error: %s\n", err.Error())
continue
}
}
}
if err := database.MarkAsUninstalled(id.ID, db); err != nil {
fmt.Printf("error removing package from database but successfully removed it from the system: %s\n", err.Error())
continue
}
}
},
}
var devCmd = &cobra.Command{
Use: "dev",
Short: "Develop a package",
Long: "Useful commands for developing packages",
}
var packCmd = &cobra.Command{
Use: "pack",
Short: "Package a directory",
Long: "Package a directory",
Run: func(cmd *cobra.Command, args []string) {
for _, arg := range args {
packetDotLuaBlob, err := os.ReadFile(filepath.Join(arg, "Packet.lua"))
if err != nil {
fmt.Printf("invalid package dir can't find Packet.lua")
continue
}
packet, err := packet.ReadPacket(packetDotLuaBlob, nil)
if err != nil {
fmt.Printf("error: %s\n", err.Error())
continue
}
packageFile, err := os.OpenFile(packet.Name+"@"+packet.Version+".pkt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
fmt.Printf("error: %s\n", err.Error())
continue
}
zstdWriter, err := zstd.NewWriter(packageFile)
if err != nil {
fmt.Printf("error: %s\n", err.Error())
continue
}
defer zstdWriter.Close()
baseDir := filepath.Clean(arg)
tarWriter := tar.NewWriter(zstdWriter)
defer tarWriter.Close()
filepath.Walk(arg, func(path string, info fs.FileInfo, err error) error {
header, err := tar.FileInfoHeader(info, "")
if err != nil {
return err
}
relPath, err := filepath.Rel(baseDir, path)
if err != nil {
return err
}
if relPath == "." {
return nil
}
header.Name = relPath
if err := tarWriter.WriteHeader(header); err != nil {
return err
}
if !info.IsDir() {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
if _, err := io.Copy(tarWriter, file); err != nil {
return err
}
}
return nil
})
}
},
}
var listCmd = &cobra.Command{
Use: "list",
Short: "List all installed packages",
Long: "List all installed packages",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("odasd")
},
}
func main() { func main() {
rootCmd.AddCommand(executeCmd) rootCmd.AddCommand(executeCmd)
rootCmd.AddCommand(removeCmd)
configCmd.Flags().Bool("raw", false, "show config names and dir in stdout")
rootCmd.AddCommand(configCmd)
rootCmd.AddCommand(devCmd)
devCmd.AddCommand(packCmd)
rootCmd.Execute() rootCmd.Execute()
} }

View File

@@ -2,8 +2,9 @@ package main
const ( const (
ConfigurationDir = "/etc/packets" ConfigurationDir = "/etc/packets"
InternalDB = ConfigurationDir + "/internal.db"
HomeDir = "/var/lib/packets" HomeDir = "/var/lib/packets"
PackageRootDir = "_pkgtest" PackageRootDir = "/var/lib/packets/packages"
NumberOfTryAttempts = 4 NumberOfTryAttempts = 4
UserHomeDirPlaceholder = "{{ USER HOME FOLDER }}" UserHomeDirPlaceholder = "{{ USER HOME FOLDER }}"
UsernamePlaceholder = "{{ USERNAME }}" UsernamePlaceholder = "{{ USERNAME }}"

37
cmd/packets/user.go Normal file
View File

@@ -0,0 +1,37 @@
package main
import (
"os/exec"
"strconv"
"strings"
"syscall"
)
func GetPacketsUID() (int, error) {
_ = exec.Command("useradd", "-M", "-N", "-r", "-s", "/bin/false", "-d", "/etc/packets", "packets").Run()
cmd := exec.Command("id", "-u", "packets")
out, err := cmd.CombinedOutput()
if err != nil {
return -1, err
}
s := strings.TrimSpace(string(out))
uid, err := strconv.Atoi(s)
if err != nil {
return -1, err
}
return uid, nil
}
func ChangeToNoPermission() error {
uid, err := GetPacketsUID()
if err != nil {
return err
}
return syscall.Setresuid(0, uid, 0)
}
func ElevatePermission() error { return syscall.Setresuid(0, 0, 0) }

21
go.mod
View File

@@ -5,6 +5,9 @@ go 1.25.3
require github.com/yuin/gopher-lua v1.1.1 require github.com/yuin/gopher-lua v1.1.1
require ( require (
github.com/charmbracelet/bubbles v0.21.0
github.com/charmbracelet/bubbletea v1.3.10
github.com/charmbracelet/lipgloss v1.1.0
github.com/go-git/go-git/v6 v6.0.0-20251029213217-0bbfc0875edd github.com/go-git/go-git/v6 v6.0.0-20251029213217-0bbfc0875edd
github.com/klauspost/compress v1.18.1 github.com/klauspost/compress v1.18.1
github.com/mattn/go-sqlite3 v1.14.32 github.com/mattn/go-sqlite3 v1.14.32
@@ -17,19 +20,37 @@ require (
require ( require (
github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/ProtonMail/go-crypto v1.3.0 // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/x/ansi v0.10.1 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/cloudflare/circl v1.6.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect
github.com/cyphar/filepath-securejoin v0.5.0 // indirect github.com/cyphar/filepath-securejoin v0.5.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/go-git/gcfg/v2 v2.0.2 // indirect github.com/go-git/gcfg/v2 v2.0.2 // indirect
github.com/go-git/go-billy/v6 v6.0.0-20251022185412-61e52df296a5 // indirect github.com/go-git/go-billy/v6 v6.0.0-20251022185412-61e52df296a5 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kevinburke/ssh_config v1.4.0 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/pjbgf/sha1cd v0.5.0 // indirect github.com/pjbgf/sha1cd v0.5.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sahilm/fuzzy v0.1.1 // indirect
github.com/sergi/go-diff v1.4.0 // indirect github.com/sergi/go-diff v1.4.0 // indirect
github.com/spf13/pflag v1.0.9 // indirect github.com/spf13/pflag v1.0.9 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/crypto v0.43.0 // indirect golang.org/x/crypto v0.43.0 // indirect
golang.org/x/net v0.46.0 // indirect golang.org/x/net v0.46.0 // indirect
golang.org/x/sys v0.37.0 // indirect golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
) )

51
go.sum
View File

@@ -6,6 +6,28 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
@@ -18,6 +40,8 @@ github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo= github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo=
@@ -41,8 +65,24 @@ github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs=
github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
@@ -51,7 +91,12 @@ github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0=
github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
@@ -64,12 +109,18 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=

10
main.go
View File

@@ -1,10 +0,0 @@
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println(runtime.GOARCH)
}

View File

@@ -0,0 +1,14 @@
package dependencysolve
import "github.com/roboogg133/packets/pkg/packet.lua.d"
type InstallInstruction struct {
Build []string
Install []string
Conflict []string
}
func ResolveDependencies(dependencies packet.PkgDependencies) InstallInstruction {
// Implementation goes here
return InstallInstruction{}
}

View File

@@ -1,7 +1,6 @@
package install package install
import ( import (
"fmt"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
@@ -45,10 +44,8 @@ func walkAll(dirToWalk string) ([]BasicFileStatus, error) {
} }
func InstallFiles(files []BasicFileStatus, packetDir string) error { func InstallFiles(files []BasicFileStatus, packetDir string) error {
for i, v := range files { for _, v := range files {
sysPath, _ := strings.CutPrefix(v.Filepath, packetDir) sysPath, _ := strings.CutPrefix(v.Filepath, packetDir)
fmt.Printf("[%d] Installing file %s\n", i, v.Filepath)
fmt.Printf("[%d] NEED to track file %s\n", i, sysPath)
if v.IsDir { if v.IsDir {
if err := os.MkdirAll(sysPath, v.PermMode.Perm()); err != nil { if err := os.MkdirAll(sysPath, v.PermMode.Perm()); err != nil {
return err return err

View File

@@ -104,10 +104,15 @@ func getSourcesFromTable(table *lua.LTable, key string) *[]Source {
case "GET": case "GET":
var getSpecs GETSpecs var getSpecs GETSpecs
getSpecs.SHA256 = new(string) getSpecs.SHA256 = new([]string)
sha256sumL := src.RawGetString("sha256") sha256sumL := src.RawGetString("sha256")
if sha256sumL.Type() == lua.LTString { if sha256sumL.Type() == lua.LTTable {
*getSpecs.SHA256 = sha256sumL.String() shatable := sha256sumL.(*lua.LTable)
shatable.ForEach(func(_, value lua.LValue) {
if value.Type() == lua.LTString {
*getSpecs.SHA256 = append(*getSpecs.SHA256, value.String())
}
})
} }
headersLT := src.RawGetString("headers") headersLT := src.RawGetString("headers")
@@ -148,8 +153,13 @@ func getSourcesFromTable(table *lua.LTable, key string) *[]Source {
var postSpecs POSTSpecs var postSpecs POSTSpecs
sha256sumL := src.RawGetString("sha256") sha256sumL := src.RawGetString("sha256")
if sha256sumL.Type() == lua.LTString { if sha256sumL.Type() == lua.LTTable {
*postSpecs.SHA256 = sha256sumL.String() shatable := sha256sumL.(*lua.LTable)
shatable.ForEach(func(_, value lua.LValue) {
if value.Type() == lua.LTString {
*postSpecs.SHA256 = append(*postSpecs.SHA256, value.String())
}
})
} }
headersLT := src.RawGetString("headers") headersLT := src.RawGetString("headers")

View File

@@ -12,6 +12,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"slices"
"time" "time"
"github.com/go-git/go-git/v6" "github.com/go-git/go-git/v6"
@@ -27,9 +28,11 @@ type OperationalSystem string
type PacketLua struct { type PacketLua struct {
Name string Name string
Version string Version string
Maintaner string Maintainer string
Description string Description string
Serial int Serial int
Page string
License []string
Plataforms *map[OperationalSystem]Plataform Plataforms *map[OperationalSystem]Plataform
GlobalSources *[]Source GlobalSources *[]Source
@@ -37,10 +40,9 @@ type PacketLua struct {
Flags []lua_utils.Flag Flags []lua_utils.Flag
Build *lua.LFunction Build *lua.LFunction
Install *lua.LFunction Install *lua.LFunction
PreRemove *lua.LFunction LuaState *lua.LState
LuaState *lua.LState
} }
type Source struct { type Source struct {
@@ -70,13 +72,13 @@ type GitSpecs struct {
} }
type POSTSpecs struct { type POSTSpecs struct {
SHA256 *string SHA256 *[]string
Body *string Body *string
Headers *map[string]string Headers *map[string]string
} }
type GETSpecs struct { type GETSpecs struct {
SHA256 *string SHA256 *[]string
Headers *map[string]string Headers *map[string]string
} }
@@ -133,18 +135,19 @@ func ReadPacket(f []byte, cfg *Config) (PacketLua, error) {
packetLua := &PacketLua{ packetLua := &PacketLua{
Name: getStringFromTable(pkgTable, "name"), Name: getStringFromTable(pkgTable, "name"),
Version: getStringFromTable(pkgTable, "version"), Version: getStringFromTable(pkgTable, "version"),
Maintaner: getStringFromTable(pkgTable, "maintainer"), Maintainer: getStringFromTable(pkgTable, "maintainer"),
Description: getStringFromTable(pkgTable, "description"), Description: getStringFromTable(pkgTable, "description"),
Serial: getIntFromTable(pkgTable, "serial"), Serial: getIntFromTable(pkgTable, "serial"),
Page: getStringFromTable(pkgTable, "pageurl"),
License: getStringArrayFromTable(pkgTable, "LICENSE"),
Plataforms: getPlataformsFromTable(pkgTable, "plataforms"), Plataforms: getPlataformsFromTable(pkgTable, "plataforms"),
GlobalDependencies: getDependenciesFromTable(pkgTable, "build_dependencies"), GlobalDependencies: getDependenciesFromTable(pkgTable, "build_dependencies"),
GlobalSources: getSourcesFromTable(pkgTable, "sources"), GlobalSources: getSourcesFromTable(pkgTable, "sources"),
Build: getFunctionFromTable(table, "build"), Build: getFunctionFromTable(table, "build"),
Install: getFunctionFromTable(table, "install"), Install: getFunctionFromTable(table, "install"),
PreRemove: getFunctionFromTable(table, "pre_remove"),
} }
packetLua.Flags = append(packetLua.Flags, newFlags.Flags...) packetLua.Flags = append(packetLua.Flags, newFlags.Flags...)
@@ -304,11 +307,10 @@ func GetSource(url, method string, info any, tryAttempts int) (any, error) {
return nil, fmt.Errorf("invalid method") return nil, fmt.Errorf("invalid method")
} }
func verifySHA256(checksum string, src []byte) bool { func verifySHA256(checksum []string, src []byte) bool {
check := sha256.Sum256(src) check := sha256.Sum256(src)
return hex.EncodeToString(check[:]) == checksum return slices.Contains(checksum, hex.EncodeToString(check[:]))
} }
func (pkg *PacketLua) ExecuteBuild(cfg *Config) { func (pkg *PacketLua) ExecuteBuild(cfg *Config) {

View File

@@ -1,25 +0,0 @@
package packet
func (pkg PacketLua) IsValid() bool {
var a, b int
for _, v := range *pkg.Plataforms {
a += len(*v.Sources)
b += len(v.Architetures)
}
a += len(*pkg.GlobalSources)
if a < 1 || len(*pkg.Plataforms) > b {
return false
}
switch {
case pkg.Serial == -133:
return false
case pkg.Description == "" || pkg.Maintaner == "" || pkg.Name == "" || pkg.Version == "":
return false
}
return true
}

View File

@@ -2,6 +2,7 @@ package packet
import ( import (
"math/rand" "math/rand"
"strings"
) )
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$%!@%&*()-=+[]{}:;.,1234567890" const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$%!@%&*()-=+[]{}:;.,1234567890"
@@ -13,3 +14,52 @@ func randStringBytes(n int) string {
} }
return string(b) return string(b)
} }
type PackageID struct {
ID string
}
func (id PackageID) Name() string {
return strings.SplitAfter(id.ID, "@")[0]
}
func (id PackageID) Version() string {
return strings.SplitAfter(id.ID, "@")[1]
}
func NewId(id string) PackageID {
var ID PackageID
ID.ID = id
return ID
}
func (pkg PacketLua) IsValid() bool {
var a, b int
for _, v := range *pkg.Plataforms {
for _, src := range *v.Sources {
a++
if src.Method == "git" {
if src.Specs.(GitSpecs).Branch == "" && src.Specs.(GitSpecs).Tag == nil {
return false
}
}
}
b += len(v.Architetures)
}
a += len(*pkg.GlobalSources)
if a < 1 || len(*pkg.Plataforms) > b {
return false
}
switch {
case pkg.Serial == -133:
return false
case pkg.Description == "" || pkg.Maintainer == "" || pkg.Name == "" || pkg.Version == "":
return false
}
return true
}

View File

@@ -4,7 +4,9 @@ return {
version = "0.26.0", -- required version = "0.26.0", -- required
maintainer = "robogg133", -- required maintainer = "robogg133", -- required
description = "A cat(1) clone with syntax highlighting and Git integration.", -- required description = "A cat(1) clone with syntax highlighting and Git integration.", -- required
serial = 0, -- required serial = 0,
LICENSE = {"APACHE", "MIT"},
pageurl = "https://github.com/sharkdp/bat"
plataforms = { plataforms = {
windows = { windows = {
@@ -14,7 +16,7 @@ return {
url = "https://github.com/sharkdp/bat/releases/download/v0.26.0/bat-v0.26.0-" .. url = "https://github.com/sharkdp/bat/releases/download/v0.26.0/bat-v0.26.0-" ..
CURRENT_ARCH_NORMALIZED .. "-pc-windows-msvc.zip", CURRENT_ARCH_NORMALIZED .. "-pc-windows-msvc.zip",
method = "GET", method = "GET",
sha256 = "a8a6862f14698b45e101b0932c69bc47a007f4c0456f3a129fdcef54d443d501" sha256 = { "a8a6862f14698b45e101b0932c69bc47a007f4c0456f3a129fdcef54d443d501" }
} }
}, },
dependencies = { dependencies = {
@@ -30,7 +32,7 @@ return {
url = "https://github.com/sharkdp/bat/releases/download/v0.26.0/bat-v0.26.0-" .. url = "https://github.com/sharkdp/bat/releases/download/v0.26.0/bat-v0.26.0-" ..
CURRENT_ARCH_NORMALIZED .. "-unknown-linux-gnu.tar.gz", CURRENT_ARCH_NORMALIZED .. "-unknown-linux-gnu.tar.gz",
method = "GET", method = "GET",
sha256 = "7efed0c768fae36f18ddbbb4a38f5c4b64db7c55a170dfc89fd380805809a44b" sha256 = { "7efed0c768fae36f18ddbbb4a38f5c4b64db7c55a170dfc89fd380805809a44b" }
} }
}, },
dependencies = { dependencies = {
@@ -56,6 +58,10 @@ return {
if not suc then if not suc then
error("failed to copy bat: " .. errmsg) error("failed to copy bat: " .. errmsg)
end end
os.copy("bat.1", pathjoin(PACKETDIR, "/usr/share/man/man1/bat.1"))
setflags("man", "manual", "/usr/share/man/man1/bat.1")
end, end,
} }

65
test/go/Packet.lua Normal file
View File

@@ -0,0 +1,65 @@
return {
package = {
name = "go",
version = "1.25.3",
maintainer = "robogg133",
description = "A cat(1) clone with syntax highlighting and Git integration.",
serial = 0,
plataforms = {
windows = {
arch = { "amd64" },
sources = {
{
url = "https://github.com/sharkdp/bat/releases/download/v0.26.0/bat-v0.26.0-" ..
CURRENT_ARCH_NORMALIZED .. "-pc-windows-msvc.zip",
method = "GET",
sha256 = "a8a6862f14698b45e101b0932c69bc47a007f4c0456f3a129fdcef54d443d501"
}
},
dependencies = {
build = {},
runtime = {},
conflicts = {}
}
},
linux = {
arch = { "amd64" },
sources = {
{
url = "https://github.com/sharkdp/bat/releases/download/v0.26.0/bat-v0.26.0-" ..
CURRENT_ARCH_NORMALIZED .. "-unknown-linux-gnu.tar.gz",
method = "GET",
sha256 = "7efed0c768fae36f18ddbbb4a38f5c4b64db7c55a170dfc89fd380805809a44b"
}
},
dependencies = {
build = {},
runtime = {},
conflicts = {}
}
}
},
sources = {}
},
build = function()
end,
install = function()
os.chdir(pathjoin(SOURCESDIR, "bat-v0.26.0-" .. CURRENT_ARCH_NORMALIZED .. "-unknown-linux-gnu"))
os.chmod("bat", 755)
local suc, errmsg = os.copy("bat", pathjoin(PACKETDIR, BIN_DIR, "bat"))
if not suc then
error("failed to copy bat: " .. errmsg)
end
os.copy("bat.1", pathjoin(PACKETDIR, "/usr/share/man/man1/bat.1"))
setflags("man", "manual", "/usr/share/man/man1/bat.1")
end,
}

View File

@@ -15,7 +15,7 @@ return {
{ {
url = "https://nginx.org/download/nginx-1.29.3.zip", url = "https://nginx.org/download/nginx-1.29.3.zip",
method = "GET", method = "GET",
sha256 = "afa2fde9fdf0ac64b91a17dcd34100ac557a3ff8e6154eeb0eeae7aa8e5bbc2d" sha256 = { "afa2fde9fdf0ac64b91a17dcd34100ac557a3ff8e6154eeb0eeae7aa8e5bbc2d" }
} }
}, },
dependencies = { dependencies = {
@@ -34,7 +34,8 @@ return {
{ {
url = "https://nginx.org/download/nginx-1.29.3.tar.gz", url = "https://nginx.org/download/nginx-1.29.3.tar.gz",
method = "GET", method = "GET",
sha256 = "9befcced12ee09c2f4e1385d7e8e21c91f1a5a63b196f78f897c2d044b8c9312" sha256 = { "9befcced12ee09c2f4e1385d7e8e21c91f1a5a63b196f78f897c2d044b8c9312" }
} }
}, },
dependencies = { dependencies = {
@@ -75,9 +76,9 @@ return {
install = function() install = function()
local uncompressedname = "nginx-1.29.3" local uncompressedname = "nginx-1.29.3"
os.copy("nginx.service", pathjoin(PACKETDIR, "/etc/systemd/system/nginx.service"))
os.chdir(pathjoin(SOURCESDIR, uncompressedname)) os.chdir(pathjoin(SOURCESDIR, uncompressedname))
os.chmod("objs/nginx", 755) os.chmod("objs/nginx", 755)
os.copy("objs/nginx", pathjoin(PACKETDIR, BIN_DIR, "nginx")) os.copy("objs/nginx", pathjoin(PACKETDIR, BIN_DIR, "nginx"))
os.mkdir(pathjoin(PACKETDIR, "/usr/local/nginx"), 755) os.mkdir(pathjoin(PACKETDIR, "/usr/local/nginx"), 755)
@@ -118,6 +119,9 @@ return {
setflags("config", "main", "/etc/nginx/nginx.conf") setflags("config", "main", "/etc/nginx/nginx.conf")
setflags("config", "sites-available", "/etc/nginx/sites-available") setflags("config", "sites-available", "/etc/nginx/sites-available")
setflags("config", "sites-enabled", "/etc/nginx/sites-enabled") setflags("config", "sites-enabled", "/etc/nginx/sites-enabled")
setflags("man", "nginx.8", "/usr/share/man/man8/nginx.8")
setflags("license", "license", "/usr/share/licenses/nginx/LICENSE")
setflags("systemd", "nginx.service", "/etc/systemd/system/nginx.service")
end, end,
} }

20
test/nginx/nginx.service Normal file
View File

@@ -0,0 +1,20 @@
[Unit]
Description=nginx web server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PrivateDevices=yes
PrivateTmp=true
SyslogLevel=err
ExecStart=/usr/bin/nginx
ExecReload=/usr/bin/nginx -s reload
Restart=on-failure
KillMode=mixed
KillSignal=SIGQUIT
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target