Skip to content

Commit

Permalink
Refactor Makefile layout
Browse files Browse the repository at this point in the history
  • Loading branch information
ingydotnet committed Sep 4, 2024
1 parent 4a9bb08 commit b47ce21
Show file tree
Hide file tree
Showing 220 changed files with 7,191 additions and 64 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
/shellcheck*
/out.txt
/.clojure/
/.local/
/.problem/
/*.ys
/*.clj
61 changes: 45 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,38 @@ ROOT := $(shell pwd)

BIN := bin

YS := $(BIN)/ys
YS_VERSION := 0.1.74

YS_LOCAL := .local
YS_LOCAL_PREFIX := $(YS_LOCAL)/ys-$(YS_VERSION)
YS_LOCAL_BIN := $(YS_LOCAL_PREFIX)/bin
YS := $(YS_LOCAL_PREFIX)/bin/ys-$(YS_VERSION)
CFGLET := $(BIN)/configlet
SHELLCHECK := $(BIN)/shellcheck
VERIFY := $(BIN)/verify-exercises

ifdef EXERCISM_YAMLSCRIPT_GHA
YS := ys
YS := ys-$(YS_VERSION)
SHELLCHECK := shellcheck
endif

export PATH := $(ROOT)/bin:$(PATH)
export PATH := $(ROOT)/bin:$(YS_LOCAL_BIN):$(PATH)

EXERCISE_DIRS := $(shell find exercises -name .meta)
EXERCISE_DIRS := $(shell find exercises -name .meta | sort)
EXERCISE_DIRS := $(EXERCISE_DIRS:%/.meta=%)
EXERCISES := $(EXERCISE_DIRS:exercises/practice/%=%)

EXERCISE_MAKEFILES := $(EXERCISE_DIRS:%=%/Makefile)
EXERCISE_GNU_MAKEFILES := $(EXERCISE_DIRS:%=%/GNUmakefile)
EXERCISE_YS_MAKEFILES := $(EXERCISE_DIRS:%=%/.yamlscript/exercise.mk)
EXERCISE_META_MAKEFILES := $(EXERCISE_DIRS:%=%/.meta/Makefile)
EXERCISE_YS_INSTALLERS := $(EXERCISE_DIRS:%=%/.yamlscript/exercism-ys-installer)

a := (
b := )
EXERCISE_META_LINKS := \
$(shell ls -d exercises/practice/*/*-test.ys \
exercises/practice/*/Makefile \
| perl -pe 's{$a.*$b/$a.*$b}{$$1/.meta/$$2}')
$(shell ls exercises/practice/*/.yamlscript/exercise.mk \
| perl -pe 's{$a.*$b/$a.*/.*$b}{$$1/.meta/$$2}')

CHECKS := \
check-yaml \
Expand All @@ -35,7 +45,11 @@ CHECKS := \

GEN_FILES := \
$(EXERCISE_MAKEFILES) \
$(EXERCISE_GNU_MAKEFILES) \
$(EXERCISE_YS_MAKEFILES) \
$(EXERCISE_META_MAKEFILES) \
$(EXERCISE_META_LINKS) \
$(EXERCISE_YS_INSTALLERS) \
config.json \

SHELL_FILES := \
Expand Down Expand Up @@ -149,18 +163,31 @@ clean:
realclean: clean
$(RM) $(CFGLET)
$(RM) $(SHELLCHECK)
$(RM) $(BIN)/ys*
$(RM) -r $(CLOJURE_REPO) $(PROBLEM_REPO)
$(RM) -r $(CLOJURE_REPO) $(PROBLEM_REPO) $(YS_LOCAL)

reset:
git checkout -- config.*
git status -- exercises | grep exercises | xargs rm -fr

exercises/practice/%/Makefile: common/exercise.mk
exercises/practice/%/GNUmakefile: common/exercise.mk
cp -p $< $@

exercises/practice/%/GNUmakefile: common/makefile.mk
cp -p $< $@

