Merge branch 'libarchive-link' into dev
ci/woodpecker/push/build Pipeline was successful Details
ci/woodpecker/push/lint Pipeline was successful Details
ci/woodpecker/push/publish Pipeline failed Details

pull/14/head
Jef Roosens 2022-01-13 13:57:01 +01:00
commit 8882e99757
Signed by: Jef Roosens
GPG Key ID: 955C0660072F691F
16 changed files with 228 additions and 19 deletions

View File

@ -1,4 +1,4 @@
*
!vieter/
!src/
!Makefile

10
.gitignore vendored
View File

@ -1,8 +1,16 @@
*.c
data/
vieter/vieter
# Build artifacts
vieter
dvieter
pvieter
vieter.c
# Ignore testing files
*.pkg*
vieter.log
# External lib; gets added by Makefile
libarchive-*

View File

@ -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

View File

@ -0,0 +1,5 @@
pipeline:
lint:
image: 'chewingbever/vlang:latest'
commands:
- make fmt

View File

@ -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

View File

@ -1,20 +1,21 @@
FROM archlinux:latest AS builder
FROM chewingbever/vlang:latest AS builder
WORKDIR /src
COPY vieter ./vieter
WORKDIR /app
# Copy over source code & build production binary
COPY src ./src
COPY Makefile ./
RUN pacman \
-Syu --noconfirm --needed \
gcc git openssl make && \
make customv && \
jjr-v/v -prod vieter
RUN make prod
FROM archlinux:latest
FROM alpine:3.15
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" ]

View File

@ -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
run:
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG v -cg run vieter
run: vieter
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG ./vieter
.PHONY: run-prod
run-prod:
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG v -prod run vieter
run-prod: prod
API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG ./vieter-prod
# Same as run, but restart when the source code changes
.PHONY: 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
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
.PHONY: customv
@ -23,3 +65,15 @@ customv:
--single-branch \
https://github.com/ChewingBever/v 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'

View File

@ -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)) }
}

View File

@ -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

View File

@ -5,6 +5,7 @@ import os
import log
import io
import repo
import archive
const port = 8000
@ -100,3 +101,12 @@ fn main() {
repo: repo
}, 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)
// }