Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33e11856c6 | |||
| 0f944f7a0e | |||
| 223037e7c2 | |||
| acecad7f75 | |||
| 4f82f28c73 | |||
| ae07e0127b | |||
| d2696a6f30 | |||
| 17ba70771c | |||
| 93984f29da | |||
| d7cd746b43 | |||
|
6988c9c4db
|
|||
|
d6e0ed8c76
|
|||
|
53be3309c5
|
|||
|
644dd18a52
|
|||
|
27c6f976df
|
|||
|
279a973633
|
|||
|
9c1b522689
|
|||
|
5c8cd46c02
|
|||
|
2dba550a2b
|
|||
|
8c64812b34
|
|||
|
d1423d980d
|
|||
|
104da0f66a
|
|||
|
d996d9fbb7
|
|||
|
469f97ccc1
|
|||
|
af7a6180a1
|
|||
|
03b5c0e20a
|
|||
|
6a31fb4fa3
|
|||
| b255f07b0f | |||
| dec4cdd068 | |||
| 73c620ecd5 | |||
| 69467a1542 | |||
| 1ae6a35bc8 | |||
| 9ef5b52b85 | |||
| f93158cb3c |
229
cmd/pkgserver/main.go
Normal file
229
cmd/pkgserver/main.go
Normal file
@@ -0,0 +1,229 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmp"
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/command"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/internal/pkg"
|
||||
"hakurei.app/internal/rosa"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
//go:generate sh -c "sass ui/static/dark.scss ui/static/dark.css && sass ui/static/light.scss ui/static/light.css && tsc ui/static/index.ts"
|
||||
//go:embed ui/*
|
||||
var content embed.FS
|
||||
|
||||
func serveWebUI(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Printf("serveWebUI: %s\n", r.URL.Path)
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
w.Header().Set("Expires", "0")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("X-XSS-Protection", "1")
|
||||
w.Header().Set("X-Frame-Options", "DENY")
|
||||
|
||||
http.ServeFileFS(w, r, content, "ui/index.html")
|
||||
}
|
||||
func serveStaticContent(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Printf("serveStaticContent: %s\n", r.URL.Path)
|
||||
switch r.URL.Path {
|
||||
case "/static/style.css":
|
||||
darkTheme := r.CookiesNamed("dark_theme")
|
||||
if len(darkTheme) > 0 && darkTheme[0].Value == "true" {
|
||||
http.ServeFileFS(w, r, content, "ui/static/dark.css")
|
||||
} else {
|
||||
http.ServeFileFS(w, r, content, "ui/static/light.css")
|
||||
}
|
||||
break
|
||||
case "/favicon.ico":
|
||||
http.ServeFileFS(w, r, content, "ui/static/favicon.ico")
|
||||
break
|
||||
case "/static/index.js":
|
||||
http.ServeFileFS(w, r, content, "ui/static/index.js")
|
||||
break
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
|
||||
}
|
||||
}
|
||||
func serveAPI(index *PackageIndex) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func serveStatus(index *PackageIndex) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if index == nil {
|
||||
http.Error(w, "index is nil", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
base := path.Base(r.URL.Path)
|
||||
name := strings.TrimSuffix(base, ".log")
|
||||
p, ok := rosa.ResolveName(name)
|
||||
if !ok {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
m := rosa.GetMetadata(p)
|
||||
pk, ok := index.names[m.Name]
|
||||
if !ok {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
if len(pk.status) > 0 {
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, err := io.Copy(w, bytes.NewReader(pk.status))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
} else {
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type SortOrders int
|
||||
|
||||
const (
|
||||
DeclarationAscending SortOrders = iota
|
||||
DeclarationDescending
|
||||
NameAscending
|
||||
NameDescending
|
||||
limitSortOrders
|
||||
)
|
||||
|
||||
type PackageIndex struct {
|
||||
sorts [limitSortOrders][rosa.PresetUnexportedStart]*PackageIndexEntry
|
||||
names map[string]*PackageIndexEntry
|
||||
}
|
||||
|
||||
type PackageIndexEntry struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Website string `json:"website"`
|
||||
Version string `json:"version"`
|
||||
status []byte
|
||||
}
|
||||
|
||||
func createPackageIndex(cache *pkg.Cache, report *rosa.Report) (_ *PackageIndex, err error) {
|
||||
index := new(PackageIndex)
|
||||
index.names = make(map[string]*PackageIndexEntry, rosa.PresetUnexportedStart)
|
||||
work := make([]PackageIndexEntry, rosa.PresetUnexportedStart)
|
||||
defer report.HandleAccess(&err)()
|
||||
for p := range rosa.PresetUnexportedStart {
|
||||
m := rosa.GetMetadata(p)
|
||||
v := rosa.Std.Version(p)
|
||||
a := rosa.Std.Load(p)
|
||||
id := cache.Ident(a)
|
||||
st, n := report.ArtifactOf(id)
|
||||
var status []byte
|
||||
if n < 1 {
|
||||
status = nil
|
||||
} else {
|
||||
status = st
|
||||
}
|
||||
log.Printf("Processing package %s...\n", m.Name)
|
||||
entry := PackageIndexEntry{
|
||||
Name: m.Name,
|
||||
Description: m.Description,
|
||||
Website: m.Website,
|
||||
Version: v,
|
||||
status: status,
|
||||
}
|
||||
work[p] = entry
|
||||
index.names[m.Name] = &entry
|
||||
}
|
||||
for i, p := range work {
|
||||
index.sorts[DeclarationAscending][i] = &p
|
||||
}
|
||||
slices.Reverse(work)
|
||||
for i, p := range work {
|
||||
index.sorts[DeclarationDescending][i] = &p
|
||||
}
|
||||
slices.SortFunc(work, func(a PackageIndexEntry, b PackageIndexEntry) int {
|
||||
return cmp.Compare(a.Name, b.Name)
|
||||
})
|
||||
for i, p := range work {
|
||||
index.sorts[NameAscending][i] = &p
|
||||
}
|
||||
slices.Reverse(work)
|
||||
for i, p := range work {
|
||||
index.sorts[NameDescending][i] = &p
|
||||
}
|
||||
return index, err
|
||||
}
|
||||
func main() {
|
||||
log.SetFlags(0)
|
||||
log.SetPrefix("pkgserver: ")
|
||||
|
||||
var (
|
||||
flagBaseDir string
|
||||
flagPort int
|
||||
)
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
||||
defer stop()
|
||||
msg := message.New(log.Default())
|
||||
|
||||
c := command.New(os.Stderr, log.Printf, "pkgserver", func(args []string) error {
|
||||
reportPath := args[0]
|
||||
baseDir, err := check.NewAbs(flagBaseDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println("baseDir:", baseDir)
|
||||
cache, err := pkg.Open(ctx, msg, 0, baseDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
report, err := rosa.OpenReport(reportPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println("reportPath:", reportPath)
|
||||
log.Println("indexing packages...")
|
||||
index, err := createPackageIndex(cache, report)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println("created package index")
|
||||
http.HandleFunc("GET /{$}", serveWebUI)
|
||||
http.HandleFunc("GET /favicon.ico", serveStaticContent)
|
||||
http.HandleFunc("GET /static/", serveStaticContent)
|
||||
http.HandleFunc("GET /api/", serveAPI(index))
|
||||
http.HandleFunc("GET /api/status/", serveStatus(index))
|
||||
log.Println("listening on", flagPort)
|
||||
err = http.ListenAndServe(fmt.Sprintf(":%d", flagPort), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}).Flag(
|
||||
&flagBaseDir,
|
||||
"b", command.StringFlag(""),
|
||||
"base directory for cache",
|
||||
).Flag(
|
||||
&flagPort,
|
||||
"p", command.IntFlag(8067),
|
||||
"http listen port",
|
||||
)
|
||||
c.MustParse(os.Args[1:], func(e error) {
|
||||
log.Fatal(e)
|
||||
})
|
||||
|
||||
}
|
||||
26
cmd/pkgserver/ui/index.html
Normal file
26
cmd/pkgserver/ui/index.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="static/style.css">
|
||||
<title>Hakurei PkgServer</title>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||
<script src="static/index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hakurei PkgServer</h1>
|
||||
|
||||
<table id="pkg-list">
|
||||
<tr><th>Status</th><th>Name</th><th>Version</th></tr>
|
||||
</table>
|
||||
<p>Showing entries <span id="entry-counter"></span>.</p>
|
||||
<span class="bottom-nav"><a href="javascript:prevPage()">« Previous</a> <span id="page-number">1</span> <a href="javascript:nextPage()">Next »</a></span>
|
||||
<span><label for="count">Entries per page:</label><select name="count" id="count">
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select></span>
|
||||
</body>
|
||||
<footer>© <a href="https://hakurei.app/">Hakurei</a>. Licensed under the MIT license.</footer>
|
||||
</html>
|
||||
0
cmd/pkgserver/ui/static/_common.scss
Normal file
0
cmd/pkgserver/ui/static/_common.scss
Normal file
6
cmd/pkgserver/ui/static/dark.css
Normal file
6
cmd/pkgserver/ui/static/dark.css
Normal file
@@ -0,0 +1,6 @@
|
||||
@use 'common';
|
||||
html {
|
||||
background-color: #2c2c2c;
|
||||
color: ghostwhite; }
|
||||
|
||||
/*# sourceMappingURL=dark.css.map */
|
||||
7
cmd/pkgserver/ui/static/dark.css.map
Normal file
7
cmd/pkgserver/ui/static/dark.css.map
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAAA,aAAa;AAEb,IAAK;EACH,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,UAAU",
|
||||
"sources": ["dark.scss"],
|
||||
"names": [],
|
||||
"file": "dark.css"
|
||||
}
|
||||
6
cmd/pkgserver/ui/static/dark.scss
Normal file
6
cmd/pkgserver/ui/static/dark.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
@use 'common';
|
||||
|
||||
html {
|
||||
background-color: #2c2c2c;
|
||||
color: ghostwhite;
|
||||
}
|
||||
BIN
cmd/pkgserver/ui/static/favicon.ico
Normal file
BIN
cmd/pkgserver/ui/static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
67
cmd/pkgserver/ui/static/index.js
Normal file
67
cmd/pkgserver/ui/static/index.js
Normal file
@@ -0,0 +1,67 @@
|
||||
"use strict";
|
||||
var PackageEntry = /** @class */ (function () {
|
||||
function PackageEntry() {
|
||||
}
|
||||
return PackageEntry;
|
||||
}());
|
||||
var State = /** @class */ (function () {
|
||||
function State() {
|
||||
this.entriesPerPage = 10;
|
||||
this.currentPage = 1;
|
||||
this.entryIndex = 0;
|
||||
this.loadedEntries = [];
|
||||
}
|
||||
State.prototype.getEntriesPerPage = function () {
|
||||
return this.entriesPerPage;
|
||||
};
|
||||
State.prototype.setEntriesPerPage = function (entriesPerPage) {
|
||||
this.entriesPerPage = entriesPerPage;
|
||||
this.updateRange();
|
||||
};
|
||||
State.prototype.getCurrentPage = function () {
|
||||
return this.currentPage;
|
||||
};
|
||||
State.prototype.setCurrentPage = function (page) {
|
||||
this.currentPage = page;
|
||||
document.getElementById("page-number").innerText = String(this.currentPage);
|
||||
this.updateRange();
|
||||
};
|
||||
State.prototype.getEntryIndex = function () {
|
||||
return this.entryIndex;
|
||||
};
|
||||
State.prototype.setEntryIndex = function (entryIndex) {
|
||||
this.entryIndex = entryIndex;
|
||||
this.updateRange();
|
||||
};
|
||||
State.prototype.getLoadedEntries = function () {
|
||||
return this.loadedEntries;
|
||||
};
|
||||
State.prototype.getMaxPage = function () {
|
||||
return this.loadedEntries.length / this.entriesPerPage;
|
||||
};
|
||||
State.prototype.updateRange = function () {
|
||||
var max = Math.min(this.entryIndex + this.entriesPerPage, this.loadedEntries.length);
|
||||
document.getElementById("entry-counter").innerText = "".concat(this.entryIndex, "-").concat(max, " of ").concat(this.loadedEntries.length);
|
||||
};
|
||||
return State;
|
||||
}());
|
||||
var STATE;
|
||||
function prevPage() {
|
||||
var current = STATE.getCurrentPage();
|
||||
if (current > 1) {
|
||||
STATE.setCurrentPage(STATE.getCurrentPage() - 1);
|
||||
}
|
||||
}
|
||||
function nextPage() {
|
||||
var current = STATE.getCurrentPage();
|
||||
if (current < STATE.getMaxPage()) {
|
||||
STATE.setCurrentPage(STATE.getCurrentPage() + 1);
|
||||
}
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
STATE = new State();
|
||||
STATE.updateRange();
|
||||
document.getElementById("count").addEventListener("change", function (event) {
|
||||
STATE.setEntriesPerPage(parseInt(event.target.value));
|
||||
});
|
||||
});
|
||||
66
cmd/pkgserver/ui/static/index.ts
Normal file
66
cmd/pkgserver/ui/static/index.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
"use strict"
|
||||
|
||||
class PackageEntry {
|
||||
|
||||
}
|
||||
class State {
|
||||
entriesPerPage: number = 10
|
||||
currentPage: number = 1
|
||||
entryIndex: number = 0
|
||||
loadedEntries: PackageEntry[] = []
|
||||
getEntriesPerPage(): number {
|
||||
return this.entriesPerPage
|
||||
}
|
||||
setEntriesPerPage(entriesPerPage: number) {
|
||||
this.entriesPerPage = entriesPerPage
|
||||
this.updateRange()
|
||||
}
|
||||
getCurrentPage(): number {
|
||||
return this.currentPage
|
||||
}
|
||||
setCurrentPage(page: number) {
|
||||
this.currentPage = page
|
||||
document.getElementById("page-number").innerText = String(this.currentPage)
|
||||
this.updateRange()
|
||||
}
|
||||
getEntryIndex(): number {
|
||||
return this.entryIndex
|
||||
}
|
||||
setEntryIndex(entryIndex: number) {
|
||||
this.entryIndex = entryIndex
|
||||
this.updateRange()
|
||||
}
|
||||
getLoadedEntries(): PackageEntry[] {
|
||||
return this.loadedEntries
|
||||
}
|
||||
getMaxPage(): number {
|
||||
return this.loadedEntries.length / this.entriesPerPage
|
||||
}
|
||||
updateRange() {
|
||||
let max = Math.min(this.entryIndex + this.entriesPerPage, this.loadedEntries.length)
|
||||
document.getElementById("entry-counter").innerText = `${this.entryIndex}-${max} of ${this.loadedEntries.length}`
|
||||
}
|
||||
}
|
||||
|
||||
let STATE: State
|
||||
|
||||
function prevPage() {
|
||||
let current = STATE.getCurrentPage()
|
||||
if (current > 1) {
|
||||
STATE.setCurrentPage(STATE.getCurrentPage() - 1)
|
||||
}
|
||||
}
|
||||
function nextPage() {
|
||||
let current = STATE.getCurrentPage()
|
||||
if (current < STATE.getMaxPage()) {
|
||||
STATE.setCurrentPage(STATE.getCurrentPage() + 1)
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
STATE = new State()
|
||||
STATE.updateRange()
|
||||
document.getElementById("count").addEventListener("change", (event) => {
|
||||
STATE.setEntriesPerPage(parseInt((event.target as HTMLSelectElement).value))
|
||||
})
|
||||
})
|
||||
6
cmd/pkgserver/ui/static/light.css
Normal file
6
cmd/pkgserver/ui/static/light.css
Normal file
@@ -0,0 +1,6 @@
|
||||
@use 'common';
|
||||
html {
|
||||
background-color: #d3d3d3;
|
||||
color: black; }
|
||||
|
||||
/*# sourceMappingURL=light.css.map */
|
||||
7
cmd/pkgserver/ui/static/light.css.map
Normal file
7
cmd/pkgserver/ui/static/light.css.map
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAAA,aAAa;AAEb,IAAK;EACH,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,KAAK",
|
||||
"sources": ["light.scss"],
|
||||
"names": [],
|
||||
"file": "light.css"
|
||||
}
|
||||
6
cmd/pkgserver/ui/static/light.scss
Normal file
6
cmd/pkgserver/ui/static/light.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
@use 'common';
|
||||
|
||||
html {
|
||||
background-color: #d3d3d3;
|
||||
color: black;
|
||||
}
|
||||
0
internal/azalea/azalea.bnf
Normal file
0
internal/azalea/azalea.bnf
Normal file
69
internal/azalea/azalea.go
Normal file
69
internal/azalea/azalea.go
Normal file
@@ -0,0 +1,69 @@
|
||||
//go:generate gocc -a azalea.bnf
|
||||
package azalea
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
Generator
|
||||
}
|
||||
|
||||
func NewParser(gen Generator) *Parser {
|
||||
return &Parser{
|
||||
Generator: gen,
|
||||
}
|
||||
}
|
||||
func (p Parser) Initialise() {
|
||||
|
||||
}
|
||||
|
||||
func (p Parser) Consume(ns string, file io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ConsumeDir walks a directory and consumes all Azalea source files within it and all its subdirectories, as long as they end with the .az extension.
|
||||
func (p Parser) ConsumeDir(dir *check.Absolute) error {
|
||||
ds := dir.String()
|
||||
return filepath.WalkDir(ds, func(path string, d fs.DirEntry, err error) (e error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.IsDir() || !strings.HasSuffix(d.Name(), ".az") {
|
||||
return
|
||||
}
|
||||
rel, e := filepath.Rel(ds, path)
|
||||
ns := strings.TrimSuffix(rel, ".az")
|
||||
f, e := os.Open(path)
|
||||
return p.Consume(ns, f)
|
||||
})
|
||||
}
|
||||
|
||||
// ConsumeAll consumes all provided readers as Azalea source code, each given the namespace `r%d` where `%d` is the index of the reader in the provided arguments.
|
||||
func (p Parser) ConsumeAll(in ...io.Reader) error {
|
||||
for i, r := range in {
|
||||
err := p.Consume("r"+strconv.FormatInt(int64(i), 10), r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ConsumeStrings consumes all provided strings as Azalea source code, each given the namespace `s%d` where `%d` is the index of the string in the provided arugments.
|
||||
func (p Parser) ConsumeStrings(in ...string) error {
|
||||
for i, s := range in {
|
||||
err := p.Consume("s"+strconv.FormatInt(int64(i), 10), strings.NewReader(s))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
36
internal/azalea/generator.go
Normal file
36
internal/azalea/generator.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package azalea
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type Generator interface {
|
||||
Finalise() (error, io.Writer)
|
||||
}
|
||||
|
||||
type JsonGenerator struct {
|
||||
t any
|
||||
}
|
||||
|
||||
func NewJsonGenerator[T any]() JsonGenerator {
|
||||
t := new(T)
|
||||
|
||||
return JsonGenerator{
|
||||
t,
|
||||
}
|
||||
}
|
||||
|
||||
func (j *JsonGenerator) Finalise() (error, io.Writer) {
|
||||
|
||||
}
|
||||
|
||||
type PkgIRGenerator struct {
|
||||
}
|
||||
|
||||
func NewPkgIRGenerator() PkgIRGenerator {
|
||||
return PkgIRGenerator{}
|
||||
}
|
||||
|
||||
func (p *PkgIRGenerator) Finalise() (error, io.Writer) {
|
||||
|
||||
}
|
||||
@@ -19,6 +19,8 @@ const (
|
||||
LLVMRuntimes
|
||||
LLVMClang
|
||||
|
||||
// EarlyInit is the Rosa OS initramfs init program.
|
||||
EarlyInit
|
||||
// ImageInitramfs is the Rosa OS initramfs archive.
|
||||
ImageInitramfs
|
||||
|
||||
@@ -28,6 +30,8 @@ const (
|
||||
KernelHeaders
|
||||
// KernelSource is a writable kernel source tree installed to [AbsUsrSrc].
|
||||
KernelSource
|
||||
// Firmware is firmware blobs for use with the Linux kernel.
|
||||
Firmware
|
||||
|
||||
ACL
|
||||
ArgpStandalone
|
||||
@@ -85,9 +89,11 @@ const (
|
||||
NSS
|
||||
NSSCACert
|
||||
Ncurses
|
||||
Nettle
|
||||
Ninja
|
||||
OpenSSL
|
||||
PCRE2
|
||||
Parallel
|
||||
Patch
|
||||
Perl
|
||||
PerlLocaleGettext
|
||||
@@ -103,12 +109,23 @@ const (
|
||||
PkgConfig
|
||||
Procps
|
||||
Python
|
||||
PythonCfgv
|
||||
PythonDiscovery
|
||||
PythonDistlib
|
||||
PythonFilelock
|
||||
PythonIdentify
|
||||
PythonIniConfig
|
||||
PythonNodeenv
|
||||
PythonPackaging
|
||||
PythonPlatformdirs
|
||||
PythonPluggy
|
||||
PythonPreCommit
|
||||
PythonPyTest
|
||||
PythonPyYAML
|
||||
PythonPygments
|
||||
PythonVirtualenv
|
||||
QEMU
|
||||
Rdfind
|
||||
Rsync
|
||||
Sed
|
||||
Setuptools
|
||||
|
||||
@@ -128,6 +128,9 @@ type CMakeHelper struct {
|
||||
Cache [][2]string
|
||||
// Runs after install.
|
||||
Script string
|
||||
|
||||
// Whether to generate Makefile instead.
|
||||
Make bool
|
||||
}
|
||||
|
||||
var _ Helper = new(CMakeHelper)
|
||||
@@ -141,7 +144,10 @@ func (attr *CMakeHelper) name(name, version string) string {
|
||||
}
|
||||
|
||||
// extra returns a hardcoded slice of [CMake] and [Ninja].
|
||||
func (*CMakeHelper) extra(int) []PArtifact {
|
||||
func (attr *CMakeHelper) extra(int) []PArtifact {
|
||||
if attr != nil && attr.Make {
|
||||
return []PArtifact{CMake, Make}
|
||||
}
|
||||
return []PArtifact{CMake, Ninja}
|
||||
}
|
||||
|
||||
@@ -173,11 +179,19 @@ func (attr *CMakeHelper) script(name string) string {
|
||||
panic("CACHE must be non-empty")
|
||||
}
|
||||
|
||||
generate := "Ninja"
|
||||
jobs := ""
|
||||
if attr.Make {
|
||||
generate = "'Unix Makefiles'"
|
||||
jobs += ` "--parallel=$(nproc)"`
|
||||
}
|
||||
|
||||
return `
|
||||
cmake -G Ninja \
|
||||
cmake -G ` + generate + ` \
|
||||
-DCMAKE_C_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
||||
-DCMAKE_CXX_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
||||
-DCMAKE_ASM_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||
` + strings.Join(slices.Collect(func(yield func(string) bool) {
|
||||
for _, v := range attr.Cache {
|
||||
if !yield("-D" + v[0] + "=" + v[1]) {
|
||||
@@ -185,9 +199,9 @@ cmake -G Ninja \
|
||||
}
|
||||
}
|
||||
}), " \\\n\t") + ` \
|
||||
-DCMAKE_INSTALL_PREFIX=/work/system \
|
||||
-DCMAKE_INSTALL_PREFIX=/system \
|
||||
'/usr/src/` + name + `/` + path.Join(attr.Append...) + `'
|
||||
cmake --build .
|
||||
cmake --install .
|
||||
cmake --build .` + jobs + `
|
||||
cmake --install . --prefix=/work/system
|
||||
` + attr.Script
|
||||
}
|
||||
|
||||
@@ -678,8 +678,8 @@ func init() {
|
||||
|
||||
func (t Toolchain) newLibiconv() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.18"
|
||||
checksum = "iV5q3VxP5VPdJ-X7O5OQI4fGm8VjeYb5viLd1L3eAHg26bbHb2_Qn63XPF3ucVZr"
|
||||
version = "1.19"
|
||||
checksum = "UibB6E23y4MksNqYmCCrA3zTFO6vJugD1DEDqqWYFZNuBsUWMVMcncb_5pPAr88x"
|
||||
)
|
||||
return t.NewPackage("libiconv", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/libiconv/libiconv-"+version+".tar.gz",
|
||||
@@ -741,6 +741,31 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newParallel() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "20260222"
|
||||
checksum = "4wxjMi3G2zMxr9hvLcIn6D7_12A3e5UNObeTPhzn7mDAYwsZApmmkxfGPyllQQ7E"
|
||||
)
|
||||
return t.NewPackage("parallel", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/parallel/parallel-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
pkg.TarBzip2,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
Perl,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Parallel] = Metadata{
|
||||
f: Toolchain.newParallel,
|
||||
|
||||
Name: "parallel",
|
||||
Description: "a shell tool for executing jobs in parallel using one or more computers",
|
||||
Website: "https://www.gnu.org/software/parallel/",
|
||||
|
||||
ID: 5448,
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newBinutils() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "2.46.0"
|
||||
|
||||
@@ -2,7 +2,19 @@ package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newHakurei(suffix, script string) pkg.Artifact {
|
||||
func (t Toolchain) newHakurei(
|
||||
suffix, script string,
|
||||
withHostname bool,
|
||||
) pkg.Artifact {
|
||||
hostname := `
|
||||
echo '# Building test helper (hostname).'
|
||||
go build -v -o /bin/hostname /usr/src/hostname/main.go
|
||||
echo
|
||||
`
|
||||
if !withHostname {
|
||||
hostname = ""
|
||||
}
|
||||
|
||||
return t.New("hakurei"+suffix+"-"+hakureiVersion, 0, []pkg.Artifact{
|
||||
t.Load(Go),
|
||||
|
||||
@@ -29,17 +41,12 @@ func (t Toolchain) newHakurei(suffix, script string) pkg.Artifact {
|
||||
"CGO_ENABLED=1",
|
||||
"GOCACHE=/tmp/gocache",
|
||||
"CC=clang -O3 -Werror",
|
||||
}, `
|
||||
echo '# Building test helper (hostname).'
|
||||
go build -v -o /bin/hostname /usr/src/hostname/main.go
|
||||
echo
|
||||
|
||||
chmod -R +w /usr/src/hakurei
|
||||
}, hostname+`
|
||||
cd /usr/src/hakurei
|
||||
|
||||
HAKUREI_VERSION='v`+hakureiVersion+`'
|
||||
`+script, pkg.Path(AbsUsrSrc.Append("hakurei"), true, t.NewPatchedSource(
|
||||
"hakurei", hakureiVersion, hakureiSource, true, hakureiPatches...,
|
||||
"hakurei", hakureiVersion, hakureiSource, false, hakureiPatches...,
|
||||
)), pkg.Path(AbsUsrSrc.Append("hostname", "main.go"), false, pkg.NewFile(
|
||||
"hostname.go",
|
||||
[]byte(`
|
||||
@@ -69,10 +76,11 @@ go build -trimpath -v -o /work/system/libexec/hakurei -ldflags="-s -w
|
||||
-buildid=
|
||||
-linkmode external
|
||||
-extldflags=-static
|
||||
-X hakurei.app/internal/info.buildVersion="$HAKUREI_VERSION"
|
||||
-X hakurei.app/internal/info.buildVersion=${HAKUREI_VERSION}
|
||||
-X hakurei.app/internal/info.hakureiPath=/system/bin/hakurei
|
||||
-X hakurei.app/internal/info.hsuPath=/system/bin/hsu
|
||||
-X main.hakureiPath=/system/bin/hakurei" ./...
|
||||
-X main.hakureiPath=/system/bin/hakurei
|
||||
" ./...
|
||||
echo
|
||||
|
||||
echo '# Testing hakurei.'
|
||||
@@ -84,7 +92,7 @@ mkdir -p /work/system/bin/
|
||||
hakurei \
|
||||
sharefs \
|
||||
../../bin/)
|
||||
`), hakureiVersion
|
||||
`, true), hakureiVersion
|
||||
},
|
||||
|
||||
Name: "hakurei",
|
||||
@@ -98,7 +106,7 @@ mkdir -p /work/system/bin/
|
||||
return t.newHakurei("-dist", `
|
||||
export HAKUREI_VERSION
|
||||
DESTDIR=/work /usr/src/hakurei/dist/release.sh
|
||||
`), hakureiVersion
|
||||
`, true), hakureiVersion
|
||||
},
|
||||
|
||||
Name: "hakurei-dist",
|
||||
|
||||
@@ -4,48 +4,15 @@ package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
const hakureiVersion = "0.3.5"
|
||||
const hakureiVersion = "0.3.6"
|
||||
|
||||
// hakureiSource is the source code of a hakurei release.
|
||||
var hakureiSource = pkg.NewHTTPGetTar(
|
||||
nil, "https://git.gensokyo.uk/security/hakurei/archive/"+
|
||||
"v"+hakureiVersion+".tar.gz",
|
||||
mustDecode("6Tn38NLezRD2d3aGdFg5qFfqn8_KvC6HwMKwJMPvaHmVw8xRgxn8B0PObswl2mOk"),
|
||||
mustDecode("Yul9J2yV0x453lQP9KUnG_wEJo_DbKMNM7xHJGt4rITCSeX9VRK2J4kzAxcv_0-b"),
|
||||
pkg.TarGzip,
|
||||
)
|
||||
|
||||
// hakureiPatches are patches applied against a hakurei release.
|
||||
var hakureiPatches = [][2]string{
|
||||
{"createTemp-error-injection", `diff --git a/container/dispatcher_test.go b/container/dispatcher_test.go
|
||||
index 5de37fc..fe0c4db 100644
|
||||
--- a/container/dispatcher_test.go
|
||||
+++ b/container/dispatcher_test.go
|
||||
@@ -238,8 +238,11 @@ func sliceAddr[S any](s []S) *[]S { return &s }
|
||||
|
||||
func newCheckedFile(t *testing.T, name, wantData string, closeErr error) osFile {
|
||||
f := &checkedOsFile{t: t, name: name, want: wantData, closeErr: closeErr}
|
||||
- // check happens in Close, and cleanup is not guaranteed to run, so relying on it for sloppy implementations will cause sporadic test results
|
||||
- f.cleanup = runtime.AddCleanup(f, func(name string) { f.t.Fatalf("checkedOsFile %s became unreachable without a call to Close", name) }, f.name)
|
||||
+ // check happens in Close, and cleanup is not guaranteed to run, so relying
|
||||
+ // on it for sloppy implementations will cause sporadic test results
|
||||
+ f.cleanup = runtime.AddCleanup(f, func(name string) {
|
||||
+ panic("checkedOsFile " + name + " became unreachable without a call to Close")
|
||||
+ }, name)
|
||||
return f
|
||||
}
|
||||
|
||||
diff --git a/container/initplace_test.go b/container/initplace_test.go
|
||||
index afeddbe..1c2f20b 100644
|
||||
--- a/container/initplace_test.go
|
||||
+++ b/container/initplace_test.go
|
||||
@@ -21,7 +21,7 @@ func TestTmpfileOp(t *testing.T) {
|
||||
Path: samplePath,
|
||||
Data: sampleData,
|
||||
}, nil, nil, []stub.Call{
|
||||
- call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), stub.UniqueError(5)),
|
||||
+ call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, (*checkedOsFile)(nil), stub.UniqueError(5)),
|
||||
}, stub.UniqueError(5)},
|
||||
|
||||
{"Write", &Params{ParentPerm: 0700}, &TmpfileOp{
|
||||
`},
|
||||
}
|
||||
var hakureiPatches [][2]string
|
||||
|
||||
@@ -2,10 +2,32 @@ package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func init() {
|
||||
artifactsM[EarlyInit] = Metadata{
|
||||
Name: "earlyinit",
|
||||
Description: "Rosa OS initramfs init program",
|
||||
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
return t.newHakurei("-early-init", `
|
||||
mkdir -p /work/system/libexec/hakurei/
|
||||
|
||||
echo '# Building earlyinit.'
|
||||
go build -trimpath -v -o /work/system/libexec/hakurei -ldflags="-s -w
|
||||
-buildid=
|
||||
-linkmode external
|
||||
-extldflags=-static
|
||||
-X hakurei.app/internal/info.buildVersion=${HAKUREI_VERSION}
|
||||
" ./cmd/earlyinit
|
||||
echo
|
||||
`, false), Unversioned
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newImageInitramfs() (pkg.Artifact, string) {
|
||||
return t.New("initramfs", TNoToolchain, []pkg.Artifact{
|
||||
t.Load(Zstd),
|
||||
t.Load(Hakurei),
|
||||
t.Load(EarlyInit),
|
||||
t.Load(GenInitCPIO),
|
||||
}, nil, nil, `
|
||||
gen_init_cpio -t 4294967295 -c /usr/src/initramfs | zstd > /work/initramfs.zst
|
||||
|
||||
@@ -1272,3 +1272,55 @@ func init() {
|
||||
Description: "a program in the kernel source tree for creating initramfs archive",
|
||||
}
|
||||
}
|
||||
|
||||
func (t Toolchain) newFirmware() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "20260221"
|
||||
checksum = "vTENPW5rZ6yLVq7YKDLHkCVgKXvwUWigEx7T4LcxoKeBVYIyf1_sEExeV4mo-e46"
|
||||
)
|
||||
return t.NewPackage("firmware", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://gitlab.com/kernel-firmware/linux-firmware/-/"+
|
||||
"archive/"+version+"/linux-firmware-"+version+".tar.bz2",
|
||||
mustDecode(checksum),
|
||||
pkg.TarBzip2,
|
||||
), &PackageAttr{
|
||||
// dedup creates temporary file
|
||||
Writable: true,
|
||||
// does not use configure
|
||||
EnterSource: true,
|
||||
|
||||
Env: []string{
|
||||
"HOME=/proc/nonexistent",
|
||||
},
|
||||
}, &MakeHelper{
|
||||
OmitDefaults: true,
|
||||
SkipConfigure: true,
|
||||
InPlace: true,
|
||||
|
||||
Make: []string{
|
||||
"DESTDIR=/work/system",
|
||||
"install-zst",
|
||||
},
|
||||
SkipCheck: true, // requires pre-commit
|
||||
Install: `make "-j$(nproc)" DESTDIR=/work/system dedup`,
|
||||
},
|
||||
Perl,
|
||||
Parallel,
|
||||
Nettle,
|
||||
Rdfind,
|
||||
Zstd,
|
||||
Findutils,
|
||||
Coreutils,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Firmware] = Metadata{
|
||||
f: Toolchain.newFirmware,
|
||||
|
||||
Name: "firmware",
|
||||
Description: "firmware blobs for use with the Linux kernel",
|
||||
Website: "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/",
|
||||
|
||||
ID: 141464,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm64 6.12.73 Kernel Configuration
|
||||
# Linux/arm64 6.12.76 Kernel Configuration
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="clang version 21.1.8"
|
||||
CONFIG_CC_VERSION_TEXT="clang version 22.1.0"
|
||||
CONFIG_GCC_VERSION=0
|
||||
CONFIG_CC_IS_CLANG=y
|
||||
CONFIG_CLANG_VERSION=210108
|
||||
CONFIG_CLANG_VERSION=220100
|
||||
CONFIG_AS_IS_LLVM=y
|
||||
CONFIG_AS_VERSION=210108
|
||||
CONFIG_AS_VERSION=220100
|
||||
CONFIG_LD_VERSION=0
|
||||
CONFIG_LD_IS_LLD=y
|
||||
CONFIG_LLD_VERSION=210108
|
||||
CONFIG_LLD_VERSION=220100
|
||||
CONFIG_RUSTC_VERSION=0
|
||||
CONFIG_RUSTC_LLVM_VERSION=0
|
||||
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
|
||||
@@ -4984,7 +4984,7 @@ CONFIG_SERIAL_TEGRA_TCU=m
|
||||
CONFIG_SERIAL_MAX3100=m
|
||||
CONFIG_SERIAL_MAX310X=m
|
||||
CONFIG_SERIAL_IMX=m
|
||||
CONFIG_SERIAL_IMX_CONSOLE=m
|
||||
# CONFIG_SERIAL_IMX_CONSOLE is not set
|
||||
CONFIG_SERIAL_IMX_EARLYCON=y
|
||||
CONFIG_SERIAL_UARTLITE=m
|
||||
CONFIG_SERIAL_UARTLITE_NR_UARTS=1
|
||||
@@ -5772,6 +5772,7 @@ CONFIG_GPIO_MADERA=m
|
||||
CONFIG_GPIO_MAX77650=m
|
||||
CONFIG_GPIO_PMIC_EIC_SPRD=m
|
||||
CONFIG_GPIO_SL28CPLD=m
|
||||
CONFIG_GPIO_TN48M_CPLD=m
|
||||
CONFIG_GPIO_TPS65086=m
|
||||
CONFIG_GPIO_TPS65218=m
|
||||
CONFIG_GPIO_TPS65219=m
|
||||
@@ -6471,6 +6472,7 @@ CONFIG_MFD_MAX5970=m
|
||||
# CONFIG_MFD_CS47L85 is not set
|
||||
# CONFIG_MFD_CS47L90 is not set
|
||||
# CONFIG_MFD_CS47L92 is not set
|
||||
CONFIG_MFD_TN48M_CPLD=m
|
||||
# CONFIG_MFD_DA9052_SPI is not set
|
||||
CONFIG_MFD_DA9062=m
|
||||
CONFIG_MFD_DA9063=m
|
||||
@@ -12532,6 +12534,7 @@ CONFIG_RESET_SUNXI=y
|
||||
CONFIG_RESET_TI_SCI=m
|
||||
CONFIG_RESET_TI_SYSCON=m
|
||||
CONFIG_RESET_TI_TPS380X=m
|
||||
CONFIG_RESET_TN48M_CPLD=m
|
||||
CONFIG_RESET_UNIPHIER=m
|
||||
CONFIG_RESET_UNIPHIER_GLUE=m
|
||||
CONFIG_RESET_ZYNQMP=y
|
||||
@@ -14022,7 +14025,6 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
|
||||
# CONFIG_DEBUG_IRQFLAGS is not set
|
||||
CONFIG_STACKTRACE=y
|
||||
# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
|
||||
# CONFIG_DEBUG_KOBJECT is not set
|
||||
|
||||
#
|
||||
@@ -14057,7 +14059,7 @@ CONFIG_USER_STACKTRACE_SUPPORT=y
|
||||
CONFIG_NOP_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_GRAPH_RETVAL=y
|
||||
CONFIG_HAVE_FUNCTION_GRAPH_FREGS=y
|
||||
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y
|
||||
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||
|
||||
@@ -23,6 +23,7 @@ func (t Toolchain) newLibxslt() (pkg.Artifact, string) {
|
||||
SkipCheck: true,
|
||||
},
|
||||
XZ,
|
||||
Zlib,
|
||||
Python,
|
||||
PkgConfig,
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ ln -s ld.lld /work/system/bin/ld
|
||||
Append: cmakeAppend,
|
||||
Script: script + attr.script,
|
||||
},
|
||||
Zlib,
|
||||
Libffi,
|
||||
Python,
|
||||
Perl,
|
||||
|
||||
@@ -13,6 +13,7 @@ func (t Toolchain) newMeson() (pkg.Artifact, string) {
|
||||
checksum = "w895BXF_icncnXatT_OLCFe2PYEtg4KrKooMgUYdN-nQVvbFX3PvYWHGEpogsHtd"
|
||||
)
|
||||
return t.New("meson-"+version, 0, []pkg.Artifact{
|
||||
t.Load(Zlib),
|
||||
t.Load(Python),
|
||||
t.Load(Setuptools),
|
||||
}, nil, nil, `
|
||||
@@ -66,6 +67,7 @@ func (*MesonHelper) name(name, version string) string {
|
||||
// extra returns hardcoded meson runtime dependencies.
|
||||
func (*MesonHelper) extra(int) []PArtifact {
|
||||
return []PArtifact{
|
||||
Zlib,
|
||||
Python,
|
||||
Meson,
|
||||
Ninja,
|
||||
|
||||
31
internal/rosa/nettle.go
Normal file
31
internal/rosa/nettle.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newNettle() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "4.0"
|
||||
checksum = "6agC-vHzzoqAlaX3K9tX8yHgrm03HLqPZzVzq8jh_ePbuPMIvpxereu_uRJFmQK7"
|
||||
)
|
||||
return t.NewPackage("nettle", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://ftpmirror.gnu.org/gnu/nettle/nettle-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
), nil, (*MakeHelper)(nil),
|
||||
M4,
|
||||
Diffutils,
|
||||
|
||||
GMP,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Nettle] = Metadata{
|
||||
f: Toolchain.newNettle,
|
||||
|
||||
Name: "nettle",
|
||||
Description: "a low-level cryptographic library",
|
||||
Website: "https://www.lysator.liu.se/~nisse/nettle/",
|
||||
|
||||
ID: 2073,
|
||||
}
|
||||
}
|
||||
@@ -75,10 +75,10 @@ func init() {
|
||||
|
||||
// newViaPip is a helper for installing python dependencies via pip.
|
||||
func newViaPip(
|
||||
name, description, version, abi, platform, checksum, prefix string,
|
||||
name, description, version, interpreter, abi, platform, checksum, prefix string,
|
||||
extra ...PArtifact,
|
||||
) Metadata {
|
||||
wname := name + "-" + version + "-py3-" + abi + "-" + platform + ".whl"
|
||||
wname := name + "-" + version + "-" + interpreter + "-" + abi + "-" + platform + ".whl"
|
||||
return Metadata{
|
||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||
extraRes := make([]pkg.Artifact, len(extra))
|
||||
@@ -87,6 +87,7 @@ func newViaPip(
|
||||
}
|
||||
|
||||
return t.New(name+"-"+version, 0, slices.Concat([]pkg.Artifact{
|
||||
t.Load(Zlib),
|
||||
t.Load(Python),
|
||||
}, extraRes), nil, nil, `
|
||||
pip3 install \
|
||||
@@ -112,6 +113,7 @@ func (t Toolchain) newSetuptools() (pkg.Artifact, string) {
|
||||
checksum = "K9f8Yi7Gg95zjmQsE1LLw9UBb8NglI6EY6pQpdD6DM0Pmc_Td5w2qs1SMngTI6Jp"
|
||||
)
|
||||
return t.New("setuptools-"+version, 0, []pkg.Artifact{
|
||||
t.Load(Zlib),
|
||||
t.Load(Python),
|
||||
}, nil, nil, `
|
||||
pip3 install \
|
||||
@@ -142,7 +144,7 @@ func init() {
|
||||
artifactsM[PythonPygments] = newViaPip(
|
||||
"pygments",
|
||||
" a syntax highlighting package written in Python",
|
||||
"2.19.2", "none", "any",
|
||||
"2.19.2", "py3", "none", "any",
|
||||
"ak_lwTalmSr7W4Mjy2XBZPG9I6a0gwSy2pS87N8x4QEuZYif0ie9z0OcfRfi9msd",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/",
|
||||
@@ -151,7 +153,7 @@ func init() {
|
||||
artifactsM[PythonPluggy] = newViaPip(
|
||||
"pluggy",
|
||||
"the core framework used by the pytest, tox, and devpi projects",
|
||||
"1.6.0", "none", "any",
|
||||
"1.6.0", "py3", "none", "any",
|
||||
"2HWYBaEwM66-y1hSUcWI1MyE7dVVuNNRW24XD6iJBey4YaUdAK8WeXdtFMQGC-4J",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/",
|
||||
@@ -160,7 +162,7 @@ func init() {
|
||||
artifactsM[PythonPackaging] = newViaPip(
|
||||
"packaging",
|
||||
"reusable core utilities for various Python Packaging interoperability specifications",
|
||||
"26.0", "none", "any",
|
||||
"26.0", "py3", "none", "any",
|
||||
"iVVXcqdwHDskPKoCFUlh2x8J0Gyq-bhO4ns9DvUJ7oJjeOegRYtSIvLV33Bki-pP",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/",
|
||||
@@ -169,15 +171,16 @@ func init() {
|
||||
artifactsM[PythonIniConfig] = newViaPip(
|
||||
"iniconfig",
|
||||
"a small and simple INI-file parser module",
|
||||
"2.3.0", "none", "any",
|
||||
"2.3.0", "py3", "none", "any",
|
||||
"SDgs4S5bXi77aVOeKTPv2TUrS3M9rduiK4DpU0hCmDsSBWqnZcWInq9lsx6INxut",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/",
|
||||
)
|
||||
|
||||
artifactsM[PythonPyTest] = newViaPip(
|
||||
"pytest",
|
||||
"the pytest framework",
|
||||
"9.0.2", "none", "any",
|
||||
"9.0.2", "py3", "none", "any",
|
||||
"IM2wDbLke1EtZhF92zvAjUl_Hms1uKDtM7U8Dt4acOaChMnDg1pW7ib8U0wYGDLH",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/",
|
||||
@@ -186,4 +189,109 @@ func init() {
|
||||
PythonPluggy,
|
||||
PythonPygments,
|
||||
)
|
||||
|
||||
artifactsM[PythonCfgv] = newViaPip(
|
||||
"cfgv",
|
||||
"validate configuration and produce human readable error messages",
|
||||
"3.5.0", "py2.py3", "none", "any",
|
||||
"yFKTyVRlmnLKAxvvge15kAd_GOP1Xh3fZ0NFImO5pBdD5e0zj3GRmA6Q1HdtLTYO",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/",
|
||||
)
|
||||
|
||||
artifactsM[PythonIdentify] = newViaPip(
|
||||
"identify",
|
||||
"file identification library for Python",
|
||||
"2.6.17", "py2.py3", "none", "any",
|
||||
"9RxK3igO-Pxxof5AuCAGiF_L1SWi4SpuSF1fWNXCzE2D4oTRSob-9VpFMLlybrSv",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/",
|
||||
)
|
||||
|
||||
artifactsM[PythonNodeenv] = newViaPip(
|
||||
"nodeenv",
|
||||
"a tool to create isolated node.js environments",
|
||||
"1.10.0", "py2.py3", "none", "any",
|
||||
"ihUb4-WQXYIhYOOKSsXlKIzjzQieOYl6ojro9H-0DFzGheaRTtuyZgsCmriq58sq",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/",
|
||||
)
|
||||
|
||||
artifactsM[PythonPyYAML] = newViaPip(
|
||||
"pyyaml",
|
||||
"a complete YAML 1.1 parser",
|
||||
"6.0.3", "cp314", "cp314", "musllinux_1_2_x86_64",
|
||||
"4_jhCFpUNtyrFp2HOMqUisR005u90MHId53eS7rkUbcGXkoaJ7JRsY21dREHEfGN",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/",
|
||||
)
|
||||
|
||||
artifactsM[PythonDistlib] = newViaPip(
|
||||
"distlib",
|
||||
"used as the basis for third-party packaging tools",
|
||||
"0.4.0", "py2.py3", "none", "any",
|
||||
"lGLLfYVhUhXOTw_84zULaH2K8n6pk1OOVXmJfGavev7N42msbtHoq-XY5D_xULI_",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/",
|
||||
)
|
||||
|
||||
artifactsM[PythonFilelock] = newViaPip(
|
||||
"filelock",
|
||||
"a platform-independent file locking library for Python",
|
||||
"3.25.0", "py3", "none", "any",
|
||||
"0gSQIYNUEjOs1JBxXjGwfLnwFPFINwqyU_Zqgj7fT_EGafv_HaD5h3Xv2Rq_qQ44",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/",
|
||||
)
|
||||
|
||||
artifactsM[PythonPlatformdirs] = newViaPip(
|
||||
"platformdirs",
|
||||
"a Python package for determining platform-specific directories",
|
||||
"4.9.4", "py3", "none", "any",
|
||||
"JGNpMCX2JMn-7c9bk3QzOSNDgJRR_5lH-jIqfy0zXMZppRCdLsTNbdp4V7QFwxOI",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/",
|
||||
)
|
||||
|
||||
artifactsM[PythonDiscovery] = newViaPip(
|
||||
"python_discovery",
|
||||
"looks for a python installation",
|
||||
"1.1.1", "py3", "none", "any",
|
||||
"Jk_qGMfZYm0fdNOSvMdVQZuQbJlqu3NWRm7T2fRtiBXmHLQyOdJE3ypI_it1OJR0",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"75/0f/2bf7e3b5a4a65f623cb820feb5793e243fad58ae561015ee15a6152f67a2/",
|
||||
PythonFilelock,
|
||||
PythonPlatformdirs,
|
||||
)
|
||||
|
||||
artifactsM[PythonVirtualenv] = newViaPip(
|
||||
"virtualenv",
|
||||
"a tool for creating isolated virtual python environments",
|
||||
"21.1.0", "py3", "none", "any",
|
||||
"SLvdr3gJZ7GTS-kiRyq2RvJdrQ8SZYC1pglbViWCMLCuAIcbLNjVEUJZ4hDtKUxm",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/",
|
||||
PythonDistlib,
|
||||
PythonFilelock,
|
||||
PythonPlatformdirs,
|
||||
PythonDiscovery,
|
||||
)
|
||||
|
||||
artifactsM[PythonPreCommit] = newViaPip(
|
||||
"pre_commit",
|
||||
"a framework for managing and maintaining multi-language pre-commit hooks",
|
||||
"4.5.1", "py2.py3", "none", "any",
|
||||
"9G2Hv5JpvXFZVfw4pv_KAsmHD6bvot9Z0YBDmW6JeJizqTA4xEQCKel-pCERqQFK",
|
||||
"https://files.pythonhosted.org/packages/"+
|
||||
"5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/",
|
||||
PythonCfgv,
|
||||
PythonIdentify,
|
||||
PythonNodeenv,
|
||||
PythonPyYAML,
|
||||
PythonDistlib,
|
||||
PythonFilelock,
|
||||
PythonPlatformdirs,
|
||||
PythonDiscovery,
|
||||
PythonVirtualenv,
|
||||
)
|
||||
}
|
||||
|
||||
33
internal/rosa/rdfind.go
Normal file
33
internal/rosa/rdfind.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package rosa
|
||||
|
||||
import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newRdfind() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.8.0"
|
||||
checksum = "PoaeJ2WIG6yyfe5VAYZlOdAQiR3mb3WhAUMj2ziTCx_IIEal4640HMJUb4SzU9U3"
|
||||
)
|
||||
return t.NewPackage("rdfind", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://rdfind.pauldreik.se/rdfind-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
), nil, &MakeHelper{
|
||||
// test suite hard codes /bin/echo
|
||||
ScriptCheckEarly: `
|
||||
ln -s ../system/bin/toybox /bin/echo
|
||||
`,
|
||||
},
|
||||
Nettle,
|
||||
), version
|
||||
}
|
||||
func init() {
|
||||
artifactsM[Rdfind] = Metadata{
|
||||
f: Toolchain.newRdfind,
|
||||
|
||||
Name: "rdfind",
|
||||
Description: "a program that finds duplicate files",
|
||||
Website: "https://rdfind.pauldreik.se/",
|
||||
|
||||
ID: 231641,
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func init() {
|
||||
artifactsM[buildcatrust] = newViaPip(
|
||||
"buildcatrust",
|
||||
"transform certificate stores between formats",
|
||||
version, "none", "any",
|
||||
version, "py3", "none", "any",
|
||||
"k_FGzkRCLjbTWBkuBLzQJ1S8FPAz19neJZlMHm0t10F2Y0hElmvVwdSBRc03Rjo1",
|
||||
"https://github.com/nix-community/buildcatrust/"+
|
||||
"releases/download/v"+version+"/",
|
||||
@@ -93,6 +93,7 @@ func init() {
|
||||
|
||||
func (t Toolchain) newNSSCACert() (pkg.Artifact, string) {
|
||||
return t.New("nss-cacert", 0, []pkg.Artifact{
|
||||
t.Load(Zlib),
|
||||
t.Load(Bash),
|
||||
t.Load(Python),
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ func (t Toolchain) newStage0() (pkg.Artifact, string) {
|
||||
runtimes,
|
||||
clang,
|
||||
|
||||
t.Load(Zlib),
|
||||
t.Load(Bzip2),
|
||||
|
||||
t.Load(Patch),
|
||||
|
||||
@@ -44,5 +44,7 @@ func init() {
|
||||
Name: "tamago",
|
||||
Description: "a Go toolchain extended with support for bare metal execution",
|
||||
Website: "https://github.com/usbarmory/tamago-go",
|
||||
|
||||
ID: 388872,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,22 +4,28 @@ import "hakurei.app/internal/pkg"
|
||||
|
||||
func (t Toolchain) newZlib() (pkg.Artifact, string) {
|
||||
const (
|
||||
version = "1.3.1"
|
||||
checksum = "E-eIpNzE8oJ5DsqH4UuA_0GDKuQF5csqI8ooDx2w7Vx-woJ2mb-YtSbEyIMN44mH"
|
||||
version = "1.3.2"
|
||||
checksum = "KHZrePe42vL2XvOUE3KlJkp1UgWhWkl0jjT_BOvFhuM4GzieEH9S7CioepOFVGYB"
|
||||
)
|
||||
return t.NewPackage("zlib", version, pkg.NewHTTPGetTar(
|
||||
nil, "https://www.zlib.net/fossils/zlib-"+version+".tar.gz",
|
||||
mustDecode(checksum),
|
||||
pkg.TarGzip,
|
||||
), &PackageAttr{
|
||||
Env: []string{
|
||||
"CC=clang -fPIC",
|
||||
},
|
||||
}, &MakeHelper{
|
||||
OmitDefaults: true,
|
||||
), nil, &CMakeHelper{
|
||||
Cache: [][2]string{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
|
||||
Host: `""`,
|
||||
Build: `""`,
|
||||
{"ZLIB_BUILD_TESTING", "OFF"},
|
||||
{"ZLIB_BUILD_SHARED", "ON"},
|
||||
{"ZLIB_BUILD_STATIC", "ON"},
|
||||
{"ZLIB_BUILD_MINIZIP", "OFF"},
|
||||
|
||||
{"ZLIB_INSTALL", "ON"},
|
||||
{"ZLIB_PREFIX", "OFF"},
|
||||
},
|
||||
|
||||
// ninja dependency loop
|
||||
Make: true,
|
||||
}), version
|
||||
}
|
||||
func init() {
|
||||
|
||||
@@ -16,7 +16,6 @@ func (t Toolchain) newZstd() (pkg.Artifact, string) {
|
||||
Append: []string{"build", "cmake"},
|
||||
Cache: [][2]string{
|
||||
{"CMAKE_BUILD_TYPE", "Release"},
|
||||
{"CMAKE_INSTALL_LIBDIR", "lib"},
|
||||
},
|
||||
}), version
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user