From 259fad54e5290ef8c51dac23e87d0d712f9526fb Mon Sep 17 00:00:00 2001 From: Nulo Date: Sat, 16 Jul 2022 21:07:22 -0300 Subject: [PATCH 1/6] =?UTF-8?q?Reemplazar=20script=20de=20compilaci=C3=B3n?= =?UTF-8?q?=20con=20script=20en=20Zig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .woodpecker.yml | 6 +- README.md | 8 +- build.sh | 62 -------------- compilar.zig | 223 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 233 insertions(+), 67 deletions(-) delete mode 100755 build.sh create mode 100644 compilar.zig diff --git a/.gitignore b/.gitignore index 567609b..3714436 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build/ +zig-cache/ diff --git a/.woodpecker.yml b/.woodpecker.yml index d8552df..1cef0ad 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -2,10 +2,8 @@ pipeline: build: image: docker.io/alpine:3.16 commands: - - apk add cmark git cmd:setup-timezone lua5.1 - # Para generar las fechas bien - - setup-timezone -z America/Argentina/Buenos_Aires - - base_uri=https://nulo.in/ ./build.sh + - apk add cmark cmark-dev lua5.1 zig + - zig run compilar.zig -lc -lcmark deploy: image: docker.io/alpine:3.14 commands: diff --git a/README.md b/README.md index b1b5b31..171385d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ Este es el README para [el repositorio del sitio](https://gitea.nulo.in/Nulo/sitio). -Escuché [HOT DEMON B!TCHES NEAR U ! ! ! (de CORPSE y Night Lovell)](https://youtu.be/wqZnO71PBis) en loop para hacer la versión inicial del sitio. +## Compilar + +Require [Zig](https://ziglang.org), shell, cmark (con cmark-dev) y Lua 5.1. + +``` +zig run compilar.zig -lc -lcmark +``` --- diff --git a/build.sh b/build.sh deleted file mode 100755 index 41dcac7..0000000 --- a/build.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh - -template () { - echo "" - echo "" - echo "" - echo "" - echo "" - echo "" - if test -n "$base_uri"; then - echo "" - fi - echo "" - echo "" - echo "" - echo "$1" - : "${inicio:=}" - if test "$mirror" = true; then - echo "

Ojo: este sitio es un espejo (mirror). nulo.in es la fuente.

" - fi - if test "$inicio" != true; then - echo "☚ Volver al inicio" - fi - if test -n "$2"; then - echo "
" - echo "

$1

" - echo "

Último cambio:

