Compare commits
37 Commits
v0.0.1
..
dbe75ce5fd
| Author | SHA1 | Date | |
|---|---|---|---|
| dbe75ce5fd | |||
| 81926a53f9 | |||
| eb59764b75 | |||
| 8c023ab05c | |||
| 0e6a2fdf2f | |||
| b5672f2e05 | |||
| 30edd51714 | |||
| 58cf7a72bb | |||
| d23da62dfc | |||
| cb38468ddd | |||
| fffc7a0b40 | |||
| ff8f176120 | |||
| 41d3d712e4 | |||
| 480c3ac20d | |||
| b717e3b131 | |||
| 0f7c55a4d8 | |||
| 4073538ee6 | |||
| d7a47f2963 | |||
| 3f3867da00 | |||
| 38d191fa53 | |||
| bbe139f779 | |||
| a0df472552 | |||
| 8aafff96dc | |||
| 688cd83481 | |||
| 4c4916159d | |||
| e6d71b9b3f | |||
| 321113aec5 | |||
| aac1fbfd1d | |||
| 5a90de4ef5 | |||
| 65e297d792 | |||
| 42469e9ef8 | |||
| f18b76424e | |||
| 18cf85ee9d | |||
| 76d7bd8d6d | |||
| e3f7a5667c | |||
| ddec44c807 | |||
| cea2117b56 |
@@ -0,0 +1,13 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Ignore files for PNPM, NPM and YARN
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
|
||||||
|
plugins: ['svelte3', '@typescript-eslint'],
|
||||||
|
ignorePatterns: ['*.cjs'],
|
||||||
|
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
|
||||||
|
settings: {
|
||||||
|
'svelte3/typescript': () => require('typescript')
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 2020
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2017: true,
|
||||||
|
node: true
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1 +1,10 @@
|
|||||||
/lure-web
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
vite.config.js.timestamp-*
|
||||||
|
vite.config.ts.timestamp-*
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Ignore files for PNPM, NPM and YARN
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"useTabs": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"printWidth": 100,
|
||||||
|
"plugins": ["prettier-plugin-svelte"],
|
||||||
|
"pluginSearchDirs": ["."],
|
||||||
|
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||||
|
}
|
||||||
@@ -1,15 +1,26 @@
|
|||||||
platform: linux/amd64
|
pipeline:
|
||||||
steps:
|
publish:
|
||||||
docker:
|
image: woodpeckerci/plugin-docker-buildx
|
||||||
image: gitea.elara.ws/elara6331/builder
|
secrets: [docker_username, docker_password]
|
||||||
environment:
|
settings:
|
||||||
- REGISTRY=gitea.elara.ws
|
repo: elara6331/lure-web
|
||||||
- REGISTRY_USERNAME=Elara6331
|
dockerfile: docker/Dockerfile
|
||||||
- KO_DOCKER_REPO=gitea.elara.ws/lure
|
platforms: linux/amd64,linux/arm64
|
||||||
- KO_DEFAULTBASEIMAGE=gitea.elara.ws/elara6331/static
|
build_args: api_url=https://api.lure.elara.ws
|
||||||
secrets: [ registry_password ]
|
tag: latest
|
||||||
commands:
|
|
||||||
- registry-login
|
|
||||||
- ko build -B --platform=linux/amd64,linux/arm64,linux/riscv64 -t latest,${CI_COMMIT_TAG} --sbom=none
|
|
||||||
when:
|
when:
|
||||||
event: tag
|
branch: public
|
||||||
|
event: push
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
image: loq9/drone-nomad
|
||||||
|
secrets: [lure_api_github_secret]
|
||||||
|
settings:
|
||||||
|
addr: http://192.168.100.62:4646
|
||||||
|
template: template.nomad
|
||||||
|
environment:
|
||||||
|
- PLUGIN_WATCH_DEPLOYMENT=true
|
||||||
|
- PLUGIN_WATCH_DEPLOYMENT_TIMEOUT=10m
|
||||||
|
when:
|
||||||
|
branch: public
|
||||||
|
event: push
|
||||||
|
|||||||
@@ -1,69 +1,38 @@
|
|||||||
# lure-web
|
# create-svelte
|
||||||
|
|
||||||
`lure-web` is a website for LURE and a web interface that lets users search and get information about LURE's packages.
|
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
|
||||||
|
|
||||||
LURE Web is powered by [Salix](https://gitea.elara.ws/Elara6331/salix) and [PicoCSS](https://picocss.com/).
|
## Creating a project
|
||||||
|
|
||||||
## API
|
If you're seeing this, you've probably already done this step. Congrats!
|
||||||
|
|
||||||
### Search Packages
|
```bash
|
||||||
|
# create a new project in the current directory
|
||||||
|
npm create svelte@latest
|
||||||
|
|
||||||
- **Endpoint:** `GET /api/search`
|
# create a new project in my-app
|
||||||
- **Description:** Search for packages based on specified search options.
|
npm create svelte@latest my-app
|
||||||
- **Parameters:**
|
```
|
||||||
- None
|
|
||||||
- **Query Parameters:**
|
|
||||||
- `sort` (optional) - Sort the results by a specific attribute.
|
|
||||||
- Possible values: "name", "version", "repo"
|
|
||||||
- `filter` (optional) - Apply a filter to narrow down the search results.
|
|
||||||
- Possible values: "inrepo", "arch"
|
|
||||||
- `fv` (optional) - Filter value to be used based on the selected filter.
|
|
||||||
- `q` (optional) - The search query string.
|
|
||||||
- **Response:**
|
|
||||||
- Content-Type: application/json
|
|
||||||
- Body: List of translated packages based on search criteria.
|
|
||||||
|
|
||||||
### Get Package Information
|
## Developing
|
||||||
|
|
||||||
- **Endpoint:** `GET /api/pkg/:repo/:pkg`
|
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||||
- **Description:** Get detailed information about a specific package.
|
|
||||||
- **Parameters:**
|
|
||||||
- `:repo` - Repository name
|
|
||||||
- `:pkg` - Package name
|
|
||||||
- **Response:**
|
|
||||||
- Content-Type: application/json
|
|
||||||
- Body: Translated information about the specified package.
|
|
||||||
|
|
||||||
### Get Package Script
|
```bash
|
||||||
|
npm run dev
|
||||||
|
|
||||||
- **Endpoint:** `GET /api/pkg/:repo/:pkg/script`
|
# or start the server and open the app in a new browser tab
|
||||||
- **Description:** Get the script associated with a specific package.
|
npm run dev -- --open
|
||||||
- **Parameters:**
|
```
|
||||||
- `:repo` - Repository name
|
|
||||||
- `:pkg` - Package name
|
|
||||||
- **Query Parameters:**
|
|
||||||
- `highlight` (optional) - If set to `true`, the script will be returned with syntax highlighting.
|
|
||||||
- **Response:**
|
|
||||||
- If `highlight` is `true`:
|
|
||||||
- Content-Type: text/html
|
|
||||||
- Body: Script with syntax highlighting in HTML format.
|
|
||||||
- If `highlight` is not provided or set to "false":
|
|
||||||
- Content-Type: text/x-shellscript
|
|
||||||
- Body: Raw script content.
|
|
||||||
|
|
||||||
### Language Translation
|
## Building
|
||||||
|
|
||||||
- **Header:** `Accept-Language`
|
To create a production version of your app:
|
||||||
- Use the Accept-Language header to specify the preferred language for response translations.
|
|
||||||
- **Query Parameter:** `lang`
|
|
||||||
- You can also include a `lang` query parameter instead of `Accept-Language` to specify the translation language.
|
|
||||||
|
|
||||||
### Error Handling
|
```bash
|
||||||
|
npm run build
|
||||||
- **Response:**
|
```
|
||||||
- Content-Type: application/json
|
|
||||||
- Body: A JSON object with a single `error` string field containing an explanation of the error.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
You can preview the production build with `npm run preview`.
|
||||||
|
|
||||||
|
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/rs/cors"
|
|
||||||
"github.com/uptrace/bunrouter"
|
|
||||||
"lure.sh/lure/pkg/loggerctx"
|
|
||||||
"lure.sh/lure/pkg/search"
|
|
||||||
"go.elara.ws/logger/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerAPI(mux *bunrouter.Router) {
|
|
||||||
g := mux.NewGroup(
|
|
||||||
"/api",
|
|
||||||
bunrouter.WithMiddleware(apiErrorHandler, corsMiddleware()),
|
|
||||||
)
|
|
||||||
|
|
||||||
g.GET("/*path", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
return HTTPError{404, "endpoint not found: " + req.URL.Path}
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/search", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
ctx := loggerctx.With(req.Context(), log.Logger)
|
|
||||||
pkgs, err := search.Search(ctx, searchOptions(req.Request))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bunrouter.JSON(w, translatePkgs(getLanguages(req.Request), pkgs))
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/pkg/:repo/:pkg", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
ctx := loggerctx.With(req.Context(), log.Logger)
|
|
||||||
pkg, err := search.GetPkg(ctx, req.Param("repo"), req.Param("pkg"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bunrouter.JSON(w, translatePkg(getLanguages(req.Request), pkg))
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/pkg/:repo/:pkg/script", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
ctx := loggerctx.With(req.Context(), log.Logger)
|
|
||||||
script, err := search.GetScript(ctx, req.Param("repo"), req.Param("pkg"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer script.Close()
|
|
||||||
|
|
||||||
if req.URL.Query().Get("highlight") == "true" {
|
|
||||||
data, err := highlight(script)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.Header().Set("Content-Type", "text/html")
|
|
||||||
_, err = io.WriteString(w, string(data))
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
w.Header().Set("Content-Type", "text/x-shellscript")
|
|
||||||
_, err = io.Copy(w, script)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func corsMiddleware() bunrouter.MiddlewareFunc {
|
|
||||||
ch := cors.AllowAll()
|
|
||||||
return func(next bunrouter.HandlerFunc) bunrouter.HandlerFunc {
|
|
||||||
return bunrouter.HTTPHandler(ch.Handler(next))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
_ "embed"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httputil"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/uptrace/bunrouter"
|
|
||||||
"lure.sh/lure/pkg/search"
|
|
||||||
)
|
|
||||||
|
|
||||||
type pkgCtxKey struct{}
|
|
||||||
|
|
||||||
//go:embed static/icons/badge-logo.base64
|
|
||||||
var logoData string
|
|
||||||
|
|
||||||
// registerBadge registers the route for generating LURE badges
|
|
||||||
func registerBadge(mux *bunrouter.Router) {
|
|
||||||
// rp is a reverse proxy that will route user requests to shields.io
|
|
||||||
// and return the responses, stripped of any irrelevant headers.
|
|
||||||
rp := &httputil.ReverseProxy{
|
|
||||||
Rewrite: func(pr *httputil.ProxyRequest) {
|
|
||||||
pkg := pr.In.Context().Value(pkgCtxKey{}).(search.Package)
|
|
||||||
pr.Out.URL = genBadgeURL(pkg, pr.In.URL.Query().Get("style"))
|
|
||||||
pr.Out.Host = pr.Out.URL.Host
|
|
||||||
},
|
|
||||||
ModifyResponse: func(r *http.Response) error {
|
|
||||||
// Remove all the irrelevant headers from the response.
|
|
||||||
r.Header.Del("Alt-Svc")
|
|
||||||
r.Header.Del("Cache-Control")
|
|
||||||
r.Header.Del("Report-To")
|
|
||||||
r.Header.Del("Cf-Cache-Status")
|
|
||||||
r.Header.Del("Cf-Ray")
|
|
||||||
r.Header.Del("Fly-Request-Id")
|
|
||||||
r.Header.Del("Nel")
|
|
||||||
r.Header.Del("Report-To")
|
|
||||||
r.Header.Del("Server")
|
|
||||||
r.Header.Del("Via")
|
|
||||||
r.Header.Del("Set-Cookie")
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
mux.GET("/pkg/:repo/:pkg/badge.svg", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
repo := req.Param("repo")
|
|
||||||
name := req.Param("pkg")
|
|
||||||
|
|
||||||
pkg, err := search.GetPkg(req.Context(), repo, name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.WithValue(req.Context(), pkgCtxKey{}, pkg)
|
|
||||||
rp.ServeHTTP(w, req.Request.WithContext(ctx))
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func genBadgeURL(pkg search.Package, style string) *url.URL {
|
|
||||||
v := url.Values{}
|
|
||||||
v.Set("label", pkg.Name)
|
|
||||||
v.Set("message", genBadgeVersion(pkg))
|
|
||||||
v.Set("logo", logoData)
|
|
||||||
v.Set("color", "0060A8")
|
|
||||||
if style != "" {
|
|
||||||
v.Set("style", style)
|
|
||||||
}
|
|
||||||
return &url.URL{Scheme: "https", Host: "img.shields.io", Path: "/static/v1", RawQuery: v.Encode()}
|
|
||||||
}
|
|
||||||
|
|
||||||
func genBadgeVersion(pkg search.Package) string {
|
|
||||||
sb := strings.Builder{}
|
|
||||||
if pkg.Epoch != 0 {
|
|
||||||
sb.WriteString(strconv.Itoa(int(pkg.Epoch)))
|
|
||||||
sb.WriteByte(':')
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.WriteString(pkg.Version)
|
|
||||||
|
|
||||||
if pkg.Release != 0 {
|
|
||||||
sb.WriteByte('-')
|
|
||||||
sb.WriteString(strconv.Itoa(pkg.Release))
|
|
||||||
}
|
|
||||||
return sb.String()
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
FROM node:19-alpine
|
||||||
|
|
||||||
|
ARG api_url
|
||||||
|
ENV LURE_WEB_API_URL $api_url
|
||||||
|
|
||||||
|
RUN apk add git
|
||||||
|
RUN git clone https://gitea.elara.ws/Elara6331/lure-web
|
||||||
|
RUN cd lure-web && \
|
||||||
|
npm i && \
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
WORKDIR /lure-web
|
||||||
|
ENTRYPOINT node build
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/uptrace/bunrouter"
|
|
||||||
"go.elara.ws/logger/log"
|
|
||||||
"go.elara.ws/salix"
|
|
||||||
)
|
|
||||||
|
|
||||||
type HTTPError struct {
|
|
||||||
StatusCode int `json:"status_code"`
|
|
||||||
Msg string `json:"error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (he HTTPError) Error() string {
|
|
||||||
return he.Msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (he HTTPError) StatusText() string {
|
|
||||||
return http.StatusText(he.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpError(err error) *HTTPError {
|
|
||||||
switch err := err.(type) {
|
|
||||||
case nil:
|
|
||||||
return nil
|
|
||||||
case HTTPError:
|
|
||||||
return &err
|
|
||||||
case *HTTPError:
|
|
||||||
return err
|
|
||||||
default:
|
|
||||||
switch {
|
|
||||||
case errors.Is(err, sql.ErrNoRows):
|
|
||||||
return &HTTPError{404, err.Error()}
|
|
||||||
default:
|
|
||||||
return &HTTPError{500, err.Error()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func siteErrorHandler(ns *salix.Namespace) bunrouter.MiddlewareFunc {
|
|
||||||
return func(next bunrouter.HandlerFunc) bunrouter.HandlerFunc {
|
|
||||||
tmpl, ok := ns.GetTemplate("error.html")
|
|
||||||
if !ok {
|
|
||||||
return basicErrorHandler(next)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
err := next(w, req)
|
|
||||||
if err != nil {
|
|
||||||
he := httpError(err)
|
|
||||||
w.WriteHeader(he.StatusCode)
|
|
||||||
err := tmpl.
|
|
||||||
WithVarMap(map[string]any{"error": he}).
|
|
||||||
Execute(w)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Error while executing error template").Err(err).Send()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func apiErrorHandler(next bunrouter.HandlerFunc) bunrouter.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
err := next(w, req)
|
|
||||||
if err != nil {
|
|
||||||
he := httpError(err)
|
|
||||||
w.WriteHeader(he.StatusCode)
|
|
||||||
_ = bunrouter.JSON(w, map[string]string{"error": he.Msg})
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func basicErrorHandler(next bunrouter.HandlerFunc) bunrouter.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
err := next(w, req)
|
|
||||||
if err != nil {
|
|
||||||
he := httpError(err)
|
|
||||||
http.Error(w, he.Msg, he.StatusCode)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
module lure.sh/lure-web
|
|
||||||
|
|
||||||
go 1.21.2
|
|
||||||
|
|
||||||
toolchain go1.21.6
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/alecthomas/chroma/v2 v2.9.1
|
|
||||||
github.com/rs/cors v1.10.1
|
|
||||||
github.com/uptrace/bunrouter v1.0.21
|
|
||||||
go.elara.ws/logger v0.0.0-20230421022458-e80700db2090
|
|
||||||
go.elara.ws/salix v0.0.0-20231228151958-745b6c0e5f10
|
|
||||||
golang.org/x/text v0.13.0
|
|
||||||
lure.sh/lure v0.1.4-0.20231223033536-5dc31f43aa39
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
dario.cat/mergo v1.0.0 // indirect
|
|
||||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
|
|
||||||
github.com/acomagu/bufpipe v1.0.4 // indirect
|
|
||||||
github.com/cloudflare/circl v1.3.3 // indirect
|
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
|
||||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
|
||||||
github.com/emirpasic/gods v1.18.1 // indirect
|
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
|
||||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
|
||||||
github.com/go-git/go-git/v5 v5.9.0 // indirect
|
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
|
||||||
github.com/gookit/color v1.5.1 // indirect
|
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
|
||||||
github.com/jmoiron/sqlx v1.3.5 // indirect
|
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
|
||||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
|
||||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
|
||||||
github.com/sergi/go-diff v1.2.0 // indirect
|
|
||||||
github.com/skeema/knownhosts v1.2.0 // indirect
|
|
||||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
|
||||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
|
||||||
go.elara.ws/vercmp v0.0.0-20230622214216-0b2b067575c4 // indirect
|
|
||||||
golang.org/x/crypto v0.13.0 // indirect
|
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
|
||||||
golang.org/x/mod v0.12.0 // indirect
|
|
||||||
golang.org/x/net v0.15.0 // indirect
|
|
||||||
golang.org/x/sync v0.3.0 // indirect
|
|
||||||
golang.org/x/sys v0.12.0 // indirect
|
|
||||||
golang.org/x/term v0.12.0 // indirect
|
|
||||||
golang.org/x/tools v0.13.0 // indirect
|
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
|
||||||
lukechampine.com/uint128 v1.2.0 // indirect
|
|
||||||
lure.sh/fakeroot v0.0.0-20231024000108-b130d64a68ee // indirect
|
|
||||||
modernc.org/cc/v3 v3.40.0 // indirect
|
|
||||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
|
||||||
modernc.org/libc v1.24.1 // indirect
|
|
||||||
modernc.org/mathutil v1.5.0 // indirect
|
|
||||||
modernc.org/memory v1.6.0 // indirect
|
|
||||||
modernc.org/opt v0.1.3 // indirect
|
|
||||||
modernc.org/sqlite v1.25.0 // indirect
|
|
||||||
modernc.org/strutil v1.1.3 // indirect
|
|
||||||
modernc.org/token v1.0.1 // indirect
|
|
||||||
mvdan.cc/sh/v3 v3.7.0 // indirect
|
|
||||||
)
|
|
||||||
@@ -1,245 +0,0 @@
|
|||||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
|
||||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
|
||||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
|
||||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
|
||||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
|
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
|
||||||
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
|
|
||||||
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
|
||||||
github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
|
|
||||||
github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
|
|
||||||
github.com/alecthomas/chroma/v2 v2.9.1 h1:0O3lTQh9FxazJ4BYE/MOi/vDGuHn7B+6Bu902N2UZvU=
|
|
||||||
github.com/alecthomas/chroma/v2 v2.9.1/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw=
|
|
||||||
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
|
|
||||||
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
|
||||||
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/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
|
||||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
|
||||||
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
|
||||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
|
||||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
|
||||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
|
||||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
|
||||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
|
|
||||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
|
||||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
|
||||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
|
||||||
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
|
|
||||||
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
|
||||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
|
||||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
|
||||||
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
|
|
||||||
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
|
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
|
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
|
|
||||||
github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY=
|
|
||||||
github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0=
|
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
|
||||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ=
|
|
||||||
github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM=
|
|
||||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
|
||||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
|
||||||
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
|
|
||||||
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
|
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
|
||||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
|
||||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
|
||||||
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.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|
||||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
|
||||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
|
||||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
|
||||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
|
||||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
|
||||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
|
||||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
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/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
|
||||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
|
||||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
|
||||||
github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
|
|
||||||
github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
|
||||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
|
||||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
|
||||||
github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
|
|
||||||
github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
|
||||||
github.com/uptrace/bunrouter v1.0.21 h1:HXarvX+N834sXyHpl+I/TuE11m19kLW/qG5u3YpHUag=
|
|
||||||
github.com/uptrace/bunrouter v1.0.21/go.mod h1:TwT7Bc0ztF2Z2q/ZzMuSVkcb/Ig/d3MQeP2cxn3e1hI=
|
|
||||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
|
||||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
|
||||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
|
||||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
|
||||||
go.elara.ws/logger v0.0.0-20230421022458-e80700db2090 h1:RVC8XvWo6Yw4HUshqx4TSzuBDScDghafU6QFRJ4xPZg=
|
|
||||||
go.elara.ws/logger v0.0.0-20230421022458-e80700db2090/go.mod h1:qng49owViqsW5Aey93lwBXONw20oGbJIoLVscB16mPM=
|
|
||||||
go.elara.ws/salix v0.0.0-20231228151958-745b6c0e5f10 h1:Z0XcJexULcFf0ITcvQml/z+c/RW4fpon3nDWuoDcr3Q=
|
|
||||||
go.elara.ws/salix v0.0.0-20231228151958-745b6c0e5f10/go.mod h1:niWia13iw7qDrS1C1mlqv5hxO1sunt8CcOQAB5yVlNU=
|
|
||||||
go.elara.ws/vercmp v0.0.0-20230622214216-0b2b067575c4 h1:Ep54XceQlKhcCHl9awG+wWP4kz4kIP3c3Lzw/Gc/zwY=
|
|
||||||
go.elara.ws/vercmp v0.0.0-20230622214216-0b2b067575c4/go.mod h1:/7PNW7nFnDR5W7UXZVc04gdVLR/wBNgkm33KgIz0OBk=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
|
||||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
|
||||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
|
||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
|
||||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
|
||||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
|
||||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|
||||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
|
||||||
golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
|
|
||||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|
||||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
|
||||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
|
||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
|
||||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
|
||||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
|
||||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
|
||||||
lure.sh/fakeroot v0.0.0-20231024000108-b130d64a68ee h1:kSXIuMid56Q29WEl7EQb5QUtmGqQqAu66EZ2G0OSUfU=
|
|
||||||
lure.sh/fakeroot v0.0.0-20231024000108-b130d64a68ee/go.mod h1:/v0u0AZ+wbzUWhV02KzciOf1KFNh7/7rbkz5Z0b5gDA=
|
|
||||||
lure.sh/lure v0.1.4-0.20231223033536-5dc31f43aa39 h1:9Rw9+Pmmkbjxiq0eREq4RJPn+ggL1jYFpgrgOkgQ9YQ=
|
|
||||||
lure.sh/lure v0.1.4-0.20231223033536-5dc31f43aa39/go.mod h1:h1+OIDD39zDosjThxQ9szoWW9Z1lGcm7M6eeo6v0OJY=
|
|
||||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
|
||||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
|
||||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
|
||||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
|
||||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
|
||||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
|
||||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
|
||||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
|
||||||
modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
|
|
||||||
modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
|
|
||||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
|
||||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
|
|
||||||
modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
|
||||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
|
||||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
|
||||||
modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA=
|
|
||||||
modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
|
|
||||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
|
||||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
|
||||||
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=
|
|
||||||
modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c=
|
|
||||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
|
||||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
|
||||||
modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY=
|
|
||||||
modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE=
|
|
||||||
mvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg=
|
|
||||||
mvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8=
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"embed"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/uptrace/bunrouter"
|
|
||||||
"go.elara.ws/logger"
|
|
||||||
"go.elara.ws/logger/log"
|
|
||||||
"lure.sh/lure/pkg/loggerctx"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed static
|
|
||||||
var static embed.FS
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.Logger = logger.NewPretty(os.Stderr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
mux := bunrouter.New()
|
|
||||||
|
|
||||||
fileServer := http.FileServer(http.FS(static))
|
|
||||||
mux.Use(cache).GET("/static/*path", bunrouter.HTTPHandler(fileServer))
|
|
||||||
|
|
||||||
ctx := loggerctx.With(context.Background(), log.Logger)
|
|
||||||
|
|
||||||
registerBadge(mux)
|
|
||||||
registerSite(mux)
|
|
||||||
registerAPI(mux)
|
|
||||||
registerWebhook(ctx, mux)
|
|
||||||
|
|
||||||
http.ListenAndServe(":8080", mux)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cache(next bunrouter.HandlerFunc) bunrouter.HandlerFunc {
|
|
||||||
return bunrouter.HandlerFunc(func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
w.Header().Set("Cache-Control", "max-age=86400, stale-while-revalidate=86400")
|
|
||||||
return next(w, req)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"name": "lure-web",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite dev",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
||||||
|
"format": "prettier --plugin-search-dir . --write ."
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@iconify/svelte": "^3.0.1",
|
||||||
|
"@sveltejs/adapter-auto": "^1.0.0",
|
||||||
|
"@sveltejs/adapter-node": "^1.0.0",
|
||||||
|
"@sveltejs/kit": "^1.0.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
|
"@typescript-eslint/parser": "^5.45.0",
|
||||||
|
"@vime/core": "^5.4.0",
|
||||||
|
"@vime/svelte": "^5.4.0",
|
||||||
|
"bulma": "^0.9.4",
|
||||||
|
"eslint": "^8.28.0",
|
||||||
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-plugin-svelte3": "^4.0.0",
|
||||||
|
"prettier": "^2.8.0",
|
||||||
|
"prettier-plugin-svelte": "^2.8.1",
|
||||||
|
"sass": "^1.53.0",
|
||||||
|
"svelte": "^3.54.0",
|
||||||
|
"svelte-carousel": "^1.0.20",
|
||||||
|
"svelte-check": "^2.9.2",
|
||||||
|
"svelte-highlight": "^6.2.1",
|
||||||
|
"svelte-loading-spinners": "^0.3.4",
|
||||||
|
"svelte-preprocess": "^4.10.7",
|
||||||
|
"tslib": "^2.4.1",
|
||||||
|
"typescript": "^4.9.3",
|
||||||
|
"vite": "^4.0.0"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"protoscript": "^0.0.14",
|
||||||
|
"twirpscript": "^0.0.66"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
"lure.sh/lure/pkg/search"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Package struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Repository string `json:"repository"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
Release int `json:"release"`
|
|
||||||
Epoch uint `json:"epoch"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Homepage string `json:"homepage"`
|
|
||||||
Maintainer string `json:"maintainer"`
|
|
||||||
Architectures []string `json:"architectures"`
|
|
||||||
Licenses []string `json:"licenses"`
|
|
||||||
Provides []string `json:"provides"`
|
|
||||||
Conflicts []string `json:"conflicts"`
|
|
||||||
Replaces []string `json:"replaces"`
|
|
||||||
Depends map[string][]string `json:"depends"`
|
|
||||||
BuildDepends map[string][]string `json:"build_depends"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Package) FullVersion() string {
|
|
||||||
ver := fmt.Sprintf("%s-%d", p.Version, p.Release)
|
|
||||||
if p.Epoch != 0 {
|
|
||||||
ver = fmt.Sprintf("%d:%s", p.Epoch, ver)
|
|
||||||
}
|
|
||||||
return ver
|
|
||||||
}
|
|
||||||
|
|
||||||
func translatePkgs(langs []string, pkgs []search.Package) []Package {
|
|
||||||
out := make([]Package, len(pkgs))
|
|
||||||
for i, pkg := range pkgs {
|
|
||||||
out[i] = translatePkg(langs, pkg)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func translatePkg(langs []string, pkg search.Package) Package {
|
|
||||||
return Package{
|
|
||||||
Name: pkg.Name,
|
|
||||||
Repository: pkg.Repository,
|
|
||||||
Version: pkg.Version,
|
|
||||||
Release: pkg.Release,
|
|
||||||
Epoch: pkg.Epoch,
|
|
||||||
Description: performTranslation(langs, pkg.Description),
|
|
||||||
Homepage: performTranslation(langs, pkg.Homepage),
|
|
||||||
Maintainer: performTranslation(langs, pkg.Maintainer),
|
|
||||||
Architectures: pkg.Architectures,
|
|
||||||
Licenses: pkg.Licenses,
|
|
||||||
Provides: pkg.Provides,
|
|
||||||
Conflicts: pkg.Conflicts,
|
|
||||||
Depends: pkg.Depends,
|
|
||||||
BuildDepends: pkg.BuildDepends,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getLanguages(req *http.Request) []string {
|
|
||||||
al := req.Header.Get("Accept-Language")
|
|
||||||
lang := req.URL.Query().Get("lang")
|
|
||||||
|
|
||||||
if al == "" && lang == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
tags, _, _ := language.ParseAcceptLanguage(al)
|
|
||||||
|
|
||||||
if lang != "" {
|
|
||||||
langTag, err := language.Parse(lang)
|
|
||||||
if err == nil {
|
|
||||||
tags = append(tags, langTag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return getLangBases(tags)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getLangBases(langs []language.Tag) []string {
|
|
||||||
out := make([]string, len(langs)+1)
|
|
||||||
for i, lang := range langs {
|
|
||||||
base, _ := lang.Base()
|
|
||||||
out[i] = base.String()
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func performTranslation(langs []string, v map[string]string) string {
|
|
||||||
if len(langs) == 0 {
|
|
||||||
val, ok := v[""]
|
|
||||||
if !ok {
|
|
||||||
return "<unknown>"
|
|
||||||
}
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, name := range langs {
|
|
||||||
val, ok := v[name]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
return "<unknown>"
|
|
||||||
}
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"io"
|
|
||||||
"io/fs"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/alecthomas/chroma/v2"
|
|
||||||
"github.com/alecthomas/chroma/v2/formatters/html"
|
|
||||||
"github.com/alecthomas/chroma/v2/lexers"
|
|
||||||
"github.com/alecthomas/chroma/v2/styles"
|
|
||||||
"github.com/uptrace/bunrouter"
|
|
||||||
"go.elara.ws/logger/log"
|
|
||||||
"go.elara.ws/salix"
|
|
||||||
"lure.sh/lure/pkg/loggerctx"
|
|
||||||
"lure.sh/lure/pkg/search"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed tmpls
|
|
||||||
var tmpls embed.FS
|
|
||||||
|
|
||||||
func registerSite(mux *bunrouter.Router) {
|
|
||||||
tmplFS, err := fs.Sub(tmpls, "tmpls")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ns := salix.New().
|
|
||||||
WithEscapeHTML(true).
|
|
||||||
WithWriteOnSuccess(true).
|
|
||||||
WithVarMap(map[string]any{
|
|
||||||
"now": time.Now,
|
|
||||||
})
|
|
||||||
err = ns.ParseFSGlob(tmplFS, "*.html")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
g := mux.WithMiddleware(siteErrorHandler(ns))
|
|
||||||
|
|
||||||
g.GET("/*path", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
if req.Param("path") == "" {
|
|
||||||
return ns.ExecuteTemplate(w, "home.html", nil)
|
|
||||||
}
|
|
||||||
return HTTPError{404, "page not found: " + req.URL.Path}
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/about", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
return ns.ExecuteTemplate(w, "about.html", nil)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/icons", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
return ns.ExecuteTemplate(w, "icons.html", nil)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/pkgs", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
ctx := loggerctx.With(req.Context(), log.Logger)
|
|
||||||
pkgs, err := search.Search(ctx, searchOptions(req.Request))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ns.ExecuteTemplate(w, "pkgs.html", map[string]any{
|
|
||||||
"pkgs": translatePkgs(getLanguages(req.Request), pkgs),
|
|
||||||
"query": req.URL.Query(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/pkg/:repo/:pkg", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
ctx := loggerctx.With(req.Context(), log.Logger)
|
|
||||||
pkg, err := search.GetPkg(ctx, req.Param("repo"), req.Param("pkg"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ns.ExecuteTemplate(w, "pkg.html", map[string]any{
|
|
||||||
"url": getURL(req.Request),
|
|
||||||
"pkg": translatePkg(getLanguages(req.Request), pkg),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/pkg/:repo/:pkg/script", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
repoName := req.Param("repo")
|
|
||||||
pkgName := req.Param("pkg")
|
|
||||||
|
|
||||||
ctx := loggerctx.With(req.Context(), log.Logger)
|
|
||||||
script, err := search.GetScript(ctx, repoName, pkgName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer script.Close()
|
|
||||||
|
|
||||||
data, err := highlight(script)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ns.ExecuteTemplate(w, "script.html", map[string]any{
|
|
||||||
"repoName": repoName,
|
|
||||||
"pkgName": pkgName,
|
|
||||||
"script": data,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// searchOptions gets a search.Options struct from the request's
|
|
||||||
// query parameters.
|
|
||||||
func searchOptions(r *http.Request) search.Options {
|
|
||||||
sort := search.SortBy(search.SortByNone)
|
|
||||||
switch r.URL.Query().Get("sort") {
|
|
||||||
case "name":
|
|
||||||
sort = search.SortByName
|
|
||||||
case "version":
|
|
||||||
sort = search.SortByVersion
|
|
||||||
case "repo":
|
|
||||||
sort = search.SortByRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := search.FilterNone
|
|
||||||
switch r.URL.Query().Get("filter") {
|
|
||||||
case "inrepo":
|
|
||||||
filter = search.FilterInRepo
|
|
||||||
case "arch":
|
|
||||||
filter = search.FilterSupportsArch
|
|
||||||
}
|
|
||||||
|
|
||||||
return search.Options{
|
|
||||||
Filter: filter,
|
|
||||||
FilterValue: r.URL.Query().Get("fv"),
|
|
||||||
SortBy: sort,
|
|
||||||
Query: r.URL.Query().Get("q"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// highlight returns an HTML string with syntax highlighting
|
|
||||||
// for the contents of the given reader.
|
|
||||||
func highlight(r io.Reader) (salix.HTML, error) {
|
|
||||||
data, err := io.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
lexer := lexers.Get("bash")
|
|
||||||
if lexer == nil {
|
|
||||||
lexer = lexers.Fallback
|
|
||||||
}
|
|
||||||
lexer = chroma.Coalesce(lexer)
|
|
||||||
|
|
||||||
style := styles.Get("modus-vivendi")
|
|
||||||
formatter := html.New()
|
|
||||||
iterator, err := lexer.Tokenise(nil, string(data))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
out := &strings.Builder{}
|
|
||||||
err = formatter.Format(out, style, iterator)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return salix.HTML(out.String()), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getURL attempts to get the current URL of the request
|
|
||||||
func getURL(r *http.Request) string {
|
|
||||||
u := *r.URL
|
|
||||||
|
|
||||||
xfp := r.Header.Get("X-Forwarded-Proto")
|
|
||||||
if xfp == "" {
|
|
||||||
if r.TLS == nil {
|
|
||||||
u.Scheme = "http"
|
|
||||||
} else {
|
|
||||||
u.Scheme = "https"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
u.Scheme = xfp
|
|
||||||
}
|
|
||||||
|
|
||||||
xfh := r.Header.Get("X-Forwarded-Host")
|
|
||||||
if xfh == "" {
|
|
||||||
if r.URL.Host == "" {
|
|
||||||
u.Host = r.Host
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
u.Host = xfh
|
|
||||||
}
|
|
||||||
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// See https://kit.svelte.dev/docs/types#app
|
||||||
|
// for information about these interfaces
|
||||||
|
// and what to do when importing types
|
||||||
|
declare namespace App {
|
||||||
|
// interface Error {}
|
||||||
|
// interface Locals {}
|
||||||
|
// interface PageData {}
|
||||||
|
// interface Platform {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@vime/core@^5/themes/default.css" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
%sveltekit.head%
|
||||||
|
</head>
|
||||||
|
<body data-sveltekit-preload-data="hover">
|
||||||
|
<div id="page-container">%sveltekit.body%</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/* Write your global styles here, in SCSS syntax. Variables and mixins from the src/variables.scss file are available here without importing */ /* Import only what you need from Bulma */
|
||||||
|
@import 'bulma/sass/utilities/_all';
|
||||||
|
@import 'bulma/sass/base/_all';
|
||||||
|
@import 'bulma/sass/elements/_all';
|
||||||
|
@import 'bulma/sass/form/_all';
|
||||||
|
@import 'bulma/sass/components/_all';
|
||||||
|
@import 'bulma/sass/grid/_all';
|
||||||
|
@import 'bulma/sass/helpers/_all';
|
||||||
|
@import 'bulma/sass/layout/_all';
|
||||||
|
|
||||||
|
@import './darkly/overrides.scss';
|
||||||
|
|
||||||
|
.input::placeholder {
|
||||||
|
color: darken($grey-light, 10) !important;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input::-webkit-input-placeholder {
|
||||||
|
color: darken($grey-light, 10) !important;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input::-moz-placeholder {
|
||||||
|
color: darken($grey-light, 10) !important;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input::-ms-input-placeholder {
|
||||||
|
color: darken($grey-light, 10) !important;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-player {
|
||||||
|
max-width: 735px;
|
||||||
|
max-height: 450px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sc-carousel__carousel-container {
|
||||||
|
--sc-arrow-size: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.sc-carousel-arrow__circle {
|
||||||
|
width: 30px !important;
|
||||||
|
height: 30px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-container > * {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
////////////////////////////////////////////////
|
||||||
|
// DARKLY
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Overrides
|
||||||
|
|
||||||
|
hr {
|
||||||
|
height: $border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
background-color: $grey-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
transition: all 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
transition: all 200ms ease;
|
||||||
|
border-width: $border-width;
|
||||||
|
color: $white;
|
||||||
|
|
||||||
|
&.is-active,
|
||||||
|
&.is-focused,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 2px rgba($button-focus-border-color, 0.5);
|
||||||
|
}
|
||||||
|
@each $name, $pair in $colors {
|
||||||
|
$color: nth($pair, 1);
|
||||||
|
$color-invert: nth($pair, 2);
|
||||||
|
|
||||||
|
&.is-#{$name} {
|
||||||
|
&.is-hovered,
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten($color, 7.5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active,
|
||||||
|
&.is-focused,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
border-color: $color;
|
||||||
|
box-shadow: 0 0 0 2px rgba($color, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: $grey-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input,
|
||||||
|
.textarea {
|
||||||
|
transition: all 200ms ease;
|
||||||
|
box-shadow: none;
|
||||||
|
border-width: $border-width;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-right: 1em;
|
||||||
|
background-color: $body-background-color;
|
||||||
|
color: $text
|
||||||
|
}
|
||||||
|
|
||||||
|
.select {
|
||||||
|
&:after,
|
||||||
|
select {
|
||||||
|
border-width: $border-width;
|
||||||
|
background-color: $body-background-color;
|
||||||
|
color: $text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.control {
|
||||||
|
&.has-addons {
|
||||||
|
.button,
|
||||||
|
.input,
|
||||||
|
.select {
|
||||||
|
margin-right: -$border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
background-color: $grey-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
$card-border-color: lighten($grey-darker, 5);
|
||||||
|
box-shadow: none;
|
||||||
|
border: $border-width solid $card-border-color;
|
||||||
|
background-color: $grey-darker;
|
||||||
|
border-radius: $radius;
|
||||||
|
|
||||||
|
.card-image {
|
||||||
|
img {
|
||||||
|
border-radius: $radius $radius 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: rgba($black-bis, 0.2);
|
||||||
|
border-radius: $radius $radius 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer {
|
||||||
|
background-color: rgba($black-bis, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer,
|
||||||
|
.card-footer-item {
|
||||||
|
border-width: $border-width;
|
||||||
|
border-color: $card-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
@each $name, $pair in $colors {
|
||||||
|
$color: nth($pair, 1);
|
||||||
|
$color-invert: nth($pair, 2);
|
||||||
|
|
||||||
|
&.is-#{$name} {
|
||||||
|
a:not(.button) {
|
||||||
|
color: $color-invert;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
border-radius: $radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list {
|
||||||
|
a {
|
||||||
|
transition: all 300ms ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-card-body {
|
||||||
|
background-color: $grey-darker;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-card-foot,
|
||||||
|
.modal-card-head {
|
||||||
|
border-color: $grey-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-header {
|
||||||
|
font-weight: $weight-bold;
|
||||||
|
background-color: $grey-dark;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-body {
|
||||||
|
border-width: $border-width;
|
||||||
|
border-color: $grey-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
border-radius: $radius;
|
||||||
|
|
||||||
|
&.is-transparent {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-primary {
|
||||||
|
.navbar-dropdown {
|
||||||
|
a.navbar-item.is-active {
|
||||||
|
background-color: $link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include until($navbar-breakpoint) {
|
||||||
|
.navbar-menu {
|
||||||
|
background-color: $navbar-background-color;
|
||||||
|
border-radius: 0 0 $radius $radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .navbar,
|
||||||
|
body > .navbar {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-link,
|
||||||
|
.pagination-next,
|
||||||
|
.pagination-previous {
|
||||||
|
border-width: $border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-block,
|
||||||
|
.panel-heading,
|
||||||
|
.panel-tabs {
|
||||||
|
border-width: $border-width;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top-width: $border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-heading {
|
||||||
|
font-weight: $weight-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-tabs {
|
||||||
|
a {
|
||||||
|
border-width: $border-width;
|
||||||
|
margin-bottom: -$border-width;
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
border-bottom-color: $link-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-block {
|
||||||
|
&:hover {
|
||||||
|
color: $link-hover;
|
||||||
|
|
||||||
|
.panel-icon {
|
||||||
|
color: $link-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
.panel-icon {
|
||||||
|
color: $link-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
a {
|
||||||
|
border-bottom-width: $border-width;
|
||||||
|
margin-bottom: -$border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
border-bottom-width: $border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-boxed {
|
||||||
|
a {
|
||||||
|
border-width: $border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.is-active a {
|
||||||
|
background-color: darken($grey-darker, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-toggle {
|
||||||
|
li a {
|
||||||
|
border-width: $border-width;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li + li {
|
||||||
|
margin-left: -$border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
// Colors
|
||||||
|
@each $name, $pair in $colors {
|
||||||
|
$color: nth($pair, 1);
|
||||||
|
$color-invert: nth($pair, 2);
|
||||||
|
|
||||||
|
&.is-#{$name} {
|
||||||
|
.navbar {
|
||||||
|
.navbar-dropdown {
|
||||||
|
.navbar-item:hover {
|
||||||
|
background-color: $navbar-dropdown-item-hover-background-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
////////////////////////////////////////////////
|
||||||
|
// DARKLY
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
$grey-lighter: #dbdee0;
|
||||||
|
$grey-light: #8c9b9d;
|
||||||
|
$grey: darken($grey-light, 18);
|
||||||
|
$grey-dark: darken($grey, 18);
|
||||||
|
$grey-darker: darken($grey, 23);
|
||||||
|
|
||||||
|
$white: #FFF;
|
||||||
|
$orange: #e67e22;
|
||||||
|
$yellow: #f1b70e;
|
||||||
|
$green: #2ecc71;
|
||||||
|
$turquoise: #1abc9c;
|
||||||
|
$blue: #3498db;
|
||||||
|
$purple: #8e44ad;
|
||||||
|
$red: #e74c3c;
|
||||||
|
$white-ter: #ecf0f1;
|
||||||
|
$primary: #375a7f !default;
|
||||||
|
$yellow-invert: #fff;
|
||||||
|
|
||||||
|
$family-sans-serif: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI",
|
||||||
|
"Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
||||||
|
$family-monospace: "Inconsolata", "Consolas", "Monaco", monospace;
|
||||||
|
|
||||||
|
$radius-small: 3px;
|
||||||
|
$radius: 0.4em;
|
||||||
|
$radius-large: 8px;
|
||||||
|
$size-6: 15px;
|
||||||
|
$size-7: 0.85em;
|
||||||
|
$title-weight: 500;
|
||||||
|
$subtitle-weight: 400;
|
||||||
|
$subtitle-color: $grey-dark;
|
||||||
|
|
||||||
|
$border-width: 2px;
|
||||||
|
$border: $grey;
|
||||||
|
|
||||||
|
$body-background-color: darken($grey-darker, 4);
|
||||||
|
$body-size: 15px;
|
||||||
|
|
||||||
|
$background: $grey-darker;
|
||||||
|
$footer-background-color: $background;
|
||||||
|
$button-background-color: $background;
|
||||||
|
$button-border-color: lighten($button-background-color, 15);
|
||||||
|
|
||||||
|
$title-color: #fff;
|
||||||
|
$subtitle-color: $grey-light;
|
||||||
|
$subtitle-strong-color: $grey-light;
|
||||||
|
|
||||||
|
$text: #fff;
|
||||||
|
$text-light: lighten($text, 10);
|
||||||
|
$text-strong: darken($text, 5);
|
||||||
|
|
||||||
|
$box-color: $text;
|
||||||
|
$box-background-color: $grey-dark;
|
||||||
|
$box-shadow: none;
|
||||||
|
|
||||||
|
$link: $turquoise;
|
||||||
|
$link-hover: lighten($link, 5);
|
||||||
|
$link-focus: darken($link, 5);
|
||||||
|
$link-active: darken($link, 5);
|
||||||
|
$link-focus-border: $grey-light;
|
||||||
|
|
||||||
|
$button-color: $primary;
|
||||||
|
$button-hover-color: darken($text, 5); // text-dark
|
||||||
|
$button-focus: darken($text, 5); // text-dark
|
||||||
|
$button-active-color: darken($text, 5); // text-dark
|
||||||
|
$button-disabled-background-color: $grey-light;
|
||||||
|
$button-focus-border-color: $link-focus-border;
|
||||||
|
|
||||||
|
$control-height: 2.5em;
|
||||||
|
|
||||||
|
$input-color: $grey-darker;
|
||||||
|
$input-icon-color: $grey;
|
||||||
|
$input-icon-active-color: $input-color;
|
||||||
|
$input-hover-color: $grey-light;
|
||||||
|
$input-disabled-background-color: $grey-light;
|
||||||
|
$input-disabled-border: $grey-lighter;
|
||||||
|
|
||||||
|
$table-color: $text;
|
||||||
|
$table-head: $grey-lighter;
|
||||||
|
$table-background-color: $grey-dark;
|
||||||
|
$table-cell-border: 1px solid $grey;
|
||||||
|
|
||||||
|
$table-row-hover-background-color: $grey-darker;
|
||||||
|
$table-striped-row-even-background-color: $grey-darker;
|
||||||
|
$table-striped-row-even-hover-background-color: lighten($grey-darker, 2);
|
||||||
|
|
||||||
|
$pagination-color: $link;
|
||||||
|
$pagination-border-color: $border;
|
||||||
|
|
||||||
|
$navbar-height: 4rem;
|
||||||
|
|
||||||
|
$navbar-background-color: $primary;
|
||||||
|
$navbar-item-color: $text;
|
||||||
|
$navbar-item-hover-color: $link;
|
||||||
|
$navbar-item-hover-background-color: transparent;
|
||||||
|
$navbar-item-active-color: $link;
|
||||||
|
$navbar-dropdown-arrow: #fff;
|
||||||
|
$navbar-divider-background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
$navbar-dropdown-border-top: 1px solid $navbar-divider-background-color;
|
||||||
|
$navbar-dropdown-background-color: $primary;
|
||||||
|
$navbar-dropdown-item-hover-color: $grey-lighter;
|
||||||
|
$navbar-dropdown-item-hover-background-color: transparent;
|
||||||
|
$navbar-dropdown-item-active-background-color: transparent;
|
||||||
|
$navbar-dropdown-item-active-color: $link;
|
||||||
|
|
||||||
|
$dropdown-content-background-color: $background;
|
||||||
|
$dropdown-item-color: $text;
|
||||||
|
|
||||||
|
$progress-value-background-color: $grey-lighter;
|
||||||
|
|
||||||
|
$bulmaswatch-import-font: true !default;
|
||||||
|
|
||||||
|
$file-cta-background-color: $grey-darker;
|
||||||
|
|
||||||
|
$progress-bar-background-color: $grey-dark;
|
||||||
|
|
||||||
|
$panel-heading-background-color: $grey-dark;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<script>
|
||||||
|
import '../app.scss';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<slot />
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
import Header from './header.svelte';
|
||||||
|
import Footer from './footer.svelte';
|
||||||
|
|
||||||
|
import Highlight from 'svelte-highlight';
|
||||||
|
import bash from 'svelte-highlight/languages/bash';
|
||||||
|
import agate from 'svelte-highlight/styles/agate';
|
||||||
|
|
||||||
|
let Carousel, Player, Video, DefaultUi;
|
||||||
|
onMount(async () => {
|
||||||
|
// Perform dynamic import of svelte-carousel because it breaks
|
||||||
|
// if imported during SSR
|
||||||
|
Carousel = (await import('svelte-carousel')).default;
|
||||||
|
({ Player, Video, DefaultUi } = await import('@vime/svelte'));
|
||||||
|
});
|
||||||
|
|
||||||
|
let images = [
|
||||||
|
{
|
||||||
|
path: '/lure-arch.webm',
|
||||||
|
caption: 'Recorded on Arch Linux with LURE commit f8af758'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/lure-debian.webm',
|
||||||
|
caption: 'Recorded on Debian 11 with LURE commit f8af758'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/lure-fedora.webm',
|
||||||
|
caption: 'Recorded on Fedora 37 with LURE commit f8af758'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/lure-alpine.webm',
|
||||||
|
caption: 'Recorded on Alpine Linux 3.17 with commit f8af758'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Home | LURE Web</title>
|
||||||
|
<meta name="description" content="LURE Web home page" />
|
||||||
|
{@html agate}
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<section class="container">
|
||||||
|
<p class="title">LURE</p>
|
||||||
|
<p class="subtitle">The user repo missing from most Linux distros</p>
|
||||||
|
<hr />
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<p class="card-header-title">Why should I use it?</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
LURE allows users to install software that may not be widely distributed through official
|
||||||
|
repositories, while still maintaining the convenience of installation through repository
|
||||||
|
sources. This includes features such as updates and simple uninstallation. Additionally,
|
||||||
|
LURE provides developers with a central location for all their users to use to install
|
||||||
|
their software.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<p class="card-header-title">How does it work?</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
LURE operates by abstracting package formats and package managers, enabling the creation
|
||||||
|
and installation of native packages automatically built from PKGBUILD-like bash scripts,
|
||||||
|
using the package manager already present on the system. As a result, packages installed
|
||||||
|
through LURE can be managed like any other package, without the need for additional
|
||||||
|
intervention from LURE for most operations.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="title">Installation</p>
|
||||||
|
<p>LURE can easily be installed by running its install script:</p>
|
||||||
|
<Highlight language={bash} code="curl https://www.elara.ws/lure.sh | bash" />
|
||||||
|
<p>
|
||||||
|
It's also available on the AUR as <a
|
||||||
|
href="https://aur.archlinux.org/packages/linux-user-repository-bin"
|
||||||
|
><code>linux-user-repository-bin</code></a
|
||||||
|
>
|
||||||
|
and distro packages are provided at the
|
||||||
|
<a href="https://gitea.elara.ws/Elara6331/lure/releases/latest">latest Gitea release</a>.
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<p class="title">Examples</p>
|
||||||
|
|
||||||
|
<!-- Use dynamically imported Carousel module -->
|
||||||
|
<svelte:component this={Carousel}>
|
||||||
|
{#each images as image}
|
||||||
|
<div class="has-text-centered">
|
||||||
|
<figure class="terminal-player mx-auto">
|
||||||
|
<svelte:component this={Player}>
|
||||||
|
<svelte:component this={Video}>
|
||||||
|
<source data-src={image.path} type="video/webm" />
|
||||||
|
</svelte:component>
|
||||||
|
<svelte:component this={DefaultUi} />
|
||||||
|
</svelte:component>
|
||||||
|
<figcaption>{image.caption ?? ''}</figcaption>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</svelte:component>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<script>
|
||||||
|
import Header from "../header.svelte";
|
||||||
|
import Footer from "../footer.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>FAQ | LURE Web</title>
|
||||||
|
<meta name="description" content="Frequently Asked Questions">
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Header/>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<p class="title">FAQ</p>
|
||||||
|
<br>
|
||||||
|
<p class="subtitle" id='distro-support'>Why isn't my distro supported?</p>
|
||||||
|
<p>
|
||||||
|
To support a distribution, LURE must be able to communicate with its package manager and create packages for it.
|
||||||
|
Communicating with the package manager is relatively straightforward, as LURE simply needs to be provided with the necessary
|
||||||
|
commands. However, the package formats are more complex. LURE uses <a href="https://github.com/goreleaser/nfpm">nFPM</a> to
|
||||||
|
handle package formats, and nFPM currently supports only deb, rpm, apk, and archlinux package formats. When developing LURE,
|
||||||
|
support for archlinux packages was not available in nFPM, so I added it through a pull request. Despite the simplicity of the
|
||||||
|
archlinux package format, implementing support required over 1,000 lines of code. As a result, supporting a distribution with
|
||||||
|
a different package format, such as xbps for Void Linux, is very complex and time-consuming.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p class="subtitle" id='flatpak-snap-appimage'>Why use LURE instead of Flatpak, Snap, or AppImage?</p>
|
||||||
|
<p>
|
||||||
|
LURE is not intended to address the same issues as Flatpak, Snap, and AppImage. These are containerized package formats that enable
|
||||||
|
the creation of a single package that can be used on all distributions. This cross-platform package contains the program and everything
|
||||||
|
else necessary for it to run, and it relies on containers to achieve this compatibility. However, containers can sometimes cause programs
|
||||||
|
to start slowly, fail to adhere to system settings, or be unable to access certain parts of the system. If you need most programs to
|
||||||
|
function consistently or you are using an older distribution with outdated packages, containerized formats may be the best choice. In contrast,
|
||||||
|
LURE does not use containers. It builds the program from source and installs it automatically. It also does not have its own package format.
|
||||||
|
Instead, it uses the same format as the distribution it is running on, so LURE packages behave like the distribution's native packages.
|
||||||
|
This means that unlike Snap and Flatpak, LURE is not a package manager; it simply uses the distribution's package manager, allowing you to
|
||||||
|
manage the packages installed through LURE even when LURE is not installed.
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
<p>
|
||||||
|
However, LURE also has some drawbacks. Since it builds programs from source, certain packages, particularly git packages that
|
||||||
|
retrieve the latest code from git, may not work on older distributions or distributions like Debian that have outdated packages.
|
||||||
|
Please consider your specific needs and whether these downsides are acceptable before using LURE. Additionally, similar to the AUR,
|
||||||
|
all packages are user-submitted and not vetted, so while it is unlikely, they may contain malicious code. It is the responsibility
|
||||||
|
of the user to review the build script to ensure this is not the case. If you come across a malicious package, please report it by
|
||||||
|
opening an issue on the git repository containing it.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p class="subtitle" id="handling-dependencies">How does LURE handle dependencies across distros?</p>
|
||||||
|
<p>
|
||||||
|
LURE manages dependencies across distributions by offering distro overrides, in which package maintainers can specify different
|
||||||
|
variables and functions for each distribution. The most specific override is given precedence. After the overrides are resolved,
|
||||||
|
LURE compares the resulting list of dependencies with the packages installed on the system and filters out any that are already
|
||||||
|
installed. For the remaining dependencies, LURE checks its own repositories to see if each package is available there. If it is,
|
||||||
|
LURE installs it from its repositories. If the package is not found in any repository, LURE passes the dependency on to the package
|
||||||
|
manager, which handles dependency resolution and installation.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p class="subtitle" id="testing">How can one test a LURE package to ensure it works?</p>
|
||||||
|
<p>
|
||||||
|
Docker is recommended for testing LURE packages on different distros. It provides a clean image of any distribution, which is very
|
||||||
|
useful for testing as it can help catch issues that might not manifest themselves on your system. Eventually, an automated
|
||||||
|
docker-based testing tool is planned, but in the meantime, this will need to be done manually for each distribution you're planning
|
||||||
|
to support. To find package names for each distribution, you can use <a href="https://repology.org">repology.org</a> and
|
||||||
|
<a href="https://pkgs.org">pkgs.org</a>. These websites maintain comprehensive databases of package repositories for various distributions.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p class="subtitle" id="icons">Can I use and modify LURE's icons?</p>
|
||||||
|
<p>
|
||||||
|
LURE's icons are available on the <a href="/icons">icons page</a> of this website and are licensed under CC-BY-NC-SA 4.0. This means that
|
||||||
|
you are free to share, modify, and use the icons for non-commercial purposes as long as you give appropriate credit and indicate any changes
|
||||||
|
made to the original icons.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p class="subtitle" id='adding-packages'>How do I add my own package to LURE?</p>
|
||||||
|
<p>
|
||||||
|
To add your own package, please refer to the <a href="https://github.com/Elara6331/lure/blob/master/docs/packages">package documentation</a> provided by LURE.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer/>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<script>
|
||||||
|
import Icon from '@iconify/svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<br style="margin-top: 20px">
|
||||||
|
<div class="hero is-dark is-small">
|
||||||
|
<div class="hero-body has-text-centered">
|
||||||
|
<p>Copyright © {new Date().getFullYear()} LURE Web Contributors. Licensed under the <a class="has-text-link" href="https://www.gnu.org/licenses/agpl-3.0-standalone.html">AGPLv3</a>.</p>
|
||||||
|
<div class="is-size-4">
|
||||||
|
<a href="https://gitea.elara.ws/Elara6331/lure-web"><Icon icon="cib:gitea"/></a>
|
||||||
|
<a href="https://github.com/Elara6331/lure-web"><Icon icon="mdi:github"/></a>
|
||||||
|
<a href="https://reddit.com/r/linux_user_repository"><Icon icon="ic:round-reddit"/></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<script>
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
|
||||||
|
import Icon from '@iconify/svelte';
|
||||||
|
|
||||||
|
function isActive(path) {
|
||||||
|
return $page.route.id == path ? 'is-active' : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
let navbarIsActive = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<nav class="navbar mb-5">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item" href="/"><img src="/lure-text-white.svg" alt="LURE Logo"></a>
|
||||||
|
<button class="navbar-burger {navbarIsActive ? 'is-active' : ''}" aria-label="menu" on:click={() => {navbarIsActive = !navbarIsActive}}>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="main-navbar" class="navbar-menu {navbarIsActive ? 'is-active' : ''}">
|
||||||
|
<div class="navbar-end">
|
||||||
|
<a class="navbar-item {isActive('/')}" href="/"><Icon icon="material-symbols:house" inline=true/> Home</a>
|
||||||
|
<a class="navbar-item {isActive('/pkgs')}" href="/pkgs"><Icon icon="mdi:package-variant-closed" inline=true/> Packages</a>
|
||||||
|
<a class="navbar-item {isActive('/faq')}" href="/faq"><Icon icon="mdi:question-mark-circle" inline=true/> FAQ</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
<script>
|
||||||
|
import Header from "../header.svelte";
|
||||||
|
import Footer from "../footer.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>FAQ | LURE Web</title>
|
||||||
|
<meta name="description" content="LURE Icons">
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Header/>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<p class="title">Icons</p>
|
||||||
|
<br>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column ">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<p class="card-header-title">
|
||||||
|
Without Text
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-content has-text-centered">
|
||||||
|
<figure class="image is-16by9">
|
||||||
|
<img src="/lure-no-text.svg" alt="LURE icon without text">
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item" href="/lure-no-text.svg" download>Download</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column ">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<p class="card-header-title">
|
||||||
|
With Text
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-content has-text-centered">
|
||||||
|
<figure class="image is-16by9">
|
||||||
|
<img src="/lure-text.svg" alt="LURE icon with text">
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item" href="/lure-text.svg" download>Download</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<p class="card-header-title">
|
||||||
|
White With Text
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-content has-text-centered">
|
||||||
|
<figure class="image is-16by9">
|
||||||
|
<img src="/lure-text-white.svg" alt="White LURE icon with white text">
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item" href="/lure-text-white.svg" download>Download</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="has-text-weight-bold">Note: The icons on this page are licensed under CC-BY-NC-SA 4.0 unless otherwise specified</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer/>
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
<script>
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
import { client } from 'twirpscript';
|
||||||
|
import { GetPkg } from '$lib/lure.pb';
|
||||||
|
import { LURE_WEB_API_URL } from '$env/static/public';
|
||||||
|
import { DoubleBounce } from 'svelte-loading-spinners';
|
||||||
|
|
||||||
|
import Header from '../../../header.svelte';
|
||||||
|
import Footer from '../../../footer.svelte';
|
||||||
|
|
||||||
|
import Icon from '@iconify/svelte';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
client.baseURL = LURE_WEB_API_URL;
|
||||||
|
client.prefix = '';
|
||||||
|
|
||||||
|
let currentURL = ``;
|
||||||
|
onMount(() => (currentURL = window.location.href));
|
||||||
|
|
||||||
|
function fullVer(pkg) {
|
||||||
|
let ver = `${pkg.version}-${pkg.release}`;
|
||||||
|
if (pkg.epoch != 0) {
|
||||||
|
ver = `${pkg.epoch}:${ver}`;
|
||||||
|
}
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
function objToMap(o) {
|
||||||
|
return new Map(Object.entries(o));
|
||||||
|
}
|
||||||
|
|
||||||
|
let modalActive = false;
|
||||||
|
|
||||||
|
function showModal() {
|
||||||
|
modalActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideModal() {
|
||||||
|
modalActive = false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{$page.params.name} Package | LURE Web</title>
|
||||||
|
<meta name="description" content="Information about the {$page.params.name} LURE package." />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<section class="container">
|
||||||
|
<a href="/pkgs"><Icon icon="material-symbols:arrow-back-rounded" inline="true" /> Back</a>
|
||||||
|
{#await GetPkg({ name: $page.params.name, repository: $page.params.repo })}
|
||||||
|
<center><DoubleBounce color="#375a7f" /></center>
|
||||||
|
{:then pkg}
|
||||||
|
<div class="modal {modalActive ? 'is-active' : ''}">
|
||||||
|
<div class="modal-background"/>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<p class="modal-card-title">Badge</p>
|
||||||
|
<button class="delete" aria-label="close" on:click={hideModal}/>
|
||||||
|
</header>
|
||||||
|
<section class="modal-card-body">
|
||||||
|
<img
|
||||||
|
src="{LURE_WEB_API_URL}/badge/{$page.params.repo}/{$page.params.name}"
|
||||||
|
alt="badge for {$page.params.name} package"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<p>Markdown</p>
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
value="[]({currentURL})"
|
||||||
|
readonly
|
||||||
|
/>
|
||||||
|
<p>HTML</p>
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
value='<a href="{currentURL}"><img src="{LURE_WEB_API_URL}/badge/{$page.params.repo}/{$page.params.name}" alt="LURE badge for {$page.params.name} package"></a>'
|
||||||
|
readonly
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
<footer class="modal-card-foot">
|
||||||
|
<button class="button is-primary" on:click={hideModal}>Close</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="title">{pkg.name}</p>
|
||||||
|
<p class="subtitle mb-3">{fullVer(pkg)}</p>
|
||||||
|
<a href="/pkg/{pkg.repository}/{pkg.name}/lure.sh" class="button is-primary mb-5">View lure.sh</a>
|
||||||
|
<button href="/pkg/{pkg.repository}/{pkg.name}/lure.sh" class="button is-success mb-5 ml-1" on:click={showModal}>View badge</button>
|
||||||
|
<div class="box">
|
||||||
|
<table class="table is-hoverable is-fullwidth">
|
||||||
|
<tbody>
|
||||||
|
{#if pkg.description != ''}
|
||||||
|
<tr>
|
||||||
|
<th>Description:</th>
|
||||||
|
<td>{pkg.description}</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{#if pkg.homepage != ''}
|
||||||
|
<tr>
|
||||||
|
<th>Homepage:</th>
|
||||||
|
<td><a href={pkg.homepage}>{pkg.homepage}</a></td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{#if pkg.maintainer != ''}
|
||||||
|
<tr>
|
||||||
|
<th>Maintainer:</th>
|
||||||
|
<td>{pkg.maintainer}</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{#if pkg.licenses.length != 0}
|
||||||
|
<tr>
|
||||||
|
<th>Licenses:</th>
|
||||||
|
<td>
|
||||||
|
{#each pkg.licenses as license, index}
|
||||||
|
{#if license.startsWith('custom')}
|
||||||
|
{license}{#if index + 1 < pkg.licenses.length}, {/if}
|
||||||
|
{:else}
|
||||||
|
<a href="https://spdx.org/licenses/{license}.html">{license}</a
|
||||||
|
>{#if index + 1 < pkg.licenses.length}, {/if}
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{#if pkg.architectures.length != 0}
|
||||||
|
<tr>
|
||||||
|
<th>Architectures:</th>
|
||||||
|
<td>{pkg.architectures.join(', ')}</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{#if pkg.conflicts.length != 0}
|
||||||
|
<tr>
|
||||||
|
<th>Conflicts:</th>
|
||||||
|
<td>{pkg.conflicts.join(', ')}</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{#if pkg.provides.length != 0}
|
||||||
|
<tr>
|
||||||
|
<th>Provides:</th>
|
||||||
|
<td>{pkg.provides.join(', ')}</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{#each [...objToMap(pkg.depends)] as [override, pkgList]}
|
||||||
|
<tr>
|
||||||
|
<th>Depends ({override == '' ? 'default' : override}):</th>
|
||||||
|
<td>{pkgList.entries.join(', ')}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
{#each [...objToMap(pkg.buildDepends)] as [override, pkgList]}
|
||||||
|
<tr>
|
||||||
|
<th>Build Depends ({override != '' ? override : 'default'}):</th>
|
||||||
|
<td>{pkgList.entries.join(', ')}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
<tr>
|
||||||
|
<th>Repository:</th>
|
||||||
|
<td>{pkg.repository}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{:catch err}
|
||||||
|
<div class="notification is-danger my-3">
|
||||||
|
Error: {err.msg}
|
||||||
|
</div>
|
||||||
|
{/await}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<script>
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
import { client } from 'twirpscript';
|
||||||
|
import { GetBuildScript } from '$lib/lure.pb';
|
||||||
|
import { LURE_WEB_API_URL } from '$env/static/public';
|
||||||
|
import { DoubleBounce } from 'svelte-loading-spinners';
|
||||||
|
|
||||||
|
import Highlight from 'svelte-highlight';
|
||||||
|
import bash from 'svelte-highlight/languages/bash';
|
||||||
|
import agate from 'svelte-highlight/styles/agate';
|
||||||
|
|
||||||
|
import Header from "../../../../header.svelte";
|
||||||
|
import Footer from "../../../../footer.svelte";
|
||||||
|
|
||||||
|
import Icon from '@iconify/svelte';
|
||||||
|
|
||||||
|
client.baseURL = LURE_WEB_API_URL
|
||||||
|
client.prefix = ""
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{$page.params.name} Build Script | LURE Web</title>
|
||||||
|
<meta name="description" content="The build script for the {$page.params.name} LURE package.">
|
||||||
|
{@html agate}
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Header/>
|
||||||
|
|
||||||
|
<section class="container">
|
||||||
|
<a href="."><Icon icon="material-symbols:arrow-back-rounded" inline=true/> Back</a>
|
||||||
|
{#await GetBuildScript({name: $page.params.name, repository: $page.params.repo})}
|
||||||
|
<center><DoubleBounce color="#375a7f" /></center>
|
||||||
|
{:then resp}
|
||||||
|
<p class="title">Build Script</p>
|
||||||
|
<p class="subtitle">{$page.params.repo} / {$page.params.name}</p>
|
||||||
|
<div class="box">
|
||||||
|
<Highlight language={bash} code={resp.script}/>
|
||||||
|
</div>
|
||||||
|
{:catch err}
|
||||||
|
<div class="notification is-danger my-3">
|
||||||
|
Error: {err.msg}
|
||||||
|
</div>
|
||||||
|
{/await}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer/>
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
<script>
|
||||||
|
import { client } from 'twirpscript';
|
||||||
|
import { Search } from '$lib/lure.pb';
|
||||||
|
import { searchReq } from '../../stores.js';
|
||||||
|
import { LURE_WEB_API_URL } from '$env/static/public';
|
||||||
|
|
||||||
|
import Header from "../header.svelte";
|
||||||
|
import Footer from "../footer.svelte";
|
||||||
|
import { DoubleBounce } from 'svelte-loading-spinners';
|
||||||
|
import Icon from '@iconify/svelte';
|
||||||
|
|
||||||
|
client.baseURL = LURE_WEB_API_URL
|
||||||
|
client.prefix = ""
|
||||||
|
|
||||||
|
let searchPromise = Search(
|
||||||
|
$searchReq ?? {
|
||||||
|
query: "",
|
||||||
|
limit: BigInt(0),
|
||||||
|
sortBy: "UNSORTED",
|
||||||
|
filterType: "NO_FILTER",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function onSubmit(e) {
|
||||||
|
let formData = new FormData(e.target);
|
||||||
|
let filterValue = formData.get('filter-value');
|
||||||
|
let req = {
|
||||||
|
query: formData.get('query'),
|
||||||
|
limit: BigInt(0),
|
||||||
|
sortBy: formData.get('sort-by'),
|
||||||
|
filterType: formData.get('filter'),
|
||||||
|
filterValue: filterValue == '' ? null : filterValue,
|
||||||
|
}
|
||||||
|
searchReq.set(req)
|
||||||
|
searchPromise = Search(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFilterChange(e) {
|
||||||
|
let filterVal = document.getElementById('filter-val');
|
||||||
|
|
||||||
|
if (e.target.value != "NO_FILTER") {
|
||||||
|
filterVal.classList.remove('is-hidden');
|
||||||
|
} else {
|
||||||
|
filterVal.classList.add('is-hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Package Search | LURE Web</title>
|
||||||
|
<meta name="description" content="Search for LURE packages">
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Header/>
|
||||||
|
|
||||||
|
<section class="container">
|
||||||
|
<p class="title">Package Search</p>
|
||||||
|
<form on:submit|preventDefault={onSubmit}>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" type="text" name="query" value="" placeholder="Query">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control select is-fullwidth">
|
||||||
|
<select name="sort-by">
|
||||||
|
<option value="UNSORTED" selected>Unsorted</option>
|
||||||
|
<option value="NAME">Sort by Name</option>
|
||||||
|
<option value="VERSION">Sort by Version</option>
|
||||||
|
<option value="REPOSITORY">Sort by Repository</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control select is-fullwidth">
|
||||||
|
<select name="filter" on:change={onFilterChange}>
|
||||||
|
<option value="NO_FILTER" selected>No Filter</option>
|
||||||
|
<option value="IN_REPOSITORY">In Repo</option>
|
||||||
|
<option value="SUPPORTS_ARCH">Supports Architecture</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input id="filter-val" class="input is-hidden" type="text" value="" name="filter-value" placeholder="Filter Value">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="submit" class="button is-fullwidth" value="Search">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{#await searchPromise}
|
||||||
|
<center><DoubleBounce color="#375a7f" /></center>
|
||||||
|
{:then resp}
|
||||||
|
{#each resp.packages as pkg}
|
||||||
|
<div class="card my-5">
|
||||||
|
<header class="card-header">
|
||||||
|
<p class="card-header-title">{pkg.repository} / {pkg.name}</p>
|
||||||
|
<div class="card-header-icon">{pkg.version}</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="card-content">
|
||||||
|
{pkg.description}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item" href="/pkg/{pkg.repository}/{pkg.name}">More info <Icon icon="material-symbols:arrow-forward-rounded" inline=true/></a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{#if resp.packages.length === 0}
|
||||||
|
<p class="subtitle has-text-centered has-text-danger my-5 is-fullwidth">No Results</p>
|
||||||
|
{/if}
|
||||||
|
{:catch err}
|
||||||
|
<div class="notification is-danger my-3">
|
||||||
|
Error: {err.msg}
|
||||||
|
</div>
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer/>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
|
export const searchReq = writable()
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/* Variables and mixins declared here will be available in all other SCSS files */ /* https://github.com/jgthms/bulma/issues/1293 */
|
||||||
|
$body-overflow-y: auto;
|
||||||
|
|
||||||
|
@import './darkly/variables.scss';
|
||||||
|
|
||||||
|
$family-sans-serif: "Ubuntu", sans-serif;
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
:root {
|
|
||||||
--primary: #0060A8;
|
|
||||||
--primary-hover: #026EBF;
|
|
||||||
--secondary: #0EAAAA;
|
|
||||||
--secondary-hover: #13b4b4;
|
|
||||||
--font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.centered {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.justify-space-between {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.close {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav:not([aria-label="breadcrumb"]) {
|
|
||||||
/* Workaround for horizontal overflow due to justify-content */
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add some spacing between the navbar items and the edge of the page */
|
|
||||||
nav:not([aria-label="breadcrumb"]) ul {
|
|
||||||
padding-left: 2rem;
|
|
||||||
padding-right: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav:not([aria-label="breadcrumb"]) a {
|
|
||||||
color: #dddedf;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav:not([aria-label="breadcrumb"]) a.active {
|
|
||||||
background-color: var(--primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav:not([aria-label="breadcrumb"]) a:hover:not(.active) {
|
|
||||||
color: var(--primary-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Keep the footer at the bottom */
|
|
||||||
body > main {
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make the footer smaller */
|
|
||||||
body > footer {
|
|
||||||
--block-spacing-vertical: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make card header and footer smaller */
|
|
||||||
article > header, article > footer {
|
|
||||||
padding-top: 1rem;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make the bottom margin on card headers smaller */
|
|
||||||
article > header {
|
|
||||||
margin-bottom: calc(var(--block-spacing-vertical) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make the top margin on card footers smaller */
|
|
||||||
article > footer {
|
|
||||||
margin-top: calc(var(--block-spacing-vertical) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fix the icon height to 100px to make cards uniform */
|
|
||||||
article > img.icon {
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
width: 30%;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
word-break: break-word;
|
|
||||||
cursor: text;
|
|
||||||
width: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre code {
|
|
||||||
cursor: text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.marginless {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[role="link"], a {
|
|
||||||
--color: var(--secondary);
|
|
||||||
}
|
|
||||||
|
After Width: | Height: | Size: 28 KiB |
@@ -1 +0,0 @@
|
|||||||
data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACNklEQVQ4jX3T32vXdRTH8cf5fL+zITLsJrroh3Rjd0VpfDPaXLMpDIbNgoTIiG6kLnPUP1AMU7qqC1G86Yfg1Km52Tf7zso5tnDRRVBBjrEugm7Km32/2+f99mIlrm297s7hvJ6cwzmHuzXb2ObX8bqfrm6+kxub6HTh+qjhyU3WULEiChtRU8ZlN77d/E/uIVmvFKM+mVoFiVXIn6/WNGNUM36zEIctxjm3Ki9rxnHNmLAYPV7f3lq7A9jaNSnplj2Az5RxVlv+XHYQU0qvrj/CXGOnm+M83vmDFM/IMSvbo/SFtnxS0hL6wPszVe/N3AX44+tBoSF5zcw37Sp5QNaDX4QJi/GKMAiO3tigMKx0ZBnw11eDijwknFPGGRUjGFLJhyRPKuOmcAwJp1TyKZH7hd8Lrfo7CkPCackB8rDQi3nhCDpFXjYXDijjJWGvwiH3FEereFA4rWK/7GNhF+YVupWxQ+E8xhT5uKXifmFA4V1vP/EBVJX5TUUU7u1J5hr3LZtzl6V4UeQhEZdU7dNfW3BiuhB53lvbzq99B3ONEc14Tiued6vyp1bULcQWzRizGC8YqC38d+sr15gdwwYpRrXlDkkXfpTtUsaIT6fa/x/wcPdFKfZjk+Syttyhd8djUvTJOpVGnJhuXx8AW7vOSHbLqpIrrlx71N7al5J9sp1KF3z0/R3f6l/4V5PfPaUVdc34Wyue1ff0rJPT/ZY84o3tH67rW6HxazX1ibpL1zvWK7kNwWfQQO79fcgAAAAASUVORK5CYII=
|
|
||||||
|
Before Width: | Height: | Size: 644 B |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,26 @@
|
|||||||
|
import preprocess from 'svelte-preprocess';
|
||||||
|
import adapter from '@sveltejs/adapter-node';
|
||||||
|
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||||
|
|
||||||
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
|
const config = {
|
||||||
|
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||||
|
// for more information about preprocessors
|
||||||
|
preprocess: [
|
||||||
|
vitePreprocess(),
|
||||||
|
preprocess({
|
||||||
|
scss: {
|
||||||
|
prependData: '@use "src/variables.scss" as *;'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
|
kit: {
|
||||||
|
adapter: adapter(),
|
||||||
|
env: {
|
||||||
|
publicPrefix: "LURE_WEB_"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
job "lure-web" {
|
||||||
|
region = "global"
|
||||||
|
datacenters = ["dc1"]
|
||||||
|
type = "service"
|
||||||
|
|
||||||
|
group "lure-web" {
|
||||||
|
network {
|
||||||
|
port "api" {
|
||||||
|
to = 8080
|
||||||
|
}
|
||||||
|
|
||||||
|
port "http" {
|
||||||
|
to = 3000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "lure-api-server" {
|
||||||
|
driver = "docker"
|
||||||
|
|
||||||
|
env {
|
||||||
|
LURE_API_GITHUB_SECRET = "${LURE_API_GITHUB_SECRET}"
|
||||||
|
|
||||||
|
// Hack to force Nomad to re-deploy the service
|
||||||
|
// instead of ignoring it
|
||||||
|
COMMIT_SHA = "${DRONE_COMMIT_SHA}"
|
||||||
|
}
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "elara6331/lure-api-server:latest"
|
||||||
|
ports = ["api"]
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "lure-api-server"
|
||||||
|
port = "api"
|
||||||
|
tags = [
|
||||||
|
"traefik.enable=true",
|
||||||
|
"traefik.http.routers.lure-api-server.rule=Host(`api.lure.elara.ws`)",
|
||||||
|
"traefik.http.routers.lure-api-server.tls.certresolver=letsencrypt"
|
||||||
|
]
|
||||||
|
|
||||||
|
check {
|
||||||
|
type = "tcp"
|
||||||
|
port = "api"
|
||||||
|
interval = "30s"
|
||||||
|
timeout = "2s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "lure-web" {
|
||||||
|
driver = "docker"
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "elara6331/lure-web:latest"
|
||||||
|
ports = ["http"]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "lure-web"
|
||||||
|
port = "http"
|
||||||
|
tags = [
|
||||||
|
"traefik.enable=true",
|
||||||
|
"traefik.http.routers.lure-web.rule=Host(`lure.elara.ws`)",
|
||||||
|
"traefik.http.routers.lure-web.tls.certresolver=letsencrypt",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
#macro("content"):
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
<li>About</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>About LURE</h1>
|
|
||||||
|
|
||||||
<section class="container">
|
|
||||||
<hgroup><h2>Why does LURE exist?</h2></hgroup>
|
|
||||||
<p>
|
|
||||||
LURE was created because packaging software for multiple Linux distros can be difficult and
|
|
||||||
error-prone, and installing those packages can be a nightmare for users unless they're available
|
|
||||||
in their distro's official repositories.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Take Discord for example. It only provides a deb file and a tar.gz file, and it's not available
|
|
||||||
in most official repositories. That means users of RPM distros have to manually install discord
|
|
||||||
using the tarball or rely on community-maintained repositories that don't always have
|
|
||||||
up-to-date versions of Discord. That's also made worse by the fact that Discord refuses to run
|
|
||||||
if there's a newer version available.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
LURE fixes that by always providing the most up to date version of Discord, which means all that
|
|
||||||
RPM users have to do is run <code>lure in discord</code> and LURE will get the tarball and
|
|
||||||
automatically build an RPM package out of it for them. When there's a newer version of Discord
|
|
||||||
available, users can just run <code>lure up</code> and LURE will automatically download the updated
|
|
||||||
version of Discord and install it. That also helps users of deb distros because it means they don't
|
|
||||||
have to manually download packages for software like Discord.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
<section class="container">
|
|
||||||
<hgroup><h2>How does LURE work?</h2></hgroup>
|
|
||||||
<p>
|
|
||||||
Similar to Arch Linux's AUR, LURE has a repository of shell scripts that tell it how to build a
|
|
||||||
package. When you run a LURE command, it updates its repository and interprets the shell script
|
|
||||||
for the package you want to install using its built-in bash implementation. Then, it uses the
|
|
||||||
code inside the script to build a file structure to be included in the final package. It detects
|
|
||||||
which distro you're running, resolves dependencies, detects which package manager you have and
|
|
||||||
which package format it uses, builds metadata for the package from the information in the shell
|
|
||||||
script, builds the final package, and then runs the install command for your package manager to
|
|
||||||
install it.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
<section class="container">
|
|
||||||
<hgroup><h2>How does LURE keep its packages up to date?</h2></hgroup>
|
|
||||||
<p>
|
|
||||||
LURE can automatically update its packages using a bot called
|
|
||||||
<a href="https://gitea.elara.ws/lure/lure-updater">lure-updater</a>. It accepts plugins that
|
|
||||||
detect when software is updated upstream and updates the LURE package accordingly. The plugins
|
|
||||||
that are currently running in my instance of the bot can be found in the
|
|
||||||
<a href="https://gitea.elara.ws/lure/updater-plugins">updater-plugins</a> repo. The
|
|
||||||
<code>discord-bin</code> package, for example, checks Discord's API every hour to see if they've
|
|
||||||
released an updated version, and if they have, it pushes an update to LURE's repo.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
<section class="container">
|
|
||||||
<hgroup><h2>How do I add my own package to LURE?</h2></hgroup>
|
|
||||||
<p>
|
|
||||||
LURE provides <a href="https://github.com/lure-sh/lure/blob/master/docs/packages">comprehensive documentation</a>
|
|
||||||
for packagers. If you need help with anything, feel free to ask on LURE's <a href="https://reddit.com/r/linux_user_repository">subreddit</a>.
|
|
||||||
If you find a bug or would like a feature to be added, please open an issue on LURE's git repo.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
<section class="container">
|
|
||||||
<hgroup><h2>Can I use and modify LURE's icons?</h2></hgroup>
|
|
||||||
<p>
|
|
||||||
LURE's icons are available on the <a href="/icons">icons page</a> of this site. They're licensed
|
|
||||||
under CC-BY-NC-SA 4.0, which means you're free to share, modify, and use the icons for non-commercial
|
|
||||||
purposes as long as you give appropriate credit and indicate any changes made to the original icons.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
#!macro
|
|
||||||
|
|
||||||
#include("base.html", title = "About", desc = "About the Linux User Repository")
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html data-theme="dark">
|
|
||||||
<head>
|
|
||||||
<title>#(title) | LURE Web</title>
|
|
||||||
<meta name="description" content='#(desc | title + " on LURE Web")' />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.8" />
|
|
||||||
<link rel="stylesheet" href="/static/css/pico.min.css">
|
|
||||||
<link rel="stylesheet" href="/static/css/lure.css">
|
|
||||||
<link rel="icon" href="/static/icons/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/"><img src="/static/icons/lure-text-white.svg" alt="LURE Logo" width="85"></a></li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/" class='#(title == "Home" ? "active" : "")'>Home</a></li>
|
|
||||||
<li><a href="/pkgs" class='#(title == "Package Search" ? "active" : "")'>Packages</a></li>
|
|
||||||
<li><a href="/about" class='#(title == "About" ? "active" : "")'>About</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<main class="container">
|
|
||||||
#macro("content")
|
|
||||||
</main>
|
|
||||||
|
|
||||||
|
|
||||||
<footer class="container">
|
|
||||||
<div class="headings marginless">
|
|
||||||
<h2>Copyright © #(now().Year()) LURE Web Contributors</h2>
|
|
||||||
</div>
|
|
||||||
<a href="https://github.com/lure-sh/lure-web" target="_blank">Source Code</a>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#macro("content"):
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
<li>Error</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Error</h1>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
|
|
||||||
<section class="container centered">
|
|
||||||
<div>
|
|
||||||
<hgroup>
|
|
||||||
<h1>Something Went Wrong!</h1>
|
|
||||||
<h2>Error #(error.StatusCode): #(error.StatusText())</h2>
|
|
||||||
</hgroup>
|
|
||||||
<pre><code>#(error.Msg)</code></pre>
|
|
||||||
<a href="/" role="button">Go Back Home</a>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
#!macro
|
|
||||||
|
|
||||||
#include("base.html", title = sprintf("Error %d", error.StatusCode), desc = sprintf("Error %d: %s", error.StatusCode, error.StatusText()))
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#macro("content"):
|
|
||||||
<section class="container centered">
|
|
||||||
<img src="/static/icons/lure-no-text.svg" alt="LURE logo without text" width="200">
|
|
||||||
<hgroup>
|
|
||||||
<h1>LURE</h1>
|
|
||||||
<h2>The community repository missing from your Linux distro</h2>
|
|
||||||
</hgroup>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="container">
|
|
||||||
<hgroup>
|
|
||||||
<h1>What does LURE do?</h1>
|
|
||||||
<h2>LURE allows you to:</h2>
|
|
||||||
</hgroup>
|
|
||||||
<ul>
|
|
||||||
<li>Access a wide range of software beyond what's available in official repositories</li>
|
|
||||||
<li>Get new versions of software as they come out, before official repositories ship them</li>
|
|
||||||
<li>Install unofficial software without having to deal with a separate package manager</li>
|
|
||||||
<li>Release software for Linux without having to package it for different distributions</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
<section class="container">
|
|
||||||
<hgroup>
|
|
||||||
<h1>Install LURE</h1>
|
|
||||||
<h2>Paste this into your Linux terminal and the install script will set everything up for you</h2>
|
|
||||||
</hgroup>
|
|
||||||
<pre><code>curl -fsSL lure.sh/install | bash</code></pre>
|
|
||||||
<p>LURE is also available on the AUR as <code>linux-user-repository-bin</code> and distro packages are provided at the <a href="https://gitea.elara.ws/lure/lure/releases/latest">latest Gitea release</a></p>
|
|
||||||
</section>
|
|
||||||
#!macro
|
|
||||||
|
|
||||||
#include("base.html", title = "Home", desc = "The community repository missing from your Linux distro")
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#macro("content"):
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
<li>Icons</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Icons</h1>
|
|
||||||
|
|
||||||
<section class="container">
|
|
||||||
<div class="grid">
|
|
||||||
<div>
|
|
||||||
<article class="centered">
|
|
||||||
<header><strong>Without Text</strong></header>
|
|
||||||
<img class="icon" src="/static/icons/lure-no-text.svg" alt="LURE icon without text">
|
|
||||||
<footer><a href="/static/icons/lure-no-text.svg" download>Download</a></footer>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<article class="centered">
|
|
||||||
<header><strong>With Text</strong></header>
|
|
||||||
<img class="icon" src="/static/icons/lure-text.svg" alt="LURE icon with text">
|
|
||||||
<footer><a href="/static/icons/lure-text.svg" download>Download</a></footer>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<article class="centered">
|
|
||||||
<header><strong>White With Text</strong></header>
|
|
||||||
<img class="icon" src="/static/icons/lure-text-white.svg" alt="LURE icon with text">
|
|
||||||
<footer><a href="/static/icons/lure-text-white.svg" download>Download</a></footer>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<strong>Note: The icons on this page are licensed under CC-BY-NC-SA 4.0 unless otherwise specified</strong>
|
|
||||||
</section>
|
|
||||||
#!macro
|
|
||||||
|
|
||||||
#include("base.html", title = "Icons", desc = "Linux User Repository icons and logos")
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
#macro("content"):
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
<li><a href="/pkgs">Packages</a></li>
|
|
||||||
<li>#(pkg.Name)</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
<hgroup>
|
|
||||||
<h1>#(pkg.Name)</h1>
|
|
||||||
<h2>#(pkg.FullVersion())</h2>
|
|
||||||
</hgroup>
|
|
||||||
<a href="/pkg/#(pkg.Repository)/#(pkg.Name)/script" role="button">View script</a>
|
|
||||||
<a href="javascript:openModal()" role="button" class="secondary">View badge</a>
|
|
||||||
<br>
|
|
||||||
<article>
|
|
||||||
<h3 >Package Information</h3>
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
#if(pkg.Description != ""):
|
|
||||||
<tr>
|
|
||||||
<th>Description:</th>
|
|
||||||
<td>#(pkg.Description)</td>
|
|
||||||
</tr>
|
|
||||||
#!if
|
|
||||||
#if(pkg.Homepage != ""):
|
|
||||||
<tr>
|
|
||||||
<th>Homepage:</th>
|
|
||||||
<td><a href="#(pkg.Homepage)" target="_blank">#(pkg.Homepage)</a></td>
|
|
||||||
</tr>
|
|
||||||
#!if
|
|
||||||
#if(pkg.Maintainer != ""):
|
|
||||||
<tr>
|
|
||||||
<th>Maintainer:</th>
|
|
||||||
<td>#(pkg.Maintainer)</td>
|
|
||||||
</tr>
|
|
||||||
#!if
|
|
||||||
#if(len(pkg.Licenses) != 0):
|
|
||||||
<tr>
|
|
||||||
<th>Licenses:</th>
|
|
||||||
<td>
|
|
||||||
#for(i, license in pkg.Licenses):
|
|
||||||
#if(hasPrefix(license, "custom")):
|
|
||||||
#(license)#if(i != len(pkg.Licenses) - 1):, #!if
|
|
||||||
#else:
|
|
||||||
<a href="https://spdx.org/licenses/#(license).html" target="_blank">#(license)</a>#if(i != len(pkg.Licenses) - 1):, #!if
|
|
||||||
#!if
|
|
||||||
#!for
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
#!if
|
|
||||||
#if(len(pkg.Architectures) != 0):
|
|
||||||
<tr>
|
|
||||||
<th>Architectures:</th>
|
|
||||||
<td>#(join(pkg.Architectures, ", "))</td>
|
|
||||||
</tr>
|
|
||||||
#!if
|
|
||||||
#if(len(pkg.Conflicts) != 0):
|
|
||||||
<tr>
|
|
||||||
<th>Conflicts:</th>
|
|
||||||
<td>#(join(pkg.Conflicts, ", "))</td>
|
|
||||||
</tr>
|
|
||||||
#!if
|
|
||||||
#if(len(pkg.Provides) != 0):
|
|
||||||
<tr>
|
|
||||||
<th>Provides:</th>
|
|
||||||
<td>#(join(pkg.Provides, ", "))</td>
|
|
||||||
</tr>
|
|
||||||
#!if
|
|
||||||
<tr>
|
|
||||||
<th>Repository:</th>
|
|
||||||
<td>#(pkg.Repository)</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
#if(len(pkg.Depends) > 0):
|
|
||||||
<article>
|
|
||||||
<h3 >Runtime Dependencies</h3>
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
#for(override, pkgList in pkg.Depends):
|
|
||||||
<tr>
|
|
||||||
<th>#(override == "" ? "default" : override):</th>
|
|
||||||
<td>#(join(pkgList, ", "))</td>
|
|
||||||
</tr>
|
|
||||||
#!for
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</article>
|
|
||||||
#!if
|
|
||||||
|
|
||||||
#if(len(pkg.BuildDepends) > 0):
|
|
||||||
<article>
|
|
||||||
<h3 >Build Dependencies</h3>
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
#for(override, pkgList in pkg.BuildDepends):
|
|
||||||
<tr>
|
|
||||||
<th>#(override == "" ? "default" : override):</th>
|
|
||||||
<td>#(join(pkgList, ", "))</td>
|
|
||||||
</tr>
|
|
||||||
#!for
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</article>
|
|
||||||
#!if
|
|
||||||
|
|
||||||
<dialog id="badgeModal">
|
|
||||||
<article style="min-width: 60%">
|
|
||||||
<header>
|
|
||||||
<strong>Badge</strong>
|
|
||||||
<a aria-label="Close" class="close" href="javascript:closeModal()"></a>
|
|
||||||
</header>
|
|
||||||
<p class="centered">
|
|
||||||
<img src="#(url)/badge.svg" alt="LURE badge for #(pkg.Name)">
|
|
||||||
<hr>
|
|
||||||
</p>
|
|
||||||
<label for="badgeMarkdown">Markdown</label>
|
|
||||||
<input id="badgeMarkdown" value="[/badge.svg)](#(url))" readonly />
|
|
||||||
<label for="badgeHTML">HTML</label>
|
|
||||||
<input id="badgeHTML" value='<a href="#(url)"><img src="#(url)/badge.svg" alt="LURE badge for #(pkg.Name)">' readonly />
|
|
||||||
</article>
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function openModal() {
|
|
||||||
let modal = document.getElementById("badgeModal");
|
|
||||||
document.documentElement.classList.add('modal-is-open');
|
|
||||||
modal.setAttribute('open', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeModal() {
|
|
||||||
let modal = document.getElementById("badgeModal");
|
|
||||||
document.documentElement.classList.remove('modal-is-open');
|
|
||||||
modal.removeAttribute('open');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
#!macro
|
|
||||||
|
|
||||||
#include("base.html", title = pkg.Name + " Package", desc = sprintf("%s %s - %s", pkg.Name, pkg.FullVersion(), pkg.Description))
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
#macro("content"):
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
<li>Packages</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Package Search</h1>
|
|
||||||
|
|
||||||
<form action="/pkgs">
|
|
||||||
<input type="text" id="query" name="q" value='#(query.Get("q"))' placeholder="Query"/>
|
|
||||||
<div class="grid">
|
|
||||||
<div>
|
|
||||||
<select name="sort">
|
|
||||||
<option value="">Unsorted</option>
|
|
||||||
<option value="name" #(query.Get("sort") == "name" ? "selected" : "")>Sort by Name</option>
|
|
||||||
<option value="version" #(query.Get("sort") == "version" ? "selected" : "")>Sort by Version</option>
|
|
||||||
<option value="repo" #(query.Get("sort") == "repo" ? "selected" : "")>Sort by Repository</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<select name="filter" onchange="onFilterChange(event)">
|
|
||||||
<option value="">No Filter</option>
|
|
||||||
<option value="inrepo" #(query.Get("filter") == "inrepo" ? "selected" : "")>In Repo</option>
|
|
||||||
<option value="arch" #(query.Get("filter") == "arch" ? "selected" : "")>Supports Architecture</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<input class='#(query.Get("filter") == "" ? "hidden" : "")' type="text" id="filterValue" name="fv" value='#(query.Get("fv"))' placeholder="Filter Value"/>
|
|
||||||
<button type="submit">Search</button>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
#for(pkg in pkgs):
|
|
||||||
<article>
|
|
||||||
<header>
|
|
||||||
<div class="justify-space-between">
|
|
||||||
<span class="left"><strong>#(pkg.Repository) / #(pkg.Name)</strong></span>
|
|
||||||
<span class="right">#(pkg.Version)</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<p>#(pkg.Description)</p>
|
|
||||||
<footer class="centered">
|
|
||||||
<a href="/pkg/#(pkg.Repository)/#(pkg.Name)">More Info →</a>
|
|
||||||
</footer>
|
|
||||||
</article>
|
|
||||||
#!for
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function onFilterChange(e) {
|
|
||||||
let filterValue = document.getElementById('filterValue');
|
|
||||||
if (e.srcElement.value == '') {
|
|
||||||
filterValue.classList.add('hidden');
|
|
||||||
} else {
|
|
||||||
filterValue.classList.remove('hidden');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
#!macro
|
|
||||||
|
|
||||||
#include("base.html", title = "Package Search", desc = "Search for LURE packages")
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#macro("content"):
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
<li><a href="/pkgs">Packages</a></li>
|
|
||||||
<li><a href="/pkg/#(repoName)/#(pkgName)">#(pkgName)</a></li>
|
|
||||||
<li>Script</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<hgroup>
|
|
||||||
<h1>Build Script</h1>
|
|
||||||
<h2>#(repoName) / #(pkgName)</h2>
|
|
||||||
</hgroup>
|
|
||||||
|
|
||||||
#(script)
|
|
||||||
#!macro
|
|
||||||
|
|
||||||
#include("base.html", title = pkgName + " Build Script", desc = sprintf("Build script for the %s package", pkgName))
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "./.svelte-kit/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": false,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||||
|
//
|
||||||
|
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||||
|
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
|
|
||||||
|
/** @type {import('vite').UserConfig} */
|
||||||
|
const config = {
|
||||||
|
plugins: [sveltekit()],
|
||||||
|
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
additionalData: '@use "src/variables.scss" as *;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/uptrace/bunrouter"
|
|
||||||
"go.elara.ws/logger/log"
|
|
||||||
"lure.sh/lure/pkg/repos"
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerWebhook(ctx context.Context, mux *bunrouter.Router) {
|
|
||||||
g := mux.WithMiddleware(apiErrorHandler)
|
|
||||||
|
|
||||||
g.POST("/webhook", func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
||||||
if req.Header.Get("X-GitHub-Event") != "push" {
|
|
||||||
return HTTPError{http.StatusBadRequest, "only push events are accepted by this bot"}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := verifySecure(req.Request)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
go pullRepos(ctx)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifySecure(req *http.Request) error {
|
|
||||||
sigStr := req.Header.Get("X-Hub-Signature-256")
|
|
||||||
sig, err := hex.DecodeString(strings.TrimPrefix(sigStr, "sha256="))
|
|
||||||
if err != nil {
|
|
||||||
return HTTPError{http.StatusBadRequest, "invalid hmac value"}
|
|
||||||
}
|
|
||||||
|
|
||||||
secretStr, ok := os.LookupEnv("LURE_WEB_GITHUB_SECRET")
|
|
||||||
if !ok {
|
|
||||||
return HTTPError{http.StatusInternalServerError, "LURE_WEB_GITHUB_SECRET must be set to the secret used for setting up the github webhook"}
|
|
||||||
}
|
|
||||||
secret := []byte(secretStr)
|
|
||||||
|
|
||||||
h := hmac.New(sha256.New, secret)
|
|
||||||
_, err = io.Copy(h, req.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hmac.Equal(h.Sum(nil), sig) {
|
|
||||||
log.Warn("Insecure webhook request").
|
|
||||||
Str("from", req.RemoteAddr).
|
|
||||||
Bytes("sig", sig).
|
|
||||||
Bytes("hmac", h.Sum(nil)).
|
|
||||||
Send()
|
|
||||||
|
|
||||||
return HTTPError{http.StatusUnauthorized, "insecure webhook request"}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var pullMtx sync.Mutex
|
|
||||||
|
|
||||||
func pullRepos(ctx context.Context) {
|
|
||||||
pullMtx.Lock()
|
|
||||||
defer pullMtx.Unlock()
|
|
||||||
|
|
||||||
err := repos.Pull(ctx, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("Error while pulling repositories").Err(err).Send()
|
|
||||||
}
|
|
||||||
}
|
|
||||||