verless is a Static Site Generator designed for Markdown-based content







A simple and lightweight Static Site Generator.





verless (pronounced like serverless) is a Static Site Generator designed for Markdown-based content with a focus on simplicity and performance. It reads your Markdown files, applies your HTML templates and renders them as a website.

Features

  • Flexible theming: Themes define the HTML templates as well as styles and scripts for your frontend. Initializing a new theme can be done within a single command, and setting it as active requires a single line of configuration. Since verless provides pre-defined template variables, themes are interchangeable.

  • Rapid development: Just like themes, new projects can be created using a single command. Local development requires no third-party webserver as verless comes with a built-in webserver and rebuilds your project when something changes.

  • High performance: Generating a static site typically is a matter of milliseconds. To keep build times short, verless lets you choose and explicitly enable features you need - only generate RSS feeds or overview pages for tags if you want to.

  • Focus on simplicity: Global information, page types, plugins and other settings are configured in a central configuration file inside your project. We try to keep things small and simple, and if your project isn't simple, verless probably isn't a good fit.

Examples

Installation

Linux and macOS

Download the latest release for your platform. Extract the downloaded binary into a directory like /usr/local/bin. Make sure the directory is in PATH.

Windows

Download the latest release, create a directory like C:\Program Files\verless and extract the executable into that directory. Add the directory to Path.

Docker

Assuming your project directory is my-blog, the following command builds your website:

$ docker container run -v $(pwd)/my-blog:/project verless/verless

The container will build the project mounted at /project and you'll find the website in my-blog/target. To run another command, just append it to the image name:

$ docker container run verless/verless version

Getting started

The easiest way to create a new project is to use the verless CLI:

$ verless create project my-blog

This initializes a project called my-blog inside a new directory, containing a small default site. You can either build the project or serve the static site directly:

$ verless serve -w my-blog

After running the command, you can view your new project under localhost:8080. Building the project works similary and generates a deployable website:

$ verless build my-blog

By default, verless generates the website into my-blog/target. You are now ready to create your first blog post!

Documentation

To find out how a verless project is structured, take a look at the example project. For a detailed reference, check out the documentation.

🔥 New tutorial: Create a website using verless

Contributing

Anyone is welcome to contribute to verless. Please refer to our contribution guidelines.