" - echo "
" - fi -} - -markdown () { - # TODO: hacky - cmark --unsafe "$1" \ - | sed "s/\1<\/a>/g' -} - -outdir=build -mkdir -p $outdir -# Autocopiarnos :) -cp ./*.sh ./*.md ./*.css ./*.png ./*.jpg ./*.mp4 ./*.svg ./*.html "$outdir" - -index="$outdir/index.html" -inicio=true header=false template "nulo.in" > "$index" -markdown index.md >> "$index" - -for file in *.md; do - test "$(basename "$file")" = index.md && continue - title="$(basename "$file" .md)" - outfile="$outdir/$title.html" - template "$title" "$file" > "$outfile" - markdown "$file" >> "$outfile" -done - -for file in *.gen; do - title="$(basename "$file" .gen)" - outfile="$outdir/$title.html" - template "$title" "$file" > "$outfile" - "./$file" >> "$outfile" -done - diff --git a/compilar.zig b/compilar.zig new file mode 100644 index 0000000..530a43a --- /dev/null +++ b/compilar.zig @@ -0,0 +1,223 @@ +const std = @import("std"); +const c = @cImport({ + @cInclude("cmark.h"); +}); +const endsWith = std.mem.endsWith; + +fn stripExtension(file_name: []const u8) ![]const u8 { + const index = std.mem.lastIndexOfLinear(u8, file_name, "."); + if (index) |i| { + return file_name[0..i]; + } else return error.NoExtension; +} + +const HeaderOptions = struct { + // Si esto es true, se muestra un botón para volver al index. + ir_al_inicio: bool = true, + // Si esto es true, se muestra un
. + header: bool = true, +}; +fn header( + writer: std.fs.File.Writer, + title: []const u8, + src_name: []const u8, + options: HeaderOptions, +) !void { + // TODO: deshardcodear base_uri + try writer.print( + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\{0s} + \\ + , .{ title, src_name }); + // if test "$mirror" = true; then + // echo "

Ojo: este sitio es un espejo (mirror). nulo.in es la fuente.

" + // fi + if (options.ir_al_inicio) { + try writer.writeAll("☚ Volver al inicio\n"); + } + if (options.header) { + try writer.print( + \\
+ \\

{s}

+ \\Historial + \\
+ \\ + , .{ title, src_name }); + } +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + var cwd = try std.fs.cwd().openDir(".", .{ .iterate = true }); + defer cwd.close(); + var cwd_iterator = cwd.iterate(); + + var build_dir = try cwd.makeOpenPath("build", .{}); + defer build_dir.close(); + + while (try cwd_iterator.next()) |entry| { + if (entry.kind != .File) continue; + + // Autocopiarnos :) + if (endsWith(u8, entry.name, ".sh") or + endsWith(u8, entry.name, ".md") or + endsWith(u8, entry.name, ".css") or + endsWith(u8, entry.name, ".png") or + endsWith(u8, entry.name, ".jpg") or + endsWith(u8, entry.name, ".mp4") or + endsWith(u8, entry.name, ".svg") or + endsWith(u8, entry.name, ".html")) + { + try cwd.copyFile(entry.name, build_dir, entry.name, .{}); + } + + if (endsWith(u8, entry.name, ".md")) + try generateMarkdown(allocator, cwd, entry.name, build_dir); + if (endsWith(u8, entry.name, ".gen")) + try generateExecutable(allocator, cwd, entry.name, build_dir); + } +} + +const Writer = std.io.BufferedWriter(4096, std.fs.File.Writer).Writer; + +fn hackilyTransformHtml(input: []const u8, writer: Writer) !void { + var iter = std.mem.split(u8, input, "\n"); + while (iter.next()) |line| { + var index: usize = 0; + + while (index < line.len) : (index += 1) { + const rest = line[index..]; + + const link_marker = "{0s} + , .{name}); + continue; + } + } + + try writer.writeByte(line[index]); + } + + try writer.writeByte('\n'); + } +} + +fn generateMarkdown( + allocator: std.mem.Allocator, + cwd: std.fs.Dir, + src_name: []const u8, + build_dir: std.fs.Dir, +) !void { + var file = try cwd.openFile(src_name, .{}); + defer file.close(); + const markdown = try file.readToEndAllocOptions( + allocator, + 69696969, + null, + @alignOf(u32), + 0, + ); + defer allocator.free(markdown); + const html = c.cmark_markdown_to_html( + markdown.ptr, + markdown.len, + c.CMARK_OPT_UNSAFE, //| c.CMARK_OPT_SMART, + ); + defer std.c.free(html); + + const output_file_name = try std.fmt.allocPrint( + allocator, + "{s}.html", + .{try stripExtension(src_name)}, + ); + defer allocator.free(output_file_name); + + const is_index = std.ascii.eqlIgnoreCase(src_name, "index.md"); + + const title = if (is_index) + "nulo.in" + else + try stripExtension(src_name); + + var output = try build_dir.createFile(output_file_name, .{}); + defer output.close(); + try header(output.writer(), title, src_name, .{ + .ir_al_inicio = !is_index, + .header = !is_index, + }); + var buffered_writer = std.io.bufferedWriter(output.writer()); + try hackilyTransformHtml( + std.mem.span(html), + buffered_writer.writer(), + ); + try buffered_writer.flush(); +} + +fn generateExecutable( + allocator: std.mem.Allocator, + cwd: std.fs.Dir, + src_name: []const u8, + build_dir: std.fs.Dir, +) !void { + _ = cwd; + const output_file_name = try std.fmt.allocPrint( + allocator, + "{s}.html", + .{try stripExtension(src_name)}, + ); + defer allocator.free(output_file_name); + + const title = try stripExtension(src_name); + + var output = try build_dir.createFile(output_file_name, .{}); + defer output.close(); + try header(output.writer(), title, src_name, .{}); + + const executable_name = try std.fmt.allocPrint(allocator, "./{s}", .{src_name}); + defer allocator.free(executable_name); + + // const process = try std.ChildProcess.init(&.{executable_name}, allocator); + // defer process.deinit(); + // process.stdout_behavior = .Ignore; + // process.stdout = output; + // const term = try process.spawnAndWait(); + const result = try std.ChildProcess.exec(.{ + .allocator = allocator, + .argv = &.{executable_name}, + }); + defer allocator.free(result.stdout); + defer allocator.free(result.stderr); + if (result.stderr.len > 0) { + std.log.err("{s} stderr: {s}", .{ src_name, result.stderr }); + } + switch (result.term) { + .Exited => |status| { + if (status != 0) return error.ProcessFailed; + }, + else => unreachable, + } + try output.writeAll(result.stdout); +} -- 2.45.2 From 2163a9f71ebc6db81d884380458b6e3637a554eb Mon Sep 17 00:00:00 2001 From: Nulo Date: Sat, 16 Jul 2022 21:40:10 -0300 Subject: [PATCH 2/6] ci: Usar edge para usar testing/zig --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 1cef0ad..682a2b5 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,6 +1,6 @@ pipeline: build: - image: docker.io/alpine:3.16 + image: docker.io/alpine:edge commands: - apk add cmark cmark-dev lua5.1 zig - zig run compilar.zig -lc -lcmark -- 2.45.2 From 24da2c684ed847620214d87c6e0fcfa0d782787b Mon Sep 17 00:00:00 2001 From: Nulo Date: Sat, 16 Jul 2022 21:43:04 -0300 Subject: [PATCH 3/6] ci: Agregar repo testing --- .woodpecker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.woodpecker.yml b/.woodpecker.yml index 682a2b5..c164219 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -2,6 +2,7 @@ pipeline: build: image: docker.io/alpine:edge commands: + - echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories - apk add cmark cmark-dev lua5.1 zig - zig run compilar.zig -lc -lcmark deploy: -- 2.45.2 From 0f360aaa1061c4f6168cc801d7640eec8b05f625 Mon Sep 17 00:00:00 2001 From: Nulo Date: Sat, 16 Jul 2022 21:52:42 -0300 Subject: [PATCH 4/6] ci: No instalar cmark de terminal, instalar musl-dev --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index c164219..c487c3b 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,7 +3,7 @@ pipeline: image: docker.io/alpine:edge commands: - echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories - - apk add cmark cmark-dev lua5.1 zig + - apk add musl-dev cmark-dev lua5.1 zig - zig run compilar.zig -lc -lcmark deploy: image: docker.io/alpine:3.14 -- 2.45.2 From c152c8ec9fb5544745ac5052d626bbebf195f5dc Mon Sep 17 00:00:00 2001 From: Nulo Date: Sat, 16 Jul 2022 21:54:27 -0300 Subject: [PATCH 5/6] ci: Instalar clang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zig necesita un compilador de C para encontrar las librerías C --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index c487c3b..f106059 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,7 +3,7 @@ pipeline: image: docker.io/alpine:edge commands: - echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories - - apk add musl-dev cmark-dev lua5.1 zig + - apk add musl-dev cmark-dev lua5.1 zig clang - zig run compilar.zig -lc -lcmark deploy: image: docker.io/alpine:3.14 -- 2.45.2 From ea51959ee8f9c0c56d2bd0669906c1a4551d573a Mon Sep 17 00:00:00 2001 From: Nulo Date: Sat, 16 Jul 2022 21:56:30 -0300 Subject: [PATCH 6/6] ci: Usar gcc No funciona con clang ya que no provee `cc` --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index f106059..177d697 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,7 +3,7 @@ pipeline: image: docker.io/alpine:edge commands: - echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories - - apk add musl-dev cmark-dev lua5.1 zig clang + - apk add musl-dev cmark-dev lua5.1 zig gcc - zig run compilar.zig -lc -lcmark deploy: image: docker.io/alpine:3.14 -- 2.45.2