exercises/practice/%/.yamlscript/exercise.mk: common/exercise-extra.mk
mkdir -p $$(dirname $@)
cp -p $< $@

$(EXERCISE_META_LINKS):
( d=$$(dirname $@); f=$$(basename $@); cd $$d && ln -fs ../$$f )
exercises/practice/%/.meta/Makefile: common/exercise-meta.mk
cp -p $< $@

exercises/practice/%/.meta/.yamlscript/exercise.mk: ../../.yamlscript/exercise.mk
ln -fs $@ $<

exercises/practice/%/.yamlscript/exercism-ys-installer: common/exercism-ys-installer
mkdir -p $$(dirname $@)
cp -p $< $@


%.json: %.yaml $(YS) Makefile
Expand All @@ -175,13 +202,15 @@ $(CLOJURE_REPO):
$(CFGLET):
$(BIN)/fetch-configlet


ifdef EXERCISM_YAMLSCRIPT_GHA
# Dummy rule for GHA
ys shellcheck:
$(YS) shellcheck:

ifndef EXERCISM_YAMLSCRIPT_GHA
bin/ys:
else
$(YS):
curl -s https://yamlscript.org/install | \
PREFIX=$(ROOT) BIN=1 bash
BIN=1 PREFIX=$(YS_LOCAL_PREFIX) VERSION=$(YS_VERSION) bash

ifeq (,$(wildcard $(SHELLCHECK)))
bin/shellcheck: $(SHELLCHECK_DIR)
Expand Down
1 change: 1 addition & 0 deletions common/exercise-extra.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
YS_VERSION := 0.1.74
24 changes: 24 additions & 0 deletions common/exercise-meta.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SHELL := bash

BASE := $(shell pwd)

include .yamlscript/exercise.mk

YS_LOCAL_PREFIX := ../../../../.local/ys-$(YS_VERSION)

YS_LOCAL_BIN := $(YS_LOCAL_PREFIX)/bin

YS_BIN := $(YS_LOCAL_BIN)/ys-$(YS_VERSION)

TEST_FILE ?= $(wildcard *-test.ys)


export PATH := $(YS_LOCAL_BIN):$(PATH)

export YSPATH := $(BASE)


default:

test: $(YS_BIN)
prove -v $(TEST_FILE)
52 changes: 48 additions & 4 deletions common/exercise.mk
Original file line number Diff line number Diff line change
@@ -1,11 +1,55 @@
SHELL := bash

test ?= $(wildcard *-test.ys)
BASE := $(shell pwd)

export YSPATH=$(shell pwd -P)
include .yamlscript/exercise.mk

YS_LOCAL_PREFIX := ../../../.local/ys-$(YS_VERSION)

ifeq (,$(shell [[ "$(YS_LOCAL_PREFIX)" ]] && echo ok))
YS_LOCAL_PREFIX := ../.yamlscript/ys-$(YS_VERSION)
endif

YS_LOCAL_BIN := $(YS_LOCAL_PREFIX)/bin

YS_BIN := $(YS_LOCAL_BIN)/ys-$(YS_VERSION)

TEST_FILE ?= $(wildcard *-test.ys)

export PATH := $(YS_LOCAL_BIN):$(PATH)

export YSPATH := $(BASE)


default:
@echo " No default make rule. Try 'make test'."

test: $(YS_BIN)
prove -v $(TEST_FILE)

$(YS_BIN):
@echo "$$install_msg"

install-ys:
bash .yamlscript/exercism-ys-installer $(YS_VERSION) $(MAKE)


define install_msg

This YAMLScript Exercism exercise requires the YAMLScript interpreter file:

$(YS_BIN)

to be installed.

You can install it with:

$(MAKE) install-ys

This should only take a few seconds and you only need to do this once.

Other exercises will use the same file.

endef

test:
prove -v $(test)
export install_msg
85 changes: 85 additions & 0 deletions common/exercism-ys-installer
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/env/bin/env bash

set -euo pipefail