Owner
verless
A simple and lightweight Static Site Generator.
verless
Comments
  • Add tests for fs package

    Add tests for fs package

    Fixes #214
    Test case scenarios/corrections would be of great help :)

    Functions and their test:

    CopyFromOS

    CopyFromOS copies a given directory from the OS filesystem into another filesystem instance to the desired destination.

    • [x] Copy a file from source to destination
    • [x] Copy with the source structure
    • [x] Copy from the parent directory of destination.
    • [x] Source directory is empty
    • [x] Source file does not exist
    • [x] Source directory has no read permissions(0000).

    IsSafeToRemove

    IsSafeToRemove determines if a directory can be removed safely.

    • [x] Remove any file
    • [x] Remove a directory
    • [x] Try to remove a non-existent directory
    • [x] Force remove a file

    Rmdir

    Rmdir removes an entire directory along with its contents. If the directory does not exist, nothing happens.

    • [x] Remove an empty directory
    • [x] Remove a file
    • [x] Remove a nested directory structure
    • [x] Try to remove a non-existent file

    StreamFiles

    StreamFiles sends all relative file paths inside a given path that match the given filters through the files channel.

    • [x] Stream files in the example folder without filters
    • [x] Stream files in the example folder with the markdown filter
    • [x] Stream files in the example folder with all filters
    • [x] Try to stream files from a path that does not exist
  • feature: verless create file command

    feature: verless create file command

    for issue #65

    We can also pass path to command for example verless create file blog/file.md Will check if blog directory exist in content directory and if it exist, it will create a file in path content/blog

    I hope you like this functionality.

  • Replace /css and /js directories with a single top-level directory

    Replace /css and /js directories with a single top-level directory

    The top level /css and /js directories which are copied from themes/<theme>/css and themes/<theme>/js may be unified to a single directory containing arbitrary sub-directories.

    As a result, a theme only requires a directory like themes/<theme>/assets, which will be copied as a top-level directory /assets.

  • Add Robots field to front matter, closes #240

    Add Robots field to front matter, closes #240

    Hi,

    I have implemented #240. I have also added the Robots field to meta.go for usage in the list pages. Please let me know if any adaptions are necessary.

  • Creating a project inside the current directory doesn't work

    Creating a project inside the current directory doesn't work

    Description

    Creating a project inside the current directory using verless create project . or verless create project doesn't work:

    RemoveAll .: invalid argument
    

    Reproduce

    Steps to reproduce the behavior:

    1. verless create project --overwrite .

    Expected behavior

    A new project should be initialized.

    verless version

    The output of verless version:

    verless version v0.4.3
    Git tag: v0.4.3
    Git commit: b96616f
    

    System information

    • OS: Windows 10
    • Version: 1909
  • Improve fs.CopyFromOs function

    Improve fs.CopyFromOs function

    fs.CopyFromOs copies a file from the host to another filesystem. The current implementation looks as follows:

    1. Read the source file

    https://github.com/verless/verless/blob/568bc63459b071b710d8fc496fb1ecf6234f948d/fs/fs.go#L118-L121

    2. Create the destination file

    https://github.com/verless/verless/blob/568bc63459b071b710d8fc496fb1ecf6234f948d/fs/fs.go#L136-L139

    3. Write the source contents into the destination file

    https://github.com/verless/verless/blob/568bc63459b071b710d8fc496fb1ecf6234f948d/fs/fs.go#L140-L142

    This works well, but can be optimized to achieve a slightly better performance according to 3 ways to copy files in Go.

    Optimizations

    • Reading the source file should be done using os.Open instead of ioutil.ReadFile.
    • Writing the source contents should be done using ~~os.Copy~~ io.Copy instead of io.Writer.Write.
    • Both files should be closed at the end of the loop.
  • Clickable Tags

    Clickable Tags

    Just trying this now. I see tags on your own site but they are not clickable. That's the only thing missing for me. I recently made a ssg myself using the worst language on the planet, a Windows batch file, including tags, but unfortunately Netlify does not support batch files, but they do support go exe's and verless would work great on Netlify. Could you add clickable tags feature?

  • Add tests for fs package

    Add tests for fs package

    The problem the feature solves

    Include tests for the fs package so that developers can check if the package works as expected after making changes.
    Suggested in #200

    Your suggested solution

    I would like to work on the solution, which includes - Unit tests for these functions:

    • CopyFromOS
    • IsSafeToRemove
    • Rmdir
    • StreamFiles

    Would writing unit-tests for each function be the best way to test the fs package?
    Thank you for your time.

  • Tags plugin: Initialize routes of list pages

    Tags plugin: Initialize routes of list pages

    The tags plugin maintains a map of tags (keys) and a list page (values) that contains pages with that tag. If the tag doesn't exist in the map yet, a new list page is generated (see line 37):

    https://github.com/verless/verless/blob/master/plugin/tags/tags.go#L32-L43

    This is okay so far, but the list page doesn't receive a Route:

    https://github.com/verless/verless/blob/e999446f6ab6006adfb829ded2beeed8b01db036/plugin/tags/tags.go#L71-L76

    List pages with an empty route cause weird behavior. In order to fix this issue, the list page needs their Route field set. This should be something like Route: tagsDir + "/" + key or so.

  • Make Page fields private

    Make Page fields private

    There are some fields in model.Page which should not be accessed from templates, like RelatedFQNs or Hide.

    https://github.com/verless/verless/blob/514f1963a76e4694a01d49f13f8467b3fab86d2c/model/page.go#L16

    These exported fields should be made private. To be able to get and set them internally from other packages, there need to be getter and setter methods for them, and those should be accessed instead.

  • Panic when a list page's route is empty

    Panic when a list page's route is empty

    For each directory inside the content directory, verless automatically creates an overview page containing all pages inside that directory. This overview page is called list page, represented by the type model.ListPage.

    Each page - and a list page is no exception - needs to have a valid Route field: / for the top-level list page, /blog for the list page for a blog directory and so on.

    If this Route field is not set, this is a programming error and verless shall panic:

    https://github.com/verless/verless/blob/7fc7f50defdd734b17699e649b723fff3d23b8e3/writer/writer.go#L66

    After accessing the list page, we should check if lp.Route == "" and panic if it is.

    Why? Because ListPage.Route represents the actual path where the list page will be rendered in the filesystem. If that route is empty, the filesystem path is "" and it will be rendered as top-level list page, which is incorrect.

  • Failed to create new project

    Failed to create new project

    Description

    Command: verless create project coffee-blog gives error: ❌ open coffee-blog: no such file or directory

    verless version

    The output of verless version:

    verless version v0.5.4
    

    System information

    • OS: Debian GNU/Linux 11 (bullseye)
    • Version: 11
  • `redirect` plugin

    `redirect` plugin

    There should be a redirect plugin to redirect from one content page to another:

    # content/my-old-page.md
    ---
    Title: My old Page
    Redirect: /my-new-page
    ---
    

    Just like the other plugins, the redirect plugin would have to be explicitly enabled in verless.yml.

  • Make tree package an independent Go package

    Make tree package an independent Go package

    For the sake of simplicity and clarity, I decided to strictly separate verless' business logic and the tree logic. This resulted in extracting all tree-related code into the tree package, and it facilitated distinguishing tree-related bugs from business-related bugs.

    It might be useful to make the tree package an independent Go package in an own repository in order to make it even more re-usable. I encounter tree-related logic from time to time in my own projects, and it might make sense to provide this functionaliy within a dedicated package.

    @aligator PTAL

  • verless serve -w: Concurrent map access

    verless serve -w: Concurrent map access

    Description

    verless serve -w occasionally runs into a concurrent map access error.

    fatal error: concurrent map writes
    
    goroutine 11079 [running]:
    runtime.throw(0xcd3f82, 0x15)
            /usr/local/go/src/runtime/panic.go:1116 +0x72 fp=0xc000533a30 sp=0xc000533a00 pc=0x434dc2
    runtime.mapassign_faststr(0xbf0b20, 0xc00080c300, 0xc000741670, 0x7, 0x7)
            /usr/local/go/src/runtime/map_faststr.go:211 +0x3f7 fp=0xc000533a98 sp=0xc000533a30 pc=0x414b17
    github.com/verless/verless/plugin/tags.(*tags).createListPage(...)
            /home/circleci/project/plugin/tags/tags.go:81
    github.com/verless/verless/plugin/tags.(*tags).ProcessPage(0xc00030e218, 0xc00036be60, 0x0, 0x0)
            /home/circleci/project/plugin/tags/tags.go:42 +0x377 fp=0xc000533b38 sp=0xc000533a98 pc=0xb5dc67
    github.com/verless/verless/core.(*Build).processFile(0xc00058d880, 0xc0005012e0, 0x10, 0xc00014ad50, 0x2e, 0x40759f, 0xb6514f)
            /home/circleci/project/core/build.go:260 +0x489 fp=0xc000533f48 sp=0xc000533b38 pc=0xb67fc9
    github.com/verless/verless/core.(*Build).Run.func2(0xc000424600, 0xc00058d880, 0xc0005012e0, 0x10, 0xc0004246c0, 0xc0005012f0)
            /home/circleci/project/core/build.go:182 +0x89 fp=0xc000533fb0 sp=0xc000533f48 pc=0xb6aab9
    runtime.goexit()
            /usr/local/go/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc000533fb8 sp=0xc000533fb0 pc=0x4643f1
    created by github.com/verless/verless/core.(*Build).Run
            /home/circleci/project/core/build.go:179 +0x20a
    
    goroutine 1 [IO wait]:
    internal/poll.runtime_pollWait(0x7efc6cbade98, 0x72, 0x0)
            /usr/local/go/src/runtime/netpoll.go:203 +0x55
    internal/poll.(*pollDesc).wait(0xc0002cfc98, 0x72, 0x0, 0x0, 0xc9ac31)
            /usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
    internal/poll.(*pollDesc).waitRead(...)
            /usr/local/go/src/internal/poll/fd_poll_runtime.go:92
    internal/poll.(*FD).Accept(0xc0002cfc80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
            /usr/local/go/src/internal/poll/fd_unix.go:384 +0x1d4
    net.(*netFD).accept(0xc0002cfc80, 0x407dfcbe44141ab6, 0x0, 0x407dfcbe44141ab6)
            /usr/local/go/src/net/fd_unix.go:238 +0x42
    net.(*TCPListener).accept(0xc000236d60, 0x5fd628f0, 0xc000937788, 0x48ce06)
            /usr/local/go/src/net/tcpsock_posix.go:139 +0x32
    net.(*TCPListener).Accept(0xc000236d60, 0xc0009377d8, 0x18, 0xc000000180, 0x6d689c)
            /usr/local/go/src/net/tcpsock.go:261 +0x64
    net/http.(*Server).Serve(0xc0000f49a0, 0xe5fe00, 0xc000236d60, 0x0, 0x0)
            /usr/local/go/src/net/http/server.go:2930 +0x25d
    net/http.(*Server).ListenAndServe(0xc0000f49a0, 0xc0000f49a0, 0x1)
            /usr/local/go/src/net/http/server.go:2859 +0xb7
    net/http.ListenAndServe(...)
            /usr/local/go/src/net/http/server.go:3115
    github.com/verless/verless/core.listenAndServe(0xe67900, 0xc0002bed80, 0xc0001f3060, 0xf, 0xc000028670, 0x4, 0x4, 0xc000271f90, 0xc00006e960, 0x0)
            /home/circleci/project/core/serve.go:132 +0x31c
    github.com/verless/verless/core.Serve(0x7fff57828f7f, 0x8, 0x0, 0x0, 0x0, 0x1f90, 0xc000028670, 0x4, 0x4, 0x1, ...)
            /home/circleci/project/core/serve.go:112 +0x3c3
    github.com/verless/verless/cli.newServeCmd.func1(0xc0002fc2c0, 0xc0002373e0, 0x1, 0x2, 0x0, 0x0)
            /home/circleci/project/cli/serve.go:24 +0xb9
    github.com/spf13/cobra.(*Command).execute(0xc0002fc2c0, 0xc0002373c0, 0x2, 0x2, 0xc0002fc2c0, 0xc0002373c0)
            /go/pkg/mod/github.com/spf13/[email protected]/command.go:850 +0x453
    github.com/spf13/cobra.(*Command).ExecuteC(0xc00029eb00, 0xc00051df78, 0x40759f, 0xc00006e058)
            /go/pkg/mod/github.com/spf13/[email protected]/command.go:958 +0x349
    github.com/spf13/cobra.(*Command).Execute(...)
            /go/pkg/mod/github.com/spf13/[email protected]/command.go:895
    main.main()
            /home/circleci/project/cmd/verless/main.go:12 +0x2b
    
    goroutine 7 [select]:
    github.com/verless/verless/core.watch.func1(0xc0002b7680, 0x7fff57828f7f, 0x8, 0xc0002bedb0, 0x3, 0x3, 0xc00006eb40, 0xc00006e960)
            /home/circleci/project/core/watch.go:35 +0x12f
    created by github.com/verless/verless/core.watch
            /home/circleci/project/core/watch.go:31 +0xb7
    
    goroutine 8 [sleep]:
    time.Sleep(0x5f5e100)
            /usr/local/go/src/runtime/time.go:188 +0xba
    github.com/radovskyb/watcher.(*Watcher).Start(0xc0002b7680, 0x5f5e100, 0x0, 0x0)
            /go/pkg/mod/github.com/radovskyb/[email protected]/watcher.go:608 +0x338
    github.com/verless/verless/core.watch.func2(0xc0002b7680, 0xc0002bb660)
            /home/circleci/project/core/watch.go:82 +0x34
    created by github.com/verless/verless/core.watch
            /home/circleci/project/core/watch.go:81 +0x18e
    
    goroutine 10780 [IO wait]:
    internal/poll.runtime_pollWait(0x7efc6cbadf78, 0x72, 0xffffffffffffffff)
            /usr/local/go/src/runtime/netpoll.go:203 +0x55
    internal/poll.(*pollDesc).wait(0xc00058c198, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
            /usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
    internal/poll.(*pollDesc).waitRead(...)
            /usr/local/go/src/internal/poll/fd_poll_runtime.go:92
    internal/poll.(*FD).Read(0xc00058c180, 0xc00015e000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
            /usr/local/go/src/internal/poll/fd_unix.go:169 +0x19b
    net.(*netFD).Read(0xc00058c180, 0xc00015e000, 0x1000, 0x1000, 0x1367340, 0xc000146480, 0x1)
            /usr/local/go/src/net/fd_unix.go:202 +0x4f
    net.(*conn).Read(0xc00030e100, 0xc00015e000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
            /usr/local/go/src/net/net.go:184 +0x8e
    net/http.(*connReader).Read(0xc0005e8300, 0xc00015e000, 0x1000, 0x1000, 0x2, 0xc00073c140, 0x203000)
            /usr/local/go/src/net/http/server.go:797 +0xf4
    bufio.(*Reader).fill(0xc000428c60)
            /usr/local/go/src/bufio/bufio.go:100 +0x103
    bufio.(*Reader).ReadSlice(0xc000428c60, 0xa, 0x28, 0xc00085b9c0, 0x40dcc6, 0xc0000e1100, 0x100)
            /usr/local/go/src/bufio/bufio.go:359 +0x3d
    bufio.(*Reader).ReadLine(0xc000428c60, 0xc00085b9c8, 0xc00003d500, 0x7efc93921e98, 0x0, 0x40e538, 0x30)
            /usr/local/go/src/bufio/bufio.go:388 +0x34
    net/textproto.(*Reader).readLineSlice(0xc0005e9170, 0xc0000e1100, 0x0, 0x48c530, 0xc00085ba40, 0x0)
            /usr/local/go/src/net/textproto/reader.go:58 +0x6c
    net/textproto.(*Reader).ReadLine(...)
            /usr/local/go/src/net/textproto/reader.go:39
    net/http.readRequest(0xc000428c60, 0x0, 0xc0000e1100, 0x0, 0x0)
            /usr/local/go/src/net/http/request.go:1015 +0xa4
    net/http.(*conn).readRequest(0xc000108aa0, 0xe61a40, 0xc000ad8000, 0x0, 0x0, 0x0)
            /usr/local/go/src/net/http/server.go:983 +0x191
    net/http.(*conn).serve(0xc000108aa0, 0xe61a40, 0xc000ad8000)
            /usr/local/go/src/net/http/server.go:1850 +0x6d4
    created by net/http.(*Server).Serve
            /usr/local/go/src/net/http/server.go:2962 +0x35c
    
    goroutine 10779 [IO wait]:
    internal/poll.runtime_pollWait(0x7efc6cbaddb8, 0x72, 0xffffffffffffffff)
            /usr/local/go/src/runtime/netpoll.go:203 +0x55
    internal/poll.(*pollDesc).wait(0xc00058c098, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
            /usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
    internal/poll.(*pollDesc).waitRead(...)
            /usr/local/go/src/internal/poll/fd_poll_runtime.go:92
    internal/poll.(*FD).Read(0xc00058c080, 0xc0004dc000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
            /usr/local/go/src/internal/poll/fd_unix.go:169 +0x19b
    net.(*netFD).Read(0xc00058c080, 0xc0004dc000, 0x1000, 0x1000, 0x13ab, 0x0, 0x0)
            /usr/local/go/src/net/fd_unix.go:202 +0x4f
    net.(*conn).Read(0xc00030e0f0, 0xc0004dc000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
            /usr/local/go/src/net/net.go:184 +0x8e
    net/http.(*connReader).Read(0xc0005e8390, 0xc0004dc000, 0x1000, 0x1000, 0x7efc6cb12878, 0x0, 0x7efc6cbb20f8)
            /usr/local/go/src/net/http/server.go:797 +0xf4
    bufio.(*Reader).fill(0xc000428cc0)
            /usr/local/go/src/bufio/bufio.go:100 +0x103
    bufio.(*Reader).ReadSlice(0xc000428cc0, 0xc00093d90a, 0x7efc6cb12878, 0xc00093d9c0, 0x40dcc6, 0xc000541f00, 0x100)
            /usr/local/go/src/bufio/bufio.go:359 +0x3d
    bufio.(*Reader).ReadLine(0xc000428cc0, 0xc00093d9c8, 0xc000080000, 0x7efc939217d0, 0x0, 0x1, 0xc0004dd000)
            /usr/local/go/src/bufio/bufio.go:388 +0x34
    net/textproto.(*Reader).readLineSlice(0xc0005e83f0, 0xc000541f00, 0x0, 0x4378ac, 0xc00093da28, 0x0)
            /usr/local/go/src/net/textproto/reader.go:58 +0x6c
    net/textproto.(*Reader).ReadLine(...)
            /usr/local/go/src/net/textproto/reader.go:39
    net/http.readRequest(0xc000428cc0, 0x0, 0xc000541f00, 0x0, 0x0)
            /usr/local/go/src/net/http/request.go:1015 +0xa4
    net/http.(*conn).readRequest(0xc000108280, 0xe61a40, 0xc000ad80c0, 0x0, 0x0, 0x0)
            /usr/local/go/src/net/http/server.go:983 +0x191
    net/http.(*conn).serve(0xc000108280, 0xe61a40, 0xc000ad80c0)
            /usr/local/go/src/net/http/server.go:1850 +0x6d4
    created by net/http.(*Server).Serve
            /usr/local/go/src/net/http/server.go:2962 +0x35c
    
    goroutine 47 [chan receive]:
    github.com/verless/verless/core.(*Build).Run(0xc00058d880, 0xc0002bed80, 0x7fff57828f7f)
            /home/circleci/project/core/build.go:199 +0x2a2
    github.com/verless/verless/core.Serve.func1(0xc00006eb40, 0xe67900, 0xc0002bed80, 0x7fff57828f7f, 0x8, 0xc000272140, 0xc00006e960)
            /home/circleci/project/core/serve.go:94 +0x249
    created by github.com/verless/verless/core.Serve
            /home/circleci/project/core/serve.go:79 +0x488
    
    goroutine 11078 [runnable]:
    github.com/verless/verless/fs.StreamFiles.func1(0xc0000604d0, 0x65, 0xe641e0, 0xc000538c30, 0x0, 0x0, 0x4a580f, 0xc000538c30)
            /home/circleci/project/fs/fs.go:71 +0x173
    path/filepath.walk(0xc0000604d0, 0x65, 0xe641e0, 0xc000538c30, 0xc00004cf08, 0x0, 0x0)
            /usr/local/go/src/path/filepath/path.go:360 +0x425
    path/filepath.walk(0xc000678560, 0x1c, 0xe641e0, 0xc000b2dc70, 0xc00004cf08, 0x0, 0x0)
            /usr/local/go/src/path/filepath/path.go:384 +0x2ff
    path/filepath.walk(0xc000678500, 0x15, 0xe641e0, 0xc000b2dba0, 0xc00004cf08, 0x0, 0x0)
            /usr/local/go/src/path/filepath/path.go:384 +0x2ff
    path/filepath.walk(0xc0005012e0, 0x10, 0xe641e0, 0xc000b2dad0, 0xc00004cf08, 0x0, 0xc0005012e0)
            /usr/local/go/src/path/filepath/path.go:384 +0x2ff
    path/filepath.Walk(0xc0005012e0, 0x10, 0xc00050af08, 0x10, 0x0)
            /usr/local/go/src/path/filepath/path.go:406 +0xff
    github.com/verless/verless/fs.StreamFiles(0xc0005012e0, 0x10, 0xc000424600, 0xc00050afa0, 0x2, 0x2, 0xb65639, 0xc0002b7680)
            /home/circleci/project/fs/fs.go:50 +0x18b
    github.com/verless/verless/core.(*Build).Run.func1(0xc0005012e0, 0x10, 0xc000424600, 0xc0004246c0)
            /home/circleci/project/core/build.go:170 +0x82
    created by github.com/verless/verless/core.(*Build).Run
            /home/circleci/project/core/build.go:169 +0x169
    
    goroutine 11083 [semacquire]:
    sync.runtime_Semacquire(0xc0005012f8)
            /usr/local/go/src/runtime/sema.go:56 +0x42
    sync.(*WaitGroup).Wait(0xc0005012f0)
            /usr/local/go/src/sync/waitgroup.go:130 +0x64
    github.com/verless/verless/core.(*Build).Run.func3(0xc0005012f0, 0xc0004246c0)
            /home/circleci/project/core/build.go:193 +0x2b
    created by github.com/verless/verless/core.(*Build).Run
            /home/circleci/project/core/build.go:191 +0x24d
    
    goroutine 11080 [runnable]:
    syscall.Syscall(0x48, 0x9, 0x3, 0x0, 0x8000, 0x0, 0x0)
            /usr/local/go/src/syscall/asm_linux_amd64.s:18 +0x5
    syscall.fcntl(0x9, 0x3, 0x0, 0xc0007daf00, 0x0, 0x0)
            /usr/local/go/src/syscall/zsyscall_linux_amd64.go:382 +0x4c
    syscall.SetNonblock(0x9, 0xc92201, 0x4, 0x1)
            /usr/local/go/src/syscall/exec_unix.go:106 +0x41
    os.newFile(0x9, 0xc000096500, 0x47, 0x1, 0x2f62000000000000)
            /usr/local/go/src/os/file_unix.go:165 +0x163
    os.openFileNolog(0xc000096500, 0x47, 0x0, 0xc000000000, 0x48, 0xc0000964b0, 0x48)
            /usr/local/go/src/os/file_unix.go:226 +0x18d
    os.OpenFile(0xc000096500, 0x47, 0x0, 0xc000000000, 0x4bd067, 0xc000096190, 0x48)
            /usr/local/go/src/os/file.go:307 +0x63
    os.Open(...)
            /usr/local/go/src/os/file.go:287
    io/ioutil.ReadFile(0xc000096500, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0)
            /usr/local/go/src/io/ioutil/ioutil.go:53 +0x77
    github.com/verless/verless/core.(*Build).processFile(0xc00058d880, 0xc0005012e0, 0x10, 0xc000422e70, 0x37, 0x0, 0x0)
            /home/circleci/project/core/build.go:235 +0xc0
    github.com/verless/verless/core.(*Build).Run.func2(0xc000424600, 0xc00058d880, 0xc0005012e0, 0x10, 0xc0004246c0, 0xc0005012f0)
            /home/circleci/project/core/build.go:182 +0x89
    created by github.com/verless/verless/core.(*Build).Run
            /home/circleci/project/core/build.go:179 +0x20a
    
    goroutine 11082 [runnable]:
    syscall.Syscall6(0x101, 0xffffffffffffff9c, 0xc0002d0b60, 0x80000, 0x0, 0x0, 0x0, 0xa, 0x80000, 0x0)
            /usr/local/go/src/syscall/asm_linux_amd64.s:41 +0x5
    syscall.openat(0xffffffffffffff9c, 0xc0002d0af0, 0x65, 0x80000, 0x2f62000000000000, 0x12, 0x1, 0x12)
            /usr/local/go/src/syscall/zsyscall_linux_amd64.go:68 +0xbb
    syscall.Open(...)
            /usr/local/go/src/syscall/syscall_linux.go:138
    os.openFileNolog(0xc0002d0af0, 0x65, 0x0, 0xc000000000, 0x66, 0xc0002d0a80, 0x66)
            /usr/local/go/src/os/file_unix.go:200 +0x8f
    os.OpenFile(0xc0002d0af0, 0x65, 0x0, 0xc000000000, 0x4bd067, 0xc0002d0a10, 0x66)
            /usr/local/go/src/os/file.go:307 +0x63
    os.Open(...)
            /usr/local/go/src/os/file.go:287
    io/ioutil.ReadFile(0xc0002d0af0, 0x65, 0x0, 0x0, 0x0, 0x0, 0x0)
            /usr/local/go/src/io/ioutil/ioutil.go:53 +0x77
    github.com/verless/verless/core.(*Build).processFile(0xc00058d880, 0xc0005012e0, 0x10, 0xc0000604e0, 0x55, 0x0, 0x0)
            /home/circleci/project/core/build.go:235 +0xc0
    github.com/verless/verless/core.(*Build).Run.func2(0xc000424600, 0xc00058d880, 0xc0005012e0, 0x10, 0xc0004246c0, 0xc0005012f0)
            /home/circleci/project/core/build.go:182 +0x89
    created by github.com/verless/verless/core.(*Build).Run
            /home/circleci/project/core/build.go:179 +0x20a
    
    goroutine 11081 [runnable]:
    github.com/alecthomas/chroma.(*coalescer).Tokenise.func1(0x10, 0xc00039e860, 0x70)
            /go/pkg/mod/github.com/alecthomas/[email protected]/coalesce.go:15 +0x5a
    github.com/alecthomas/chroma.Iterator.Tokens(0xc000b43200, 0xc00060d428, 0x9bffaf, 0xc00060d428)
            /go/pkg/mod/github.com/alecthomas/[email protected]/iterator.go:15 +0x3c
    github.com/alecthomas/chroma/formatters/html.(*Formatter).Format(0xc0002eaa10, 0xe55580, 0xc000398b40, 0xc000197000, 0xc000b43200, 0x0, 0x0)
            /go/pkg/mod/github.com/alecthomas/[email protected]/formatters/html/html.go:161 +0x2f
    github.com/yuin/goldmark-highlighting.(*HTMLRenderer).renderFencedCodeBlock(0xc000258540, 0xe654a0, 0xc000398b40, 0xc0005f2000, 0x1538, 0x1738, 0xe6e880, 0xc0006120a0, 0x1701, 0x3, ...)
            /go/pkg/mod/github.com/yuin/[email protected]/highlighting.go:488 +0xd55
    github.com/yuin/goldmark/renderer.(*renderer).Render.func2(0xe6e880, 0xc0006120a0, 0x1, 0x3, 0x0, 0x0)
            /go/pkg/mod/github.com/yuin/[email protected]/renderer/renderer.go:166 +0x108
    github.com/yuin/goldmark/ast.walkHelper(0xe6e880, 0xc0006120a0, 0xc00060d8f8, 0x3, 0x0, 0x0)
            /go/pkg/mod/github.com/yuin/[email protected]/ast/ast.go:476 +0x43
    github.com/yuin/goldmark/ast.walkHelper(0xe6e640, 0xc0002b6280, 0xc00060d8f8, 0xc00063a000, 0x0, 0xc0005f2000)
            /go/pkg/mod/github.com/yuin/[email protected]/ast/ast.go:482 +0x160
    github.com/yuin/goldmark/ast.Walk(...)
            /go/pkg/mod/github.com/yuin/[email protected]/ast/ast.go:471
    github.com/yuin/goldmark/renderer.(*renderer).Render(0xc000686050, 0xe555e0, 0xc0000ea150, 0xc0005f2000, 0x1538, 0x1738, 0xe6e640, 0xc0002b6280, 0xc10e01, 0xc000090138)
            /go/pkg/mod/github.com/yuin/[email protected]/renderer/renderer.go:161 +0x13c
    github.com/yuin/goldmark.(*markdown).Convert(0xc000326300, 0xc0005f2000, 0x1538, 0x1738, 0xe555e0, 0xc0000ea150, 0xc000090138, 0x1, 0x1, 0x8, ...)
            /go/pkg/mod/github.com/yuin/[email protected]/markdown.go:117 +0xe3
    github.com/verless/verless/parser.(*markdown).ParsePage(0xc00079b770, 0xc0005f2000, 0x1538, 0x1738, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
            /home/circleci/project/parser/markdown.go:38 +0x162
    github.com/verless/verless/core.(*Build).processFile(0xc00058d880, 0xc0005012e0, 0x10, 0xc000422ce0, 0x33, 0x40759f, 0xb6514f)
            /home/circleci/project/core/build.go:240 +0x17a
    github.com/verless/verless/core.(*Build).Run.func2(0xc000424600, 0xc00058d880, 0xc0005012e0, 0x10, 0xc0004246c0, 0xc0005012f0)
            /home/circleci/project/core/build.go:182 +0x89
    created by github.com/verless/verless/core.(*Build).Run
            /home/circleci/project/core/build.go:179 +0x20a
    
    

    verless version

    The output of verless version:

    verless version v0.5.2
    Git tag: v0.5.2
    Git commit: acf5c32
    

    System information

    • OS: macOS
    • Version: 11
  • verless serve displays wrong port information

    verless serve displays wrong port information

    Description

    verless serve prints wrong port information. By default, verless serves projects on port 8080, but verless serve prints port 80 as listening port.

    Reproduce

    Steps to reproduce the behavior:

    1. Serve the example project. Run this in the verless project directory:
      • Native: verless serve -w example
      • Docker: docker container run -v $(pwd)/example:/project -p 8080:8080 verless/verless serve -w /project
    2. Check the output: 💡 serving website on 0.0.0.0:80

    Expected behavior

    The output should be 💡 serving website on 0.0.0.0:8080.

    verless version

    The output of verless version:

    verless version v0.5.3
    Git tag: v0.5.3       
    Git commit: 4a9444f
    
Statika is simple static site generator(SSG) written in go emphasizing convention over configuration

Statika Statika is simple static site generator(SSG) written in go emphasizing convention over configuration. This is a newer version of my original s

Dec 13, 2022
notion-md-gen allows you to use Notion as a CMS for pages built with any static site generators

notion-md-gen allows you to use Notion as a CMS for pages built with any static site generators

Dec 12, 2022
Vela plugin designed for generating a static documentation website with Hugo.

Vela plugin designed for generating a static documentation website with Hugo.

Jul 22, 2022
A small site builder for the Gemini protocol

?? Flounder A lightweight platform to help users build simple Gemini sites over http(s) and serve those sites over http(s) and Gemini Flounder is in A

Dec 7, 2021
Ecommerce - An ecommerce site with golang
Ecommerce - An ecommerce site with golang

How To's Steps Required tools: go docker kubectl minikube Docker registry The cu

Jan 8, 2022
Creating Web Content in Golang

Creating Web Content in Golang From GoWebExamples.com Go is an open source programming language designed for building simple, fast, and reliable softw

Jan 16, 2022
A web forum built in Golang and SQLite and designed in SCSS
A web forum built in Golang and SQLite and designed in SCSS

Forum "Fairfax" ?? What is it? A web forum built in Golang and SQLite and designed in SCSS. Members of the forum can take a personality test and be so

Nov 10, 2021
A golang script designed to output the cert information for various websites

gofer gofer is a golang script designed to output the cert information for various websites Example run You can supply multiple sites with port (ie. :

Jun 15, 2022
Muxer - This repo is designed to trancode RTMP streams from the ingester and then push them to be muxed
Muxer - This repo is designed to trancode RTMP streams from the ingester and then push them to be muxed

VidersMuxer This repo is designed to trancode RTMP streams from the ingester and

Feb 3, 2022
Crane - 🐦 A full-text WebAssembley search engine for static websites
Crane - 🐦 A full-text WebAssembley search engine for static websites

Crane ?? My blog post: WebAssembly Search Tools for Static Sites Crane is a technical demo is inspired by Stork and uses a near-identical configuratio

Dec 1, 2022
A simple web-based time in/time out intended for home-based workers.

Web-based Time in/Time out About A simple web-based time in/time out intended for home-based workers. Pre-requisite To run the pre-built binary: An in

Dec 16, 2021
A code generator that turns plain old Go services into RPC-enabled (micro)services with robust HTTP APIs.

Frodo Frodo is a code generator and runtime library that helps you write RPC-enabled (micro) services and APIs. It parses the interfaces/structs/comme

Dec 16, 2022
导航网站生成器(Navigation website generator)
导航网站生成器(Navigation website generator)

gena 导航网站生成器 | English Document 安装 一键生成(推荐) 从 gena-template 自动生成并自动部署到 GitHub Pages 源码安装 go1.16 required go get -u github.com/x1ah/gena/cmd/gena > gen

Nov 20, 2022
Protocol Generator API in Golang

PGen (building... learning GO Lang...) Protocol generator API in GO. The PGen is a microservice created to generate service protocols for any type of

Dec 20, 2021
A Binance Chain vanity address generator written in golang
A Binance Chain vanity address generator written in golang

VaniBNB A Binance Chain vanity address generator written in golang. For example address ending with 0xkat Raw https://github.com/makevoid/vanieth http

Dec 14, 2021
Account Generator Bot, written in GoLang via gotgbot library

Account Generator Bot Account Generator Bot, written in GoLang via gotgbot library. Variables Env Vars - BOT_TOKEN - Get it from @BotFather CHANNEL_ID

Dec 28, 2021
GoCondor is a golang web framework with an MVC like architecture, it's based on Gin framework
GoCondor is a golang web framework with an MVC like architecture, it's based on Gin framework

GoCondor is a golang web framework with an MVC like architecture, it's based on Gin framework, it features a simple organized directory structure for your next project with a pleasant development experience, made for developing modern APIs and microservices.

Dec 29, 2022
Handles file uploads & organises files based on your database entities.

Handles file uploads & organises files based on your database entities.

Nov 22, 2022
Retro-Floppy UI is a web based application for managing & using a GoTek floppy emulator running the Flash Floppy firmware.
Retro-Floppy UI is a web based application for managing & using a GoTek floppy emulator running the Flash Floppy firmware.

A web user interface for a GoTek running flashfloppy utilising a Raspberry PI 0W as the storage. This allows for remote uploading of files & selecting which disk image is loaded on a retro computer like the BBC Micro or Amiga A1200

Dec 10, 2022