Fossil Forum

Mini-howto: mini download page
Login

Mini-howto: mini download page

Mini-howto: mini download page

(1) By Stephan Beal (stephan) on 2020-12-12 03:49:20 [source]

For the first time ever, in the context of a mini-project, i've found myself in need of (1) a programmatically-generated download page for use with fossil and (2) unversioned files. Using fossil's own download page as a starting point, i came up with a more basic-case variation which is fully static (doesn't load the file list vi ajax) and is trivial to build directly from a makefile without an intermediary script...

Summary:

  • Build a zip file using fossil zip, excluding anything which isn't interesting for end users.
  • Build a download.html which includes a link to /uv/the-zip-file.zip, its size, its virtual timestamp (that of the latest checkin), and its SHA3 hash.
  • Stuff them both into the unversioned space, explicitly giving them the timestamp of the latest checkin.
  • fossil uv sync

The relevant makefile code is:

########################################################################
# Zip file for distribution. This differs from the zip generated via
# the /zip page by removing stuff most users won't need.
dist.zip := dark-venture-card-tools.zip
dist.html := download.html
FDB := .fslckout
.PHONY: $(dist.zip) $(dist.html) $(FDB)
$(FDB):
	@test -f $@ || { echo "Missing fossil checkout db."; exit 1; }
$(dist.zip): $(FDB)
	fossil zip trunk --name dark-venture-card-tools -X "cgi-backend/*,.fossil-settings/*,*.in.css,*Makefile,*.make" $@
SQL_MTIME := select max(mtime) from event where type='ci'
$(dist.html): $(FDB)
	@{ \
	echo "<div class='fossil-doc' data-title='Downloads'>"; \
	echo "<style>#download-list{ line-height: 1.3; font-size: 120%; white-space: pre-wrap; }</style>"; \
	echo "<pre id='download-list'>"; \
	echo "<a href='$(dist.zip)'>$(dist.zip)</a>"; \
	echo "$$(stat --printf=%s $(dist.zip)) bytes"; \
	echo "Last updated (YYYY-MM-DD):" $$(echo "select strftime('%Y-%m-%d %H:%M',($(SQL_MTIME)))" | fossil sql | sed -e "s/'//g") UTC; \
	echo "SHA3-256 hash:" $$(fossil sha3sum $(dist.zip) | cut -d' ' -f1); \
	echo "</pre>"; \
	} > $@
	@echo "Created $@"
dist: $(dist.zip) $(dist.html)
	fossil uv add $(dist.zip) $(dist.html) --mtime $$(echo "$(SQL_MTIME)" | fossil sql)
	fossil uv list
dist-push: dist
	fossil uv sync --verbose

It's currently limited to a single zip file, as that's the extent of my modest needs, but it would be trivial to move into an external script which accepts multiple names or do add a foreach loop directly in the makefile.

The end result looks like:

https://fossil.wanderinghorse.net/r/darkventure/uv/download.html

If /uvlist used a full timestamp, rather than a relative time, i'd have just used that instead, but i'm not a big fan of relative timestamps, in particular for this download, where the name stays constant but the file will be updated from time to time.

(2) By sean (jungleboogie) on 2020-12-12 04:10:05 in reply to 1 [link] [source]

This is great! I wonder if Richard would consider using it for althttpd.

(3) By John Rouillard (rouilj) on 2020-12-12 18:17:49 in reply to 1 [link] [source]

You are adding some meta info (datestamp/hash) on the download page, but the main focus of this technique seems to be removing unneeded files from the generated zip.

A different way to do some of this is to use a wiki page for the download page. Set the fossil download page in /setup_config to:

  /wiki?name=Download
(which I assume you pointed to /uv/download.html).

Then on that page create the download links using:

## Most Recent Development Version

* [Zip of current development trunk](/zip/Roundup_sysadmin_tracker-devel.zip?uid=trunk&ex=.fossil-settings*,.hgignore)
* [Tar of current development trunk](/tarball/Roundup_sysadmin_tracker-devel.tgz?uid=trunk&ex=.fossil-settings*,.hgignore)

* sqlar downloads are available from the [builtin download page](/download)

Files/directories are excluded using the ex query argument. (The sqlar version will have the fossil settings and hgignore files obviously.)

Specific versions can be specified by replacing uid=trunk with the version hash. Changing the name of the file to match the release version is probably a good idea too.

Downsides of doing it this way:

  1. Downloads do use cpu cycles and incur a delay. This can be reduced using fossil cache.
  2. If you have other things in the zipfile (e.g. programs compiled from source etc.) this won't work. You could check the binaries into the repo though this is not a great idea.

(4.1) By Stephan Beal (stephan) on 2020-12-12 18:28:45 edited from 4.0 in reply to 3 [link] [source]

A different way to do some of this is to use a wiki page for the download page.

It's not an either/or, actually:

https://fossil.wanderinghorse.net/r/darkventure/wiki/download

that page has links to both the script-built "release" (/uv/download.html) and the full/current development copies (via /zip/...), but it's not anticipated that anyone will actually want the development files for this particular project (a tiny, tiny group of hobby tabletop gamers, few, if any, of whom would recognize a makefile if it bit them in the face).