1. Mock Skel Readme

1.1. Overview

status
WIP
forge
Heptapod
mirror
Github

This system provides functions and macros for building and deploying project skeletons. This is not a general purpose templating system. It is specifically for my software stack.

1.1.1. Goals

  • vaporize boilerplate code and docs
  • integrate reasonably well with my tools (Emacs/etc)
  • object-oriented project management

1.2. Quickstart

Make sure you have sbcl installed:

sbcl --version
SBCL 2.3.12+main

Then compile the program. This command produces a binary called skel in the project root:

sbcl --noinform  --non-interactive --eval '(ql:quickload :app/cli/skel)' --eval '(asdf:make :app/cli/skel)'

Run the binary without any args, which will print a skeleton of the current project directory (*skel-project*).

skel -h
skel v0.1.1
  usage: skel [global] <command> [<arg>]

  A hacker's project compiler and build tool.
  options:
     -h/--help* :  print this message
     -v/--version* :  print version
     -d/--debug* :  set log level (debug,info,trace,warn)
     -c/--config* :  set a custom skel user config
     -i/--input  :  input source
     -o/--output  :  output target
  commands:
    init  :  initialize a skelfile in the current directory
     -n/--name  :  project name
    
    show  :  describe the project skelfile
     -f/--file  :  path to skelfile
    
    inspect  :  inspect the project skelfile
     -f/--file  :  path to skelfile
    
    make  :  build project targets
     -t/--target  :  target to build
    
    run  :  run a script or command
    
    push  :  push the current project upstream
    
    pull  :  pull the current project from remote
    
    clone  :  clone a remote project
    
    commit  :  commit changes to the project vc
    
    edit  :  edit a project file
    
    shell  :  open the sk-shell interpreter
    

Here's skel's skelfile:

;;; skelfile @ 2023-10-08.02:37:25 -*- mode: skel; -*-
:name skel
:author "ellis"
:version "0.1.0"
:description "a hacker's project compiler"
:license "MPL"
:vc :hg
:tags ("lisp")
:rules ((build () (print (asdf:make :skel/cli)))
        (clean () #$rm -rf */*.fasl$#))
:documents ((:org "readme"))
:components 
((:elisp "sk")
 (:lisp-system 
  "skel"
  :version "0.1.0"
  :maintainer "ellis <ellis@rwest.io>"
  :bug-tracker "https://lab.rwest.io/ellis/skel/issues"
  :class :package-inferred-system
  :defsystem-depends-on (:asdf-package-system)
  :depends-on (:uiop :asdf :sb-posix :sb-bsd-sockets :sb-concurrency :cl-ppcre :std :organ :skel/pkg)
  :in-order-to ((test-op (test-op skel/tests)))
  :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests))))
:stash "~/dev/comp/stash"
:shed "~/dev/comp/shed"
:abbrevs nil
:snippets 
((autogen #$sbcl --eval '(ql:quickload :app/cli/skel)' --eval '(asdf:make :app/cli/skel)'$#))

This is just a form without the top-level parentheses - you're free to omit them in a skelfile.

1.2.1. describe

The describe command can be used to check the currently active skelfile, printing any errors and the parsed object.

skel show
#<SKEL:SK-PROJECT :ID 1e61-38b1-c5fe-7eac>
  [standard-object]

Slots with :INSTANCE allocation:
  NAME                           = SKEL
  PATH                           = #P"/home/ellis/dev/skel/skelfile"
  AUTHOR                         = "ellis"
  VERSION                        = "0.1.0"
  TAGS                           = ("lisp")
  DESCRIPTION                    = "a hacker's project compiler"
  LICENSE                        = "MPL"
  AST                            = NIL
  ID                             = 2189093230060928684
  VC                             = :HG
  RULES                          = ((BUILD NIL (PRINT (ASDF/OPERATE:MAKE :SKEL/CLI)))..
  DOCUMENTS                      = ((:ORG "readme"))
  COMPONENTS                     = ((:ELISP "sk")..
  SCRIPTS                        = NIL
  SNIPPETS                       = ((AUTOGEN "sbcl --eval '(asdf:make :skel/cli)'"))
  STASH                          = #P"~/stash"
  SHED                           = #P"~/shed"
  ABBREVS                        = NIL
  IMPORTS                        = NIL

1.2.2. TODO compile

Skelfiles can be compiled to produce a new project skeleton or update an existing one.

Try compiling skel's skelfile:

skel compile

You may also compile individual components of the project structure, for example, to compile the rules into a makefile:

skel compile --rules
cat makefile
### SKEL @ 2023-09-14.01:47:59 --- A hacker's project compiler -*- mode:makefile ; -*-
LISP=sbcl --noinform --non-interactive --eval "(asdf:load-asd \"skel.asd\")" --eval "(ql:quickload :skel)"
.PHONY: compile clean
compile:;$(LISP) --eval "(asdf:compile-system :skel)"
test:compile;$(LISP) --eval "(ql:quickload :skel/tests)" --eval "(in-package :skel.tests)" --eval "(compile-file \"tests.lisp\")" --eval "(load-file \"tests.lisp\")" --eval "(do-tests :skel)"
clean:;rm -rf *.fasl
debug:compile;$(LISP) --eval "(start-repl)"

1.3. Examples

1.3.1. Default

When you run skel init this is the basic skelfile that will be generated in the current directory, depending on the following contexts:

  • default user config
  • directory contents
  • cli args

With no cli args or user config and an empty directory the output looks like this:

;;; examples @ 2023-10-09.23:38:23 -*- mode: skel; -*-
:name "examples"

1.3.2. Imports

1.3.3. Multi

1.4. Tests

The unit tests may also be a useful reference:

(ql:quickload :skel/tests)
(in-package :skel.tests)
(setq *log-level* nil)
;; (setq *catch-test-errors* nil)
(setq *compile-tests* t)
(list (multiple-value-list (do-tests :skel)) (test-results *test-suite*))
To load "skel/tests":
  Load 1 ASDF system:
    skel/tests
; Loading "skel/tests"
..................................................
[package skel.vc].................................
[package skel.virt]...............................
[package skel.comp.asd]...........................
[package skel.make]...............................
[package skel.ext.asdf]...........................
[package skel.tests].
in suite SKEL with 6/6 tests:
#<PASS VM-TEST788> 
#<PASS MAKEFILE-TEST787> 
#<PASS SKELRC-TEST786> 
#<PASS SKELFILE-TEST785> 
#<PASS HEADER-COMMENTS-TEST784> 
#<PASS SANITY-TEST783> 
No tests failed.

1.5. API

TODO
CLOS-based core classes
TODO
EIEIO-based wrapper classes
api.svg