Quality Assurance, Audit and Tags #14
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;;
|
;;;
|
||||||
;;; This file is designed to process the command line arguments using the standardized 'getopts-long' as described in the GNU Guile reference manual <https://www.gnu.org/software/guile/manual/html_node/getopt_002dlong.html>.
|
;;; Backend for the `pmake` command to process the command line arguments using the standardized 'getopts-long' as described in the GNU Guile reference manual <https://www.gnu.org/software/guile/manual/html_node/getopt_002dlong.html>.
|
||||||
;;;
|
;;;
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
-(define-module (potato exceptions)
|
-(define-module (potato exceptions)
|
||||||
#:use-module (ice-9 exceptions)
|
#:use-module (ice-9 exceptions)
|
||||||
#:export (bad-key-type
|
#:export (bad-key-type
|
||||||
bad-value-type
|
bad-value-type
|
||||||
bad-proc-output
|
bad-proc-output
|
||||||
invalid-macro
|
invalid-macro
|
||||||
not-a-regular-file
|
not-a-regular-file
|
||||||
not-a-procedure
|
not-a-procedure
|
||||||
no-read-access-to-file
|
no-read-access-to-file
|
||||||
))
|
))
|
||||||
|
|
||||||
(define (make-bad-key-type origin irritants)
|
(define (make-bad-key-type origin irritants)
|
||||||
(make-exception
|
(make-exception
|
||||||
|
242
potato/make.scm
242
potato/make.scm
@ -1,3 +1,13 @@
|
|||||||
|
;;; The Project Manager ("pman") -- GNU Guile-based solution for project management
|
||||||
|
;;; Copyright (C) 2021 Mike Gran <spk121@yahoo.com>
|
||||||
|
;;; Copyright (C) 2022 Jacob Hrbek <kreyren@rixotstudio.cz>
|
||||||
|
;;;
|
||||||
|
;;; The Project Manager is a Free/Libre Open-Source Software; you can redistribute it and/or modify it under the terms of the MIT License as published by the Massachusetts Institute of Technology
|
||||||
|
;;;
|
||||||
|
;;; This project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details.
|
||||||
|
;;;
|
||||||
|
;;; You should have received a copy of the MIT License along with the project. If not, see <https://mit-license.org>.
|
||||||
|
|
||||||
(define-module (potato make)
|
(define-module (potato make)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (ice-9 exceptions)
|
#:use-module (ice-9 exceptions)
|
||||||
@ -9,30 +19,39 @@
|
|||||||
#:use-module (potato makevars)
|
#:use-module (potato makevars)
|
||||||
#:use-module (potato rules)
|
#:use-module (potato rules)
|
||||||
#:use-module (potato text)
|
#:use-module (potato text)
|
||||||
#:export (initialize
|
#:export (initialize execute)
|
||||||
execute)
|
|
||||||
#:re-export (%suffix-rules
|
#:re-export (%suffix-rules
|
||||||
lazy-assign ?=
|
lazy-assign ?=
|
||||||
assign :=
|
assign :=
|
||||||
reference $ Q
|
;; WTF(Krey): Why is the 'Q' here?
|
||||||
reference-func $$
|
reference $ Q
|
||||||
target-rule :
|
reference-func $$
|
||||||
suffix-rule ->
|
target-rule :
|
||||||
target-name $@
|
suffix-rule ->
|
||||||
target-basename $*
|
target-name $@
|
||||||
newer-prerequisites $? $$?
|
target-basename $*
|
||||||
prerequisites $^ $$^
|
newer-prerequisites $? $$?
|
||||||
primary-prerequisite $<
|
prerequisites $^ $$^
|
||||||
string-compose ~
|
primary-prerequisite $<
|
||||||
silent-compose ~@
|
string-compose ~
|
||||||
always-execute-compose ~+
|
silent-compose ~@
|
||||||
ignore-error-compose ~-
|
always-execute-compose ~+
|
||||||
install-alternate-system-driver
|
ignore-error-compose ~-
|
||||||
))
|
install-alternate-system-driver))
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;;
|
||||||
|
;;; TBD
|
||||||
|
;;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;; Project version
|
||||||
(define %version "1.0")
|
(define %version "1.0")
|
||||||
|
|
||||||
|
;; WTF(Krey)
|
||||||
(define %debug-argv0 #f)
|
(define %debug-argv0 #f)
|
||||||
|
|
||||||
|
;; WTF(Krey): Was commented out by the original author.. no idea why
|
||||||
;; #:re-export (
|
;; #:re-export (
|
||||||
;; lazy-assign ?=
|
;; lazy-assign ?=
|
||||||
;; assign :=
|
;; assign :=
|
||||||
@ -42,37 +61,44 @@
|
|||||||
;; compose ~
|
;; compose ~
|
||||||
;; ))
|
;; ))
|
||||||
|
|
||||||
;; Asynchronous events.
|
;;; Asynchronous events.
|
||||||
;; SIGHUP, SIGTERM, SIGINT and SIGQUIT remove the current target
|
;;; SIGHUP, SIGTERM, SIGINT and SIGQUIT remove the current target
|
||||||
;; unless that target is a directory or the target is a prerequisite
|
;;; unless that target is a directory or the target is a prerequisite
|
||||||
;; of .PRECIOUS or the -n, -q, or -p option was specified. This
|
;;; of .PRECIOUS or the -n, -q, or -p option was specified. This
|
||||||
;; deletion shall be reported to the error port, then the default for
|
;;; deletion shall be reported to the error port, then the default for
|
||||||
;; that action will continue.
|
;;; that action will continue.
|
||||||
|
|
||||||
;; .SILENT
|
;;; .SILENT
|
||||||
;; The utility shall write all commands to the standard output unless
|
;;; The utility shall write all commands to the standard output unless
|
||||||
;; the -s option was specified, the command is prefixed with +, or
|
;;; the -s option was specified, the command is prefixed with +, or
|
||||||
;; .SILENT has the current target as a prerequisite or has no pre
|
;;; .SILENT has the current target as a prerequisite or has no pre
|
||||||
;; requisites.
|
;;; requisites.
|
||||||
|
|
||||||
;; Nothing to be done
|
;;; Nothing to be done
|
||||||
;; If make was invoked but found no work to do, it shall write a
|
;;; If make was invoked but found no work to do, it shall write a
|
||||||
;; message to standard output that no action was taken
|
;;; message to standard output that no action was taken
|
||||||
|
|
||||||
;; File Touched
|
;;; File Touched
|
||||||
;; If the -t option was specified, make shall write to standard
|
;;; If the -t option was specified, make shall write to standard
|
||||||
;; output a message for each file that was touched.
|
;;; output a message for each file that was touched.
|
||||||
|
|
||||||
;; Verbosity is 0 = silent, 1 = terse, 2 = default, 3 = verbose
|
;; Verbosity is 0 = silent, 1 = terse, 2 = default, 3 = verbose
|
||||||
(define %verbosity 2)
|
(define %verbosity 2)
|
||||||
|
;; WTF(Krey)
|
||||||
(define %opt-verbose #f)
|
(define %opt-verbose #f)
|
||||||
|
;; WTF(Krey)
|
||||||
(define %opt-ignore-errors #f)
|
(define %opt-ignore-errors #f)
|
||||||
|
;; WTF(Krey)
|
||||||
(define %opt-continue-on-error #f)
|
(define %opt-continue-on-error #f)
|
||||||
|
;; WTF(Krey)
|
||||||
(define %targets '())
|
(define %targets '())
|
||||||
|
;; WTF(Krey)
|
||||||
(define %initialized #f)
|
(define %initialized #f)
|
||||||
|
|
||||||
|
;; Output handlers
|
||||||
(define (critical spec . args)
|
(define (critical spec . args)
|
||||||
(apply format (append (list #t spec) args)))
|
(apply format (append (list #t spec) args)))
|
||||||
|
;; FIXME-QA(Krey): The 'print' is too generic, should we rename it?
|
||||||
(define (print spec . args)
|
(define (print spec . args)
|
||||||
(when (>= %verbosity 2)
|
(when (>= %verbosity 2)
|
||||||
(apply format (append (list #t spec) args))))
|
(apply format (append (list #t spec) args))))
|
||||||
@ -91,15 +117,15 @@
|
|||||||
(continue-on-error (single-char #\k) (value #f))
|
(continue-on-error (single-char #\k) (value #f))
|
||||||
(no-execution (single-char #\n) (value #f))
|
(no-execution (single-char #\n) (value #f))
|
||||||
(ascii (single-char #\A) (value #f))
|
(ascii (single-char #\A) (value #f))
|
||||||
(strict (single-char #\S) (value #f))
|
(strict (single-char #\S) (value #f))))
|
||||||
))
|
|
||||||
|
|
||||||
|
;; FIXME-QA(Krey): This is calling `format` multiple times to print one line which is resource inefficient
|
||||||
(define (display-help-and-exit argv0)
|
(define (display-help-and-exit argv0)
|
||||||
(format #t "~A [-hvqVeEbn] [KEY=VALUE ...] [targets ...]~%" argv0)
|
(format #t "~A [-hvqVeEbn] [KEY=VALUE ...] [targets ...]~%" argv0)
|
||||||
(format #t " -h, --help print help and exit~%")
|
(format #t " -h, --help print help and exit~%")
|
||||||
(format #t " -v, --version print version and exit~%")
|
(format #t " -v, --version print version and exit~%")
|
||||||
(format #t " -V 0..3, --verbosity=0..3~%")
|
(format #t " -V 0..3, --verbosity=0..3~%")
|
||||||
(format #t " set output level from 0=silent to 3=verbose~%")
|
(format #t " set output level from 0=silent to 3=verbose~%")
|
||||||
(format #t " -e, --environment use environment variables~%")
|
(format #t " -e, --environment use environment variables~%")
|
||||||
(format #t " -E, --elevate-environment~%")
|
(format #t " -E, --elevate-environment~%")
|
||||||
(format #t " use environment variables and let~%")
|
(format #t " use environment variables and let~%")
|
||||||
@ -116,9 +142,11 @@
|
|||||||
(format #t " ASCII only output and no colors~%")
|
(format #t " ASCII only output and no colors~%")
|
||||||
(format #t " -S, --strict~%")
|
(format #t " -S, --strict~%")
|
||||||
(format #t " causes some behaviours to throw errors~%")
|
(format #t " causes some behaviours to throw errors~%")
|
||||||
|
;; FIXME-QA(Krey): 'exit'? It should be using 'throw'
|
||||||
(exit 0))
|
(exit 0))
|
||||||
|
|
||||||
(define (display-version-and-exit argv0)
|
(define (display-version-and-exit argv0)
|
||||||
|
"Procedure to output the project version and exit"
|
||||||
(format #t "~a~%" argv0)
|
(format #t "~a~%" argv0)
|
||||||
(format #t " using potato make~a~%" %version)
|
(format #t " using potato make~a~%" %version)
|
||||||
(exit 0))
|
(exit 0))
|
||||||
@ -130,12 +158,12 @@ of pairs of KEY VAL"
|
|||||||
(lambda (str)
|
(lambda (str)
|
||||||
(let ((tok (string-split str #\=)))
|
(let ((tok (string-split str #\=)))
|
||||||
(cond
|
(cond
|
||||||
((= 1 (length tok))
|
((= 1 (length tok))
|
||||||
#f)
|
#f)
|
||||||
((= 2 (length tok))
|
((= 2 (length tok))
|
||||||
(cons (car tok) (cadr tok)))
|
(cons (car tok) (cadr tok)))
|
||||||
(else
|
(else
|
||||||
(invalid-macro "parse-macros" str)))))
|
(invalid-macro "parse-macros" str)))))
|
||||||
lst))
|
lst))
|
||||||
|
|
||||||
(define (parse-targets lst)
|
(define (parse-targets lst)
|
||||||
@ -144,12 +172,12 @@ return them in a list."
|
|||||||
(filter-map
|
(filter-map
|
||||||
(lambda (str)
|
(lambda (str)
|
||||||
(if (string-index str #\=)
|
(if (string-index str #\=)
|
||||||
#f
|
#f
|
||||||
str))
|
str))
|
||||||
lst))
|
lst))
|
||||||
|
|
||||||
(define* (initialize #:optional
|
(define* (initialize #:optional
|
||||||
(arguments #f))
|
(arguments #f))
|
||||||
"Set up the options, rules, and makevars. If ARGUMENTS
|
"Set up the options, rules, and makevars. If ARGUMENTS
|
||||||
is not set, it will use options, makevars, and targets as
|
is not set, it will use options, makevars, and targets as
|
||||||
specified by the command line. If it is set, it is
|
specified by the command line. If it is set, it is
|
||||||
@ -166,14 +194,14 @@ arguments."
|
|||||||
|
|
||||||
;; We start of with the --help and --version command-line arguments.
|
;; We start of with the --help and --version command-line arguments.
|
||||||
(let ((options (getopt-long arguments option-spec))
|
(let ((options (getopt-long arguments option-spec))
|
||||||
(%opt-builtins #f)
|
(%opt-builtins #f)
|
||||||
(%opt-environment #f)
|
(%opt-environment #f)
|
||||||
(%opt-elevate-environment #f)
|
(%opt-elevate-environment #f)
|
||||||
(%opt-no-errors #f)
|
(%opt-no-errors #f)
|
||||||
(%opt-continue-on-error #f)
|
(%opt-continue-on-error #f)
|
||||||
(%opt-no-execution #f)
|
(%opt-no-execution #f)
|
||||||
(%opt-ascii #f)
|
(%opt-ascii #f)
|
||||||
(%opt-strict #f))
|
(%opt-strict #f))
|
||||||
(when (option-ref options 'help #f)
|
(when (option-ref options 'help #f)
|
||||||
(display-help-and-exit (car arguments)))
|
(display-help-and-exit (car arguments)))
|
||||||
(when (option-ref options 'version #f)
|
(when (option-ref options 'version #f)
|
||||||
@ -188,32 +216,32 @@ arguments."
|
|||||||
;; command-line options to override MAKEFLAGS options.
|
;; command-line options to override MAKEFLAGS options.
|
||||||
(when %opt-environment
|
(when %opt-environment
|
||||||
(let ((mf (getenv "MAKEFLAGS")))
|
(let ((mf (getenv "MAKEFLAGS")))
|
||||||
(when mf
|
(when mf
|
||||||
(let ((tokens (string-tokenize mf)))
|
(let ((tokens (string-tokenize mf)))
|
||||||
(when (member "silent" tokens)
|
(when (member "silent" tokens)
|
||||||
(set! %verbosity 0))
|
(set! %verbosity 0))
|
||||||
(when (member "terse" tokens)
|
(when (member "terse" tokens)
|
||||||
(set! %verbosity 1))
|
(set! %verbosity 1))
|
||||||
(when (member "verbose" tokens)
|
(when (member "verbose" tokens)
|
||||||
(set! %verbosity 3))
|
(set! %verbosity 3))
|
||||||
(when (member "builtins" tokens)
|
(when (member "builtins" tokens)
|
||||||
(set! %opt-builtins #t))
|
(set! %opt-builtins #t))
|
||||||
(when (member "ascii" tokens)
|
(when (member "ascii" tokens)
|
||||||
(set! %opt-ascii #t))
|
(set! %opt-ascii #t))
|
||||||
(when (member "ignore-errors" tokens)
|
(when (member "ignore-errors" tokens)
|
||||||
(set! %opt-ignore-errors #t))
|
(set! %opt-ignore-errors #t))
|
||||||
(when (member "continue-on-error" tokens)
|
(when (member "continue-on-error" tokens)
|
||||||
(set! %opt-continue-on-error #t))
|
(set! %opt-continue-on-error #t))
|
||||||
(when (member "strict" tokens)
|
(when (member "strict" tokens)
|
||||||
(set! %opt-strict #t))
|
(set! %opt-strict #t))
|
||||||
(when (member "no-execution" tokens)
|
(when (member "no-execution" tokens)
|
||||||
(set! %opt-no-execution #t))))))
|
(set! %opt-no-execution #t))))))
|
||||||
|
|
||||||
;; Now the bulk of the command-line options.
|
;; Now the bulk of the command-line options.
|
||||||
(when (option-ref options 'verbosity #f)
|
(when (option-ref options 'verbosity #f)
|
||||||
(let ((verbosity (string->number (option-ref options 'verbosity #f))))
|
(let ((verbosity (string->number (option-ref options 'verbosity #f))))
|
||||||
(when verbosity
|
(when verbosity
|
||||||
(set! %verbosity verbosity))))
|
(set! %verbosity verbosity))))
|
||||||
(when (option-ref options 'builtins #f)
|
(when (option-ref options 'builtins #f)
|
||||||
(set! %opt-builtins #t))
|
(set! %opt-builtins #t))
|
||||||
(when (option-ref options 'elevate-environment #f)
|
(when (option-ref options 'elevate-environment #f)
|
||||||
@ -234,22 +262,22 @@ arguments."
|
|||||||
(let ((extra (option-ref options '() '())))
|
(let ((extra (option-ref options '() '())))
|
||||||
(initialize-text %opt-ascii)
|
(initialize-text %opt-ascii)
|
||||||
(initialize-makevars (parse-macros extra)
|
(initialize-makevars (parse-macros extra)
|
||||||
%opt-environment
|
%opt-environment
|
||||||
%opt-elevate-environment
|
%opt-elevate-environment
|
||||||
%opt-builtins
|
%opt-builtins
|
||||||
%opt-strict
|
%opt-strict
|
||||||
%verbosity
|
%verbosity
|
||||||
%opt-ascii)
|
%opt-ascii)
|
||||||
;; The remaining command-line words are the build targets that
|
;; The remaining command-line words are the build targets that
|
||||||
;; we're going to tackle.
|
;; we're going to tackle.
|
||||||
(set! %targets (parse-targets extra))
|
(set! %targets (parse-targets extra))
|
||||||
(initialize-rules %targets
|
(initialize-rules %targets
|
||||||
%opt-builtins
|
%opt-builtins
|
||||||
%opt-ignore-errors
|
%opt-ignore-errors
|
||||||
%opt-continue-on-error
|
%opt-continue-on-error
|
||||||
%opt-no-execution
|
%opt-no-execution
|
||||||
%verbosity
|
%verbosity
|
||||||
%opt-ascii)
|
%opt-ascii)
|
||||||
(set! %initialized #t)
|
(set! %initialized #t)
|
||||||
%targets
|
%targets
|
||||||
)))
|
)))
|
||||||
@ -269,27 +297,27 @@ targets listed on the parsed command-line are used."
|
|||||||
(debug "No build target was explicitely specified.~%")
|
(debug "No build target was explicitely specified.~%")
|
||||||
(let ((rule (first-target-rule-name)))
|
(let ((rule (first-target-rule-name)))
|
||||||
(if rule
|
(if rule
|
||||||
(begin
|
(begin
|
||||||
(debug "Using first rule ~a~A~a as the build target.~%" (lquo) rule (rquo))
|
(debug "Using first rule ~a~A~a as the build target.~%" (lquo) rule (rquo))
|
||||||
(set! targets (list rule)))
|
(set! targets (list rule)))
|
||||||
;; else
|
;; else
|
||||||
(debug "There are no target rules in the recipe.~%"))))
|
(debug "There are no target rules in the recipe.~%"))))
|
||||||
|
|
||||||
;; Build each target in order.
|
;; Build each target in order.
|
||||||
(when (not (null? targets))
|
(when (not (null? targets))
|
||||||
(let loop ((target (car targets))
|
(let loop ((target (car targets))
|
||||||
(rest (cdr targets)))
|
(rest (cdr targets)))
|
||||||
(if (not (build target))
|
(if (not (build target))
|
||||||
(begin
|
(begin
|
||||||
(print "The recipe for “~A” has failed.~%" target)
|
(print "The recipe for “~A” has failed.~%" target)
|
||||||
#f)
|
#f)
|
||||||
;; else
|
;; else
|
||||||
(begin
|
(begin
|
||||||
(print "The recipe “~A” finished successfully.~%" target)
|
(print "The recipe “~A” finished successfully.~%" target)
|
||||||
(if (not (null? rest))
|
(if (not (null? rest))
|
||||||
(loop (car rest) (cdr rest))
|
(loop (car rest) (cdr rest))
|
||||||
|
|
||||||
;; True if all targets are built successfully.
|
;; True if all targets are built successfully.
|
||||||
#t))))))
|
#t))))))
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
;;; make.scm ends here
|
||||||
|
0
potato/zz-README.org~
Normal file
0
potato/zz-README.org~
Normal file
Loading…
Reference in New Issue
Block a user