178 lines
8.0 KiB
Makefile
178 lines
8.0 KiB
Makefile
# **************************************************************************
|
|
# * (C)opyright 2026 by Ruben Carlo Benante *
|
|
# * *
|
|
# * This program is free software; you can redistribute it and/or modify *
|
|
# * it under the terms of the GNU General Public License as published by *
|
|
# * the Free Software Foundation, either version 3 of the License, or *
|
|
# * (at your option) any later version. *
|
|
# * *
|
|
# * This program 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 *
|
|
# * GNU General Public License for more details. *
|
|
# * *
|
|
# * You should have received a copy of the GNU General Public License *
|
|
# * along with this program. If not, see http://www.gnu.org/licenses/. *
|
|
# * *
|
|
# * Contact author at: *
|
|
# * Ruben Carlo Benante *
|
|
# * rcb@beco.cc *
|
|
# **************************************************************************
|
|
|
|
# Makefile for logsdu - build the extension for Firefox and Chrome.
|
|
#
|
|
# Usage:
|
|
# make # everything: build and package both browsers
|
|
# make firefox # build Firefox only -> build/firefox/
|
|
# make chrome # build Chrome only -> build/chrome/
|
|
# make test # run the unit tests
|
|
# make smoke # check the background bundle works as a service worker
|
|
# make xpi # package Firefox -> dist/logsdu-<version>-firefox.xpi
|
|
# make crx # package Chrome -> dist/logsdu-<version>-chrome.zip
|
|
# make packages # both of the above (same as plain "make")
|
|
# make prune # drop packages left in dist/ by earlier versions
|
|
# make clean # remove build/, dist/ and stray packages
|
|
# make distclean # clean, plus node_modules/
|
|
#
|
|
# build/<target>/ holds the unpacked extension for one browser; the two targets
|
|
# never share a directory, so neither can be left stale by the other. dist/
|
|
# holds the packages meant to be published, and is kept out of build/ so that
|
|
# packaging never tries to include its own output.
|
|
#
|
|
# Dependencies are installed with pnpm, never npm:
|
|
# corepack pnpm install
|
|
#
|
|
# Load the unpacked build while developing:
|
|
# Firefox about:debugging -> This Firefox -> Load Temporary Add-on ->
|
|
# build/firefox/manifest.json (dropped when Firefox restarts)
|
|
# Chrome chrome://extensions -> Developer mode -> Load unpacked ->
|
|
# build/chrome/
|
|
#
|
|
# Publishing:
|
|
# Firefox upload dist/*-firefox.xpi at addons.mozilla.org
|
|
# Chrome upload dist/*-chrome.zip at chrome.google.com/webstore/devconsole
|
|
#
|
|
# Every package filename names its browser. The two are not interchangeable --
|
|
# they differ in the manifest's background key -- and uploading the wrong one
|
|
# fails in ways that are not obvious from the error.
|
|
|
|
EXT_ID := logsdu
|
|
VERSION := $(shell node -p "require('./package.json').version")
|
|
FIREFOX_DIR := build/firefox
|
|
CHROME_DIR := build/chrome
|
|
DIST := dist
|
|
XPI := $(DIST)/$(EXT_ID)-$(VERSION)-firefox.xpi
|
|
CRX := $(DIST)/$(EXT_ID)-$(VERSION)-chrome.zip
|
|
|
|
.PHONY: all firefox chrome typecheck test smoke prune xpi crx packages clean \
|
|
distclean check-deps
|
|
|
|
# The default does the lot: build both browsers and package both. Packaging is
|
|
# only a zip of a directory that was going to be built anyway, so making it the
|
|
# default costs nothing and means dist/ is never quietly out of date with src/.
|
|
all: packages
|
|
|
|
# Unit tests for the pure logic: the input formatters and the decision that
|
|
# says whether a page load may press "Entrar". Run straight through Node's
|
|
# built-in runner and type stripping, so there is no test framework to install.
|
|
test:
|
|
node --test "src/**/*.test.ts"
|
|
|
|
# Runs the built background bundle in a service-worker-shaped sandbox, which
|
|
# is where a Chrome-only breakage would otherwise hide until runtime. The
|
|
# bundle is identical for both targets, so checking one covers both.
|
|
smoke: chrome
|
|
node tools/sw-smoke.mjs $(CHROME_DIR)/background.js
|
|
|
|
# Typecheck once. Both build targets depend on it rather than each running tsc,
|
|
# which halves the work when building both.
|
|
#
|
|
# Calls the local toolchain directly, so this works regardless of how pnpm is
|
|
# provided (corepack vs standalone). Run "corepack pnpm install" first.
|
|
typecheck: check-deps
|
|
node_modules/.bin/tsc -noEmit -skipLibCheck
|
|
|
|
firefox: typecheck
|
|
node esbuild.config.mjs production
|
|
@echo "Firefox build: $(CURDIR)/$(FIREFOX_DIR)"
|
|
|
|
# The same sources with Chrome's manifest. Firefox and Chrome disagree on the
|
|
# background key and on the gecko block, so the manifest is generated per
|
|
# target rather than forked.
|
|
chrome: typecheck
|
|
TARGET=chrome node esbuild.config.mjs production
|
|
@echo
|
|
@echo "Chrome build: $(CURDIR)/$(CHROME_DIR)"
|
|
@echo "Load it with chrome://extensions -> Developer mode -> Load unpacked."
|
|
@echo "Select the folder itself; Chrome wants the directory holding manifest.json."
|
|
@echo
|
|
|
|
# Drop packages left over from earlier versions.
|
|
#
|
|
# Package names carry their version, so a bump does not overwrite the previous
|
|
# build -- without this, dist/ accumulates every version ever built and it
|
|
# becomes easy to upload the wrong file to a store. dist/ is regenerated
|
|
# output: keep signed downloads from AMO somewhere else, not here.
|
|
prune:
|
|
@mkdir -p $(DIST)
|
|
@find $(DIST) -maxdepth 1 -type f \( -name '$(EXT_ID)-*.xpi' -o -name '$(EXT_ID)-*.zip' \) \
|
|
! -name '$(notdir $(XPI))' ! -name '$(notdir $(CRX))' \
|
|
-print -delete | sed 's/^/removed stale package: /'
|
|
|
|
# An .xpi is just a zip of the extension directory, with the manifest at the
|
|
# top level rather than inside a wrapper folder.
|
|
xpi: firefox prune
|
|
rm -f $(XPI)
|
|
cd $(FIREFOX_DIR) && zip -qr $(CURDIR)/$(XPI) .
|
|
@echo
|
|
@echo "Built: $(CURDIR)/$(XPI)"
|
|
@echo
|
|
@echo "This file is UNSIGNED. Two ways to use it:"
|
|
@echo
|
|
@echo " Publish -- upload it at addons.mozilla.org/developers/addon/submit/"
|
|
@echo " Listed add-ons are signed once review approves them; unlisted"
|
|
@echo " ones are signed straight away."
|
|
@echo
|
|
@echo " Install locally -- only on ESR, Developer Edition or Nightly:"
|
|
@echo " 1. about:config -> xpinstall.signatures.required = false"
|
|
@echo " 2. about:addons -> gear icon -> Install Add-on From File"
|
|
@echo " 3. paste this path into the file picker:"
|
|
@echo " $(CURDIR)/$(XPI)"
|
|
@echo
|
|
|
|
# The Chrome Web Store takes a plain zip, and does the packing into .crx itself.
|
|
crx: chrome prune
|
|
rm -f $(CRX)
|
|
cd $(CHROME_DIR) && zip -qr $(CURDIR)/$(CRX) .
|
|
@echo
|
|
@echo "Built: $(CURDIR)/$(CRX)"
|
|
@echo "Upload it at chrome.google.com/webstore/devconsole"
|
|
@echo
|
|
|
|
# Both packages. Order no longer matters: each target has its own directory.
|
|
packages: xpi crx
|
|
|
|
# Removes everything the build produces, including packages from earlier
|
|
# versions, whose filenames carry their own version number and so are never
|
|
# overwritten by a later build. dist/ is tracked in git, so a clean shows the
|
|
# packages as deleted until the next "make packages" puts them back.
|
|
clean:
|
|
rm -rf build $(DIST)
|
|
rm -f $(EXT_ID)-*.xpi $(EXT_ID)-*.zip
|
|
find . -name '*.map' -not -path './node_modules/*' -delete
|
|
@echo "Removed build/, $(DIST)/ and any stray packages."
|
|
|
|
# Everything clean removes, plus the installed dependencies. Recover with
|
|
# "corepack pnpm install" -- never with npm, see the note in README.md.
|
|
distclean: clean
|
|
rm -rf node_modules
|
|
@echo "Removed node_modules/. Run: corepack pnpm install"
|
|
|
|
# Fail with a useful message rather than a confusing "tsc: not found".
|
|
check-deps:
|
|
@test -x node_modules/.bin/tsc || { \
|
|
echo "ERROR: dependencies are not installed."; \
|
|
echo "Run: corepack pnpm install (do NOT use npm install in this tree)"; \
|
|
exit 1; \
|
|
}
|