changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > org > notes / skel-readme.org

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