bahmanm / bmakelib Goto Github PK
View Code? Open in Web Editor NEWA minimalist standard library for writing Makefiles.
Home Page: https://matrix.to/#/#.mk:matrix.org
License: Apache License 2.0
A minimalist standard library for writing Makefiles.
Home Page: https://matrix.to/#/#.mk:matrix.org
License: Apache License 2.0
bmakelib should contain a target to list all available targets along w/ their documentation.
For example:
$ make bmakelib.help
TARGETS
-------
foo: foo inline docs
bar: bar inline docs
baz: no documentation available
VARIABLES
---------
X: no documentation available
Y: Y inline docs
Ideally each the doc for each feature, should start w/ a brief intro, at least one example (or synopsis) followed by functionalities/variables/targets.
Additionally, at this stage, the landing page is quite long and confusing. One possible improvement is moving the installation and usage sections to a "getting started" page to keep the landing page as lean as possible.
Offer the user to use either bmakelib
or other shorter namespace(s).
For example:
some-target : bmk.error-if-blank( VAR1 )
or (๐ผ represents "Makemake" the god of fertility in Polynesian mythology)
some-target : ๐ผ.error-if-blank( VAR1 )
or even
some-target : ๐ฎ.error-if-blank( VAR1 )
some-target : ๐.error-if-blank( VAR1 )
some-target : ๐.error-if-blank( VAR1 )
See also #80
Currently all targets/variables are prefixed w/ bmakelib.
.
For example:
foo : bmakelib.error-if-blank(VAR1)
foo :
...
To reduce clutter and save some a few bytes, it should be possible to omit the prefix for all targets/variables if you ask for it; much in the same vein as bmakelib.conf.logged.convenience-target
For example:
bmakelib.conf.convenience-targets := yes
include bmakelib/bmakelib.mk
foo : error-if-blank(VAR1)
foo :
...
NB: To ensure backward compat and respect user's choice, this should be an opt-in, ie the default behaviour should be bmakelib.conf.convenience-targets := no
.
Discovered this when working on bmakelib Homebrew formula.
The test cases which test features that run make (such as !!bmakelib.logged
), assume a system-dependent path to Gnu Make, ie make
while that can change depending how make is invoked.
For example
Line 52 in 7597c57
when_silent_is_no_and_echo_command_is_yes: Received:
make[1]: Entering directory '/tmp/tmp.RWIV7iQv4E/test_logged'
Logging target some-target to /tmp/tmp.RWIV7iQv4E/test_logged/some-target-20230819-11321692444771-396599475.logged
exec 3>&1 4>&2 \
&& trap 'exec 2>&4 1>&3' 0 1 2 3 \
&& exec 1>/tmp/tmp.RWIV7iQv4E/test_logged/some-target-20230819-11321692444771-396599475.logged 2>&1 \
&& /home/linuxbrew/.linuxbrew/opt/make/bin/make -f Makefile some-target
make[1]: Leaving directory '/tmp/tmp.RWIV7iQv4E/test_logged'
when_silent_is_no_and_echo_command_is_yes: Expected:
make.+Entering.+
Logging target some-target to .+
exec .+ \
\s*&& trap .+ \
\s*&& exec .+ \
\s*&& make -f .+ some-target
make.+Leaving.+
test_logged: ERROR: when_silent_is_no_and_echo_command_is_yes failed.
NB: This bug does NOT impact bmakelib features but rather it's a flaw w/ how the tests are written.
There are a few recipes in Makefile
which run commands w/o chaining them. That makes it quite difficult to debug when things run in the pipeline and fail.
Almost all pattern rules in bmakelib are declared as .PHONY
. That is redundant b/c by definition pattern rules will always be executed unless overridden.
This is a follow up on #37 which turned out to be invalid. Even though setting SHELL
is good practice, it did not solve the failing tests on MacOS.
The problem was in the non-POSIX date format used in bmakelib.logged._make-and-log-target
which only works on Linux.
It should be possible to create the release and make the packages and upload them as part of the pipeline on tag
event.
It should be possible to trigger an update of bmakelib Homebrew tap after a release is created.
I follow the steps and encounter problem in point 2.4: https://github.com/bahmanm/lemmy-synapse?tab=readme-ov-file#24-install-it-already
My terminal throws this
Makefile:30: bmakelib/bmakelib.mk: No such file or directory
when running this:
make \
ansible.user=<REMOTE_USER> \
ansible.password-auth=no \
ansible.lemmy-synapse-server=<YOUR_INSTANCE> \
install
Installing on ubuntu 22.04
What can be done? Hopebrew didnt throw any errors. The package is indeed installed, I can see it listed in brew installations.
The current targets only generate DEB and RPM packages which should be enough for most Linux distros.
Many programmers who use an Apple machine, use homebrew. Additionally homebrew is also available for Linux.
It's quite wasteful to build the DEB & RPM packages on every push and simply discard them - esp since this Travis doesn't charge for FOSS repos.
A better strategy is to run build
either only on tags or main
.
I find myself frequently needing to generate a ยตs precision timestamp.
some-target :
@echo Microseconds: $(call now,micros)
@echo Milliseconds: $(call now,millis)
@echo Seconds: $(call now,secs)
@echo Default precision (millis): $(call now)
$ make some-target
Microseconds: 1693049901575259
Milliseconds: 1693049901575
Seconds: 1693049902
Default precision (millis): 1693049901575
This can be used to name log files or to prefix log entries w/ an accurate timestamp.
โ The question is, is it a common enough use-cases to be included in bmakelib?
Currently, the only way to use enum
is to use it a target dependency. It'd be useful to provide an API which would allow defining and using an enum via $(call)
construct.
.PHONY : bmakelib/bmakelib.mk
include bmakelib/bmakelib.mk
.PHONY : a-target
a-target : bmakelib.default-if-blank( VAR1,foo )
a-target :
@echo "VAR1 = '$(VAR1)'"
$ make VAR1= a-target
VAR1 = 'foo'
$ make VAR1= a-target
VAR1 = ''
$ make bmakelib.conf.default-if-blank.SILENT=no VAR1= a-target
Using default value 'foo' for variable 'VAR1'
VAR1 = ''
Inspired by a thread in GNU Make mailing list.
One of the pains of using $(shell ...)
is that you need to take extra measures to check the exit status of the command and potentially do something in case of failure.
It'd be great if there was something like bmakelib.shell.error-if-nonzero
which, in case of failed shell commands, would immediately exit the makefile w/ an error message.
For example, given:
VAR1 := $(call bmakelib.shell.error-if-nonzero, echo kaboom && false)
...
Using the above makefile would result in
$ make
*** Shell command "echo kaboom && false" with a non-zero return code.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
pkg/debbuild-env.Dockerfile
ubuntu 22.04
pkg/rpmbuild-env.Dockerfile
The pipeline doesn't run the tests or anything else and it just prints out the bash version.
The variable SHELL
has its value /bin/bash
almost everywhere.
This works just fine on Linux but during attempts to create a homebrew formula, turned out that value loads the outdated bash 3 instead of the more recent 5.
The solution is to use /usr/bin/env bash
instead.
The current output is quite bloated and is not easy to find the test case or suite you're interested in.
There are cases where all the possible values of a variable are already known in advance. For example, a variable deployment.environment
can only be set to one of testing
, staging
and production
.
It could be possible to capture that via a bmakelib target and validate the values.
For example, a pseudo-code could look like
$(call bmakelib.enum.define VAR,value1,value2)
...
a-target : $(call bmakelib.enum.get VAR)
@echo VAR is $(VAR)
$ make VAR=value1 a-target
VAR is value1
$ make VAR=unknown a-target
Error: invalid value for VAR: unknown
An alternative approach, which I'd prefer is using targets instead of call
:
a-target : bmakelib.enum.define( MY_ENUM,value1,value2 )
a-target : bmakelib.enum.get( VAR,MY_ENUM )
@echo VAR is $(VAR)
Things like make foo!timed!!logged
work flawlessly, for now! But it's best to capture that behaviour in a test suite.
Follow up on a conversation on Mastodon.
Is it possible to have a smarterโข way of caching a target based on the contents rather than modification time?
For example:
_expensive-target-workhorse:
a bunch of expensive commands
expensive-target : _expensive-target-workhorse!cached
One idea for the implementation (non-PHONY targets) is to store the caches in PROJECT_ROOT/.bmakelib-caches
& use checksums to identify if a target exists in the cache and retrieve the value. In the case of directories, the checksum of the tar
'ed archive can be used.
It can simplify using bmakelib, eg in a pipeline or a "toolbox" image on the user's machine.
For a decent coverage the following platforms should be supported:
The install
recipe passes the file permissions using --mode
to install
which breaks on MacOS.
Move default-if-blank
and error-if-blank
to the new var
namespace (eg bmakelib.var.default-if-blank
)
Filenames and doc links should also be updated as it makes sense to either move them to a single var.mk
file or prefix each existing file w/ var.
.
Follow up on #36 which turned out to be invalid.
The culprit is not setting SHELL
in the temporary Makefile
s generated by tests. In its absence, Make will use /bin/sh
which breaks tests on MacOS.
It would be useful to have a dictionary to group related variables/values, either statically or dynamically.
For example:
$(call dict.put,DEPLOY,env,prod)
$(call dict.put,DEPLOY,service,accounts)
$(call dict.put,DEPLOY,host,accounts.my-cool-product.com)
$(call dict.put,DEPLOY,gpg-key,992443840122)
$(call dict.put,BUILD,arch,x86_64)
$(call dict.put,BUILD,dir,/tmp/my-app/build)
It can, of course, be provided to work as a target:
define-config : dict.put( DEPLOY,env,prod )
define-config : dict.put( DEPLOY,service,accounts )
define-config : dict.put( DEPLOY,host,accounts.my-cool-product.com )
define-config : dict.put( DEPLOY,gpg-key,992443840122 )
deploy : define-config
deploy :
/usr/bin/deploy \
--env $(call dict.get,DEPLOY,env) \
--server $(call dict.get,DEPLOY,service) \
$(call dict.get,DEPLOY,host)
Not sure how useful it's going to be TBH.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.