changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > org > notes / skel-readme.org

changeset 1: 4b49701b8c04
child: 04e86b94ef1a
author: Richard Westhaver <ellis@rwest.io>
date: Sun, 02 Jun 2024 20:08:07 -0400
permissions: -rw-r--r--
description: import
1 #+title: skel
2 #+author: Richard Westhaver
3 #+description: Project Skeletons
4 * Overview
5 + status :: WIP
6 + forge :: [[https://lab.rwest.io/ellis/skel][Heptapod]]
7 + mirror :: [[https://github.com/richardwesthaver/skel][Github]]
8 
9 This system provides functions and macros for building and deploying
10 project skeletons. /This is not a general purpose templating
11 system/. It is specifically for my software stack.
12 
13 ** Goals
14 - vaporize boilerplate code and docs
15 - integrate reasonably well with my tools (Emacs/etc)
16 - object-oriented project management
17 ** Resources
18 - [[https://www.gnu.org/software/emacs/manual/html_node/autotype/Skeleton-Language.html][skeleton-lanaguage (emacs)]]
19 - [[https://github.com/emacs-mirror/emacs/tree/master/lisp/cedet/ede][cedet/ede (emacs)]]
20 - [[https://www.gnu.org/software/make/manual/make.html][GNU make]]
21 - [[https://docs.factorcode.org/content/article-vocabularies.html][Factor (forth) definitions]]
22 * Quickstart
23 Make sure you have sbcl installed:
24 #+begin_src shell :results pp :exports both
25 sbcl --version
26 #+end_src
27 
28 #+RESULTS:
29 : SBCL 2.3.12+main
30 
31 Then compile the program. This command produces a binary called =skel=
32 in the project root:
33 #+begin_src shell :results raw silent
34 sbcl --noinform --non-interactive --eval '(ql:quickload :app/cli/skel)' --eval '(asdf:make :app/cli/skel)'
35 #+end_src
36 
37 Run the binary without any args, which will print a skeleton of the
38 current project directory (=*skel-project*=).
39 
40 #+begin_src shell :results output replace :exports both
41  skel -h
42 #+end_src
43 
44 #+RESULTS:
45 #+begin_example
46 skel v0.1.1
47  usage: skel [global] <command> [<arg>]
48 
49  A hacker's project compiler and build tool.
50  options:
51  -h/--help* : print this message
52  -v/--version* : print version
53  -d/--debug* : set log level (debug,info,trace,warn)
54  -c/--config* : set a custom skel user config
55  -i/--input : input source
56  -o/--output : output target
57  commands:
58  init : initialize a skelfile in the current directory
59  -n/--name : project name
60 
61  show : describe the project skelfile
62  -f/--file : path to skelfile
63 
64  inspect : inspect the project skelfile
65  -f/--file : path to skelfile
66 
67  make : build project targets
68  -t/--target : target to build
69 
70  run : run a script or command
71 
72  push : push the current project upstream
73 
74  pull : pull the current project from remote
75 
76  clone : clone a remote project
77 
78  commit : commit changes to the project vc
79 
80  edit : edit a project file
81 
82  shell : open the sk-shell interpreter
83 
84 #+end_example
85 
86 Here's skel's skelfile:
87 
88 #+begin_src shell :results output replace :wrap src skel :exports results
89 cat skel.sk
90 #+end_src
91 
92 #+RESULTS:
93 #+begin_src skel
94 ;;; skelfile @ 2023-10-08.02:37:25 -*- mode: skel; -*-
95 :name skel
96 :author "ellis"
97 :version "0.1.0"
98 :description "a hacker's project compiler"
99 :license "MPL"
100 :vc :hg
101 :tags ("lisp")
102 :rules ((build () (print (asdf:make :skel/cli)))
103  (clean () #$rm -rf */*.fasl$#))
104 :documents ((:org "readme"))
105 :components
106 ((:elisp "sk")
107  (:lisp-system
108  "skel"
109  :version "0.1.0"
110  :maintainer "ellis <ellis@rwest.io>"
111  :bug-tracker "https://lab.rwest.io/ellis/skel/issues"
112  :class :package-inferred-system
113  :defsystem-depends-on (:asdf-package-system)
114  :depends-on (:uiop :asdf :sb-posix :sb-bsd-sockets :sb-concurrency :cl-ppcre :std :organ :skel/pkg)
115  :in-order-to ((test-op (test-op skel/tests)))
116  :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests))))
117 :stash "~/dev/comp/stash"
118 :shed "~/dev/comp/shed"
119 :abbrevs nil
120 :snippets
121 ((autogen #$sbcl --eval '(ql:quickload :app/cli/skel)' --eval '(asdf:make :app/cli/skel)'$#))
122 #+end_src
123 
124 This is just a form without the top-level parentheses - you're free to
125 omit them in a skelfile.
126 
127 ** describe
128 The =describe= command can be used to check the currently active
129 skelfile, printing any errors and the parsed object.
130 
131 #+begin_src shell :results output replace :exports both
132  skel show
133 #+end_src
134 
135 #+RESULTS:
136 #+begin_example
137 #<SKEL:SK-PROJECT :ID 1e61-38b1-c5fe-7eac>
138  [standard-object]
139 
140 Slots with :INSTANCE allocation:
141  NAME = SKEL
142  PATH = #P"/home/ellis/dev/skel/skelfile"
143  AUTHOR = "ellis"
144  VERSION = "0.1.0"
145  TAGS = ("lisp")
146  DESCRIPTION = "a hacker's project compiler"
147  LICENSE = "MPL"
148  AST = NIL
149  ID = 2189093230060928684
150  VC = :HG
151  RULES = ((BUILD NIL (PRINT (ASDF/OPERATE:MAKE :SKEL/CLI)))..
152  DOCUMENTS = ((:ORG "readme"))
153  COMPONENTS = ((:ELISP "sk")..
154  SCRIPTS = NIL
155  SNIPPETS = ((AUTOGEN "sbcl --eval '(asdf:make :skel/cli)'"))
156  STASH = #P"~/stash"
157  SHED = #P"~/shed"
158  ABBREVS = NIL
159  IMPORTS = NIL
160 #+end_example
161 
162 ** TODO compile
163 Skelfiles can be compiled to produce a new project skeleton or update
164 an existing one.
165 
166 Try compiling skel's skelfile:
167 
168 #+begin_src shell :results output replace :exports code
169  skel compile
170 #+end_src
171 
172 You may also compile individual components of the project structure,
173 for example, to compile the rules into a makefile:
174 
175 #+begin_src shell :results output replace :exports code
176  skel compile --rules
177 #+end_src
178 
179 #+begin_src shell :results output :wrap src makefile :exports both
180 cat makefile
181 #+end_src
182 
183 #+RESULTS:
184 #+begin_src makefile
185 ### SKEL @ 2023-09-14.01:47:59 --- A hacker's project compiler -*- mode:makefile ; -*-
186 LISP=sbcl --noinform --non-interactive --eval "(asdf:load-asd \"skel.asd\")" --eval "(ql:quickload :skel)"
187 .PHONY: compile clean
188 compile:;$(LISP) --eval "(asdf:compile-system :skel)"
189 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)"
190 clean:;rm -rf *.fasl
191 debug:compile;$(LISP) --eval "(start-repl)"
192 #+end_src
193 
194 * Examples
195 ** Default
196 When you run =skel init= this is the basic skelfile that will be
197 generated in the current directory, depending on the following
198 contexts:
199 - default user config
200 - directory contents
201 - cli args
202 With no cli args or user config and an empty directory the output
203 looks like this:
204 #+begin_src skel
205 ;;; examples @ 2023-10-09.23:38:23 -*- mode: skel; -*-
206 :name "examples"
207 #+end_src
208 ** Imports
209 ** Multi
210 * Tests
211 The unit tests may also be a useful reference:
212 
213 #+begin_src lisp :results output replace :wrap src lisp :exports both :package :skel.tests
214  (ql:quickload :skel/tests)
215  (in-package :skel.tests)
216  (setq *log-level* nil)
217  ;; (setq *catch-test-errors* nil)
218  (setq *compile-tests* t)
219  (list (multiple-value-list (do-tests :skel)) (test-results *test-suite*))
220 #+end_src
221 
222 #+RESULTS:
223 #+begin_src lisp
224 To load "skel/tests":
225  Load 1 ASDF system:
226  skel/tests
227 ; Loading "skel/tests"
228 ..................................................
229 [package skel.vc].................................
230 [package skel.virt]...............................
231 [package skel.comp.asd]...........................
232 [package skel.make]...............................
233 [package skel.ext.asdf]...........................
234 [package skel.tests].
235 in suite SKEL with 6/6 tests:
236 #<PASS VM-TEST788>
237 #<PASS MAKEFILE-TEST787>
238 #<PASS SKELRC-TEST786>
239 #<PASS SKELFILE-TEST785>
240 #<PASS HEADER-COMMENTS-TEST784>
241 #<PASS SANITY-TEST783>
242 No tests failed.
243 #+end_src
244 
245 * API
246 - TODO :: CLOS-based core classes
247 - TODO :: EIEIO-based wrapper classes
248 
249 #+begin_src dot :file api.svg :exports results
250  digraph { splines=true; label="CLOS API"; labelloc="t"; node [shape=record];
251  sk [label="(skel :ID :AST)"]
252  methods [label="(sk-compile sk-expand sk-build\nsk-run sk-init sk-new sk-save\nsk-tangle sk-weave sk-call sk-print)"]
253  skmet [label="(sk-meta :NAME :PATH :VERSION :DESCRIPTION)"]
254  skvcs [label="(sk-vc-meta :VC)"]
255  skcmd [label="(sk-command)"]
256  sktar [label="(sk-target)"]
257  sksrc [label="(sk-source)"]
258  skrec [label="(sk-recipe :COMMANDS)"]
259  skrul [label="(sk-rule :TARGET :SOURCE :RECIPE)"]
260  skdoc [label="(sk-document)"]
261  skscr [label="(sk-script)"]
262  skcfg [label="(sk-config)"]
263  sksni [label="(sk-snippet)"]
264  skabb [label="(sk-abbrev)"]
265  skpro [label="(sk-project\l:RULES\l:DOCUMENTS\l:SCRIPTS\l:SNIPPETS\l:ABBREVS)\l"]
266  sk -> skmet
267  skmet -> skvcs
268  sk -> skcfg
269  sk -> sksni
270  sk -> skabb
271  sk -> sktar
272  sk -> skrul
273  sk -> sksrc
274  sk -> skcmd
275  skvcs -> skpro
276  skmet -> skdoc
277  skmet -> skscr
278  skrul -> skpro
279  skscr -> skpro
280  skdoc -> skpro
281  sksni -> skpro
282  skabb -> skpro
283  sktar -> skrul
284  sksrc -> skrul
285  skrec -> skrul
286  skcmd -> skrec
287  }
288 #+end_src
289 
290 #+RESULTS:
291 [[file:api.svg]]