forked from vieter-v/vieter
Merge branch 'libarchive-link' into dev
commit
8882e99757
|
@ -1,4 +1,4 @@
|
||||||
*
|
*
|
||||||
|
|
||||||
!vieter/
|
!src/
|
||||||
!Makefile
|
!Makefile
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
*.c
|
*.c
|
||||||
data/
|
data/
|
||||||
vieter/vieter
|
|
||||||
|
# Build artifacts
|
||||||
|
vieter
|
||||||
|
dvieter
|
||||||
|
pvieter
|
||||||
|
vieter.c
|
||||||
|
|
||||||
# Ignore testing files
|
# Ignore testing files
|
||||||
*.pkg*
|
*.pkg*
|
||||||
|
|
||||||
vieter.log
|
vieter.log
|
||||||
|
|
||||||
|
# External lib; gets added by Makefile
|
||||||
|
libarchive-*
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
pipeline:
|
||||||
|
vieter:
|
||||||
|
image: 'chewingbever/vlang:latest'
|
||||||
|
group: 'build'
|
||||||
|
commands:
|
||||||
|
- make vieter
|
||||||
|
|
||||||
|
debug:
|
||||||
|
image: 'chewingbever/vlang:latest'
|
||||||
|
group: 'build'
|
||||||
|
commands:
|
||||||
|
- make debug
|
||||||
|
|
||||||
|
prod:
|
||||||
|
image: 'chewingbever/vlang:latest'
|
||||||
|
group: 'build'
|
||||||
|
commands:
|
||||||
|
- make prod
|
|
@ -0,0 +1,5 @@
|
||||||
|
pipeline:
|
||||||
|
lint:
|
||||||
|
image: 'chewingbever/vlang:latest'
|
||||||
|
commands:
|
||||||
|
- make fmt
|
|
@ -0,0 +1,24 @@
|
||||||
|
branches: [main, dev]
|
||||||
|
|
||||||
|
pipeline:
|
||||||
|
dev:
|
||||||
|
image: plugins/docker
|
||||||
|
secrets: [ docker_username, docker_password ]
|
||||||
|
settings:
|
||||||
|
repo: chewingbever/vieter
|
||||||
|
tag: dev
|
||||||
|
when:
|
||||||
|
event: push
|
||||||
|
branch: dev
|
||||||
|
|
||||||
|
release:
|
||||||
|
image: plugins/docker
|
||||||
|
secrets: [ docker_username, docker_password ]
|
||||||
|
settings:
|
||||||
|
repo: chewingbever/vieter
|
||||||
|
tag:
|
||||||
|
- latest
|
||||||
|
- $CI_COMMIT_TAG
|
||||||
|
when:
|
||||||
|
event: tag
|
||||||
|
branch: main
|
23
Dockerfile
23
Dockerfile
|
@ -1,20 +1,21 @@
|
||||||
FROM archlinux:latest AS builder
|
FROM chewingbever/vlang:latest AS builder
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /app
|
||||||
COPY vieter ./vieter
|
|
||||||
|
# Copy over source code & build production binary
|
||||||
|
COPY src ./src
|
||||||
COPY Makefile ./
|
COPY Makefile ./
|
||||||
|
RUN make prod
|
||||||
RUN pacman \
|
|
||||||
-Syu --noconfirm --needed \
|
|
||||||
gcc git openssl make && \
|
|
||||||
make customv && \
|
|
||||||
jjr-v/v -prod vieter
|
|
||||||
|
|
||||||
|
|
||||||
FROM archlinux:latest
|
FROM alpine:3.15
|
||||||
|
|
||||||
ENV REPO_DIR=/data
|
ENV REPO_DIR=/data
|
||||||
|
|
||||||
COPY --from=builder /src/vieter/vieter /usr/local/bin/
|
RUN apk update && \
|
||||||
|
apk add --no-cache \
|
||||||
|
libarchive
|
||||||
|
|
||||||
|
COPY --from=builder /app/pvieter /usr/local/bin/vieter
|
||||||
|
|
||||||
ENTRYPOINT [ "/usr/local/bin/vieter" ]
|
ENTRYPOINT [ "/usr/local/bin/vieter" ]
|
||||||
|
|
66
Makefile
66
Makefile
|
@ -1,18 +1,60 @@
|
||||||
|
# =====CONFIG=====
|
||||||
|
SRC_DIR := src
|
||||||
|
SOURCES != find '$(SRC_DIR)' -iname '*.v'
|
||||||
|
|
||||||
|
LARCHIVE_VER := 3.5.2
|
||||||
|
LARCHIVE_DIR := libarchive-$(LARCHIVE_VER)
|
||||||
|
LARCHIVE_LIB := $(LARCHIVE_DIR)/libarchive/libarchive.so
|
||||||
|
|
||||||
|
# Custom V command for linking libarchive
|
||||||
|
# V := LDFLAGS=$(PWD)/$(LARCHIVE_LIB) v -cflags '-I$(PWD)/$(LARCHIVE_DIR) -I $(PWD)/$(LARCHIVE_DIR)'
|
||||||
|
V := v
|
||||||
|
|
||||||
|
all: vieter
|
||||||
|
|
||||||
|
# =====COMPILATION=====
|
||||||
|
# Regular binary
|
||||||
|
vieter: $(SOURCES)
|
||||||
|
$(V) -g -o vieter $(SRC_DIR)
|
||||||
|
|
||||||
|
# Debug build using gcc
|
||||||
|
.PHONY: debug
|
||||||
|
debug: dvieter
|
||||||
|
dvieter: $(SOURCES)
|
||||||
|
$(V) -keepc -cg -cc gcc -o dvieter $(SRC_DIR)
|
||||||
|
|
||||||
|
# Optimised production build
|
||||||
|
.PHONY: prod
|
||||||
|
prod: pvieter
|
||||||
|
pvieter: $(SOURCES)
|
||||||
|
$(V) -o pvieter -prod $(SRC_DIR)
|
||||||
|
|
||||||
|
.PHONY: c
|
||||||
|
c:
|
||||||
|
$(V) -o vieter.c $(SRC_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
# =====EXECUTION=====
|
||||||
|
# Run the server in the default 'data' directory
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run:
|
run: vieter
|
||||||
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG v -cg run vieter
|
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG ./vieter
|
||||||
|
|
||||||
.PHONY: run-prod
|
.PHONY: run-prod
|
||||||
run-prod:
|
run-prod: prod
|
||||||
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG v -prod run vieter
|
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG ./vieter-prod
|
||||||
|
|
||||||
|
# Same as run, but restart when the source code changes
|
||||||
.PHONY: watch
|
.PHONY: watch
|
||||||
watch:
|
watch:
|
||||||
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG v watch run vieter
|
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG $(V) watch run vieter
|
||||||
|
|
||||||
|
|
||||||
|
# =====OTHER=====
|
||||||
|
# Format the V codebase
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
v fmt -w vieter
|
v fmt -w $(SRC_DIR)
|
||||||
|
|
||||||
# Pulls & builds my personal build of the v compiler, required for this project to function
|
# Pulls & builds my personal build of the v compiler, required for this project to function
|
||||||
.PHONY: customv
|
.PHONY: customv
|
||||||
|
@ -23,3 +65,15 @@ customv:
|
||||||
--single-branch \
|
--single-branch \
|
||||||
https://github.com/ChewingBever/v jjr-v
|
https://github.com/ChewingBever/v jjr-v
|
||||||
'$(MAKE)' -C jjr-v
|
'$(MAKE)' -C jjr-v
|
||||||
|
|
||||||
|
|
||||||
|
# =====LIBARCHIVE=====
|
||||||
|
.PHONY: libarchive
|
||||||
|
libarchive: $(LARCHIVE_LIB)
|
||||||
|
$(LARCHIVE_LIB):
|
||||||
|
curl -o - "https://libarchive.org/downloads/libarchive-${LARCHIVE_VER}.tar.gz" | tar xzf -
|
||||||
|
cd "libarchive-${LARCHIVE_VER}" && cmake .
|
||||||
|
'$(MAKE)' -C "libarchive-${LARCHIVE_VER}"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf '$(LARCHIVE_DIR)' 'data' 'vieter' 'dvieter' 'pvieter' 'vieter.c'
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
module archive
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
pub fn get_pkg_info(pkg_path string) ?string {
|
||||||
|
if !os.is_file(pkg_path) {
|
||||||
|
return error("'$pkg_path' doesn't exist or isn't a file.")
|
||||||
|
}
|
||||||
|
|
||||||
|
a := C.archive_read_new()
|
||||||
|
entry := C.archive_entry_new()
|
||||||
|
mut r := 0
|
||||||
|
|
||||||
|
C.archive_read_support_filter_all(a)
|
||||||
|
C.archive_read_support_format_all(a)
|
||||||
|
|
||||||
|
// TODO find out where does this 10240 come from
|
||||||
|
r = C.archive_read_open_filename(a, &char(pkg_path.str), 10240)
|
||||||
|
defer {
|
||||||
|
C.archive_read_free(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if r != C.ARCHIVE_OK {
|
||||||
|
return error('Failed to open package.')
|
||||||
|
}
|
||||||
|
|
||||||
|
// We iterate over every header in search of the .PKGINFO one
|
||||||
|
mut buf := voidptr(0)
|
||||||
|
for C.archive_read_next_header(a, &entry) == C.ARCHIVE_OK {
|
||||||
|
if C.strcmp(C.archive_entry_pathname(entry), c'.PKGINFO') == 0 {
|
||||||
|
size := C.archive_entry_size(entry)
|
||||||
|
|
||||||
|
// TODO can this unsafe block be avoided?
|
||||||
|
buf = unsafe { malloc(size) }
|
||||||
|
C.archive_read_data(a, voidptr(buf), size)
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
C.archive_read_data_skip(a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unsafe { cstring_to_vstring(&char(buf)) }
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
module archive
|
||||||
|
|
||||||
|
#flag -larchive
|
||||||
|
|
||||||
|
#include "archive.h"
|
||||||
|
|
||||||
|
struct C.archive {}
|
||||||
|
|
||||||
|
// Create a new archive struct
|
||||||
|
fn C.archive_read_new() &C.archive
|
||||||
|
fn C.archive_read_support_filter_all(&C.archive)
|
||||||
|
fn C.archive_read_support_format_all(&C.archive)
|
||||||
|
|
||||||
|
// Open an archive for reading
|
||||||
|
fn C.archive_read_open_filename(&C.archive, &char, int) int
|
||||||
|
|
||||||
|
// Go to next entry header in archive
|
||||||
|
fn C.archive_read_next_header(&C.archive, &&C.archive_entry) int
|
||||||
|
|
||||||
|
// Skip reading the current entry
|
||||||
|
fn C.archive_read_data_skip(&C.archive)
|
||||||
|
|
||||||
|
// Free an archive
|
||||||
|
fn C.archive_read_free(&C.archive) int
|
||||||
|
|
||||||
|
// Read an archive entry's contents into a pointer
|
||||||
|
fn C.archive_read_data(&C.archive, voidptr, int)
|
||||||
|
|
||||||
|
#include "archive_entry.h"
|
||||||
|
|
||||||
|
struct C.archive_entry {}
|
||||||
|
|
||||||
|
// Create a new archive_entry struct
|
||||||
|
fn C.archive_entry_new() &C.archive_entry
|
||||||
|
|
||||||
|
// Get the filename of the given entry
|
||||||
|
fn C.archive_entry_pathname(&C.archive_entry) &char
|
||||||
|
|
||||||
|
// Get an entry's file size
|
||||||
|
// Note: this function actually returns an i64, but as this can't be used as an arugment to malloc, we'll just roll with it & assume an entry is never bigger than 4 gigs
|
||||||
|
fn C.archive_entry_size(&C.archive_entry) int
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Compare two C strings; 0 means they're equal
|
||||||
|
fn C.strcmp(&char, &char) int
|
|
@ -5,6 +5,7 @@ import os
|
||||||
import log
|
import log
|
||||||
import io
|
import io
|
||||||
import repo
|
import repo
|
||||||
|
import archive
|
||||||
|
|
||||||
const port = 8000
|
const port = 8000
|
||||||
|
|
||||||
|
@ -100,3 +101,12 @@ fn main() {
|
||||||
repo: repo
|
repo: repo
|
||||||
}, port)
|
}, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fn main() {
|
||||||
|
// // archive.list_filenames()
|
||||||
|
// info := archive.get_pkg_info('test/jjr-joplin-desktop-2.6.10-4-x86_64.pkg.tar.zst') or {
|
||||||
|
// eprintln(err.msg)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// println(info)
|
||||||
|
// }
|
Loading…
Reference in New Issue