main() {
setup "$@"

installed || install-from-local
installed || install-from-release
installed || install-from-build
installed ||
die "Installing '$installed' failed. Giving up." \
"Consider filing an issue at: $gh_issue_url"

echo
echo 'Success!'
echo
echo "$installed is now installed."
}

installed() { [[ $(readlink "$bin/ys-0") == ys-$version ]]; }

install-from-local() (
path=$(command -v "$ysfq")
if [[ -f $path ]]; then
cp "$path" "$bin"/
ln -fs "$ysfq" "$bin/ys-0"
ln -fs "$ysfq" "$bin/ys"
fi
)

install-from-release() (
echo "Installing '$installed' for this exercise."

curl -s https://yamlscript.org/install |
BIN=1 VERSION="$(YS_VERSION)" PREFIX="$prefix" bash
)

install-from-build() (
echo "The binary release install failed."
echo "We can attempt to build and install $ysfq now."
echo "This can take from 1 to 5 minutes to complete."
echo
printf "Enter 'y' to continue: "

read -r answer

[[ $answer == y ]] ||
die 'Giving up.'

[[ -d /tmp && -w /tmp ]] ||
die "Can't write to /tmp" \
'Giving up.'

set -x

rm -fr "$yamlscript_clone"

git clone --branch="$version" "$yamlscript_repo" "$yamlscript_clone"

"$make" -C "$yamlscript_clone/ys" install PREFIX="$prefix"
)

setup() {
version=$1
make=${2:-make}

[[ $version =~ ^0\.1\.[0-9]+$ ]] ||
die "Invalid YS_VERSION '$version'"

prefix=../.yamlscript/v$version
bin=$prefix/bin
ysfq=ys-$version
installed=$bin/$ysfq
yamlscript_repo=https://github.com/yamlscript
yamlscript_clone=/tmp/yamlscript-exercism
gh_issue_url=https://github.com/exercism/yamlscript/issues
}

die() {
printf '%s\n' "$@" >&2
exit 1
}

main "$@"
8 changes: 8 additions & 0 deletions common/makefile.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This Makefile is a decoy to attempt to detect when a non-GNU make is being
# used and alert the user.

test:
@echo "You appear to be using a non-GNU version of the 'make' program."
@echo "The YAMLScript Exercism track requires you to use GNU make."
@echo "Please try 'make $@' again using GNU make."
@exit 1
5 changes: 4 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
],
"test": [
"%{kebab_slug}-test.ys",
"Makefile"
"GNUmakefile",
"Makefile",
".yamlscript/exercise.mk",
".yamlscript/exercism-ys-installer"
],
"example": [
".meta/%{kebab_slug}.ys"
Expand Down
3 changes: 3 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ files:
- '%{kebab_slug}.ys'
test:
- '%{kebab_slug}-test.ys'
- GNUmakefile
- Makefile
- .yamlscript/exercise.mk
- .yamlscript/exercism-ys-installer
example:
- .meta/%{kebab_slug}.ys

Expand Down
1 change: 1 addition & 0 deletions exercises/practice/acronym/.meta/.yamlscript/exercise.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
YS_VERSION := 0.1.74
1 change: 0 additions & 1 deletion exercises/practice/acronym/.meta/Makefile

This file was deleted.

24 changes: 24 additions & 0 deletions exercises/practice/acronym/.meta/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SHELL := bash

BASE := $(shell pwd)

include .yamlscript/exercise.mk

YS_LOCAL_PREFIX := ../../../../.local/ys-$(YS_VERSION)

YS_LOCAL_BIN := $(YS_LOCAL_PREFIX)/bin

YS_BIN := $(YS_LOCAL_BIN)/ys-$(YS_VERSION)

TEST_FILE ?= $(wildcard *-test.ys)


export PATH := $(YS_LOCAL_BIN):$(PATH)

export YSPATH := $(BASE)


default:

test: $(YS_BIN)
prove -v $(TEST_FILE)
1 change: 1 addition & 0 deletions exercises/practice/acronym/.yamlscript/exercise.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
YS_VERSION := 0.1.74
Loading

0 comments on commit b47ce21

Please sign in to comment.