add mapforge: web-based GIS vector editor
Ruby on Rails 8.1 app backed by MongoDB and Redis. Git snapshot from 2026-03-22 (no upstream releases yet). Requires Ruby 4.0, libproj (rgeo-proj4 C ext), and ImageMagick (rszr C ext).
This commit is contained in:
parent
373f4c3824
commit
a05011396f
105
geo/mapforge/CLAUDE.md
Normal file
105
geo/mapforge/CLAUDE.md
Normal file
@ -0,0 +1,105 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## What this port is
|
||||
|
||||
An OpenBSD port for [mapforge](https://github.com/mapforge-org/mapforge), a self-hosted web GIS application. It is a Ruby on Rails 8.1 app backed by MongoDB and Redis, with MapLibre GL JS on the frontend.
|
||||
|
||||
- No upstream releases — the port tracks a git snapshot (`GIT_COMMIT` + `SNAP` in Makefile)
|
||||
- To update to a newer commit: change `GIT_COMMIT` and `SNAP`, then run `doas make makesum`
|
||||
|
||||
## Build commands
|
||||
|
||||
```sh
|
||||
doas make fetch # download source tarball from GitHub
|
||||
doas make patch # extract and apply patches
|
||||
doas make build # bundle install + bootsnap precompile
|
||||
doas make fake # stage into WRKINST
|
||||
doas make package # create the .tgz package
|
||||
doas make install # install from package
|
||||
doas make clean=all # full clean (use instead of make clean)
|
||||
```
|
||||
|
||||
Run from `/usr/ports/mystuff/geo/mapforge/`.
|
||||
|
||||
## Gem dependency handling
|
||||
|
||||
This port has no cargo-style bundler module in OpenBSD ports infrastructure. Two approaches:
|
||||
|
||||
**Development (network access):** `do-build` calls `bundle install` which fetches gems from rubygems.org and git. Requires network access during the build phase — acceptable for local development.
|
||||
|
||||
**Proper offline build:** Pre-generate a vendor cache and add it as a distfile:
|
||||
|
||||
```sh
|
||||
# After make extract, in WRKDIST:
|
||||
bundle _4.0.3_ config set --local without "development test"
|
||||
bundle _4.0.3_ package --all --all-platforms --no-install
|
||||
tar czf ${DISTDIR}/mapforge-gems-20260322.tar.gz vendor/cache/
|
||||
```
|
||||
|
||||
Then add `DISTFILES += mapforge-gems-${SNAP}.tar.gz` to the Makefile, extract it in `post-extract` into `${WRKSRC}/vendor/cache/`, and use `bundle install --local` in `do-build`.
|
||||
|
||||
Two Gemfile entries use git sources (not rubygems.org):
|
||||
- `gpx` from `https://github.com/digitaltom/gpx` (Ruby 4.0 fork)
|
||||
- `net-pop` from `https://github.com/ruby/net-pop`
|
||||
|
||||
These will be fetched by bundler during build. For a fully offline build, vendor them too via `bundle package --all`.
|
||||
|
||||
## Ruby version
|
||||
|
||||
Tied to Ruby 4.0 (`MODRUBY_REV = 4.0`). The Gemfile enforces `ruby "4.0.0"` and the Gemfile.lock was generated with bundler 4.0.3 (built into Ruby 4.0).
|
||||
|
||||
Relevant paths once ruby40 is installed:
|
||||
- `${LOCALBASE}/bin/ruby40`
|
||||
- `${LOCALBASE}/bin/bundle40`
|
||||
- `${LOCALBASE}/bin/gem40`
|
||||
|
||||
## C extension gems
|
||||
|
||||
Three gems compile native extensions at `bundle install` time:
|
||||
- **rgeo** — geospatial types; optionally links against GEOS (not required)
|
||||
- **rgeo-proj4** — coordinate projections; links against `libproj` (`devel/proj`)
|
||||
- **rszr** — image resizing; links against `MagickCore-6.Q16`, `MagickWand-6.Q16` (`graphics/ImageMagick`)
|
||||
|
||||
This makes the package architecture-dependent (no `PKG_ARCH=*`).
|
||||
|
||||
## Runtime services
|
||||
|
||||
The app needs these running before starting:
|
||||
- `mongod` from `databases/mongodb/80`
|
||||
- `redis-server` from `databases/redis`
|
||||
|
||||
Start with `rcctl start mongod redis mapforge`.
|
||||
|
||||
## Installation layout
|
||||
|
||||
| Path | Contents |
|
||||
|---|---|
|
||||
| `${PREFIX}/share/mapforge/` | Application code + vendored gems |
|
||||
| `${LOCALSTATEDIR}/mapforge/log/` | Rails logs |
|
||||
| `${LOCALSTATEDIR}/mapforge/storage/` | Active Storage uploads |
|
||||
| `${LOCALSTATEDIR}/mapforge/tmp/` | Pids, sockets, cache |
|
||||
| `${PREFIX}/share/examples/mapforge/mapforge.rc` | rc.d startup script template |
|
||||
|
||||
Copy `mapforge.rc` to `/etc/rc.d/mapforge` and enable with `rcctl enable mapforge`.
|
||||
|
||||
## Environment variables
|
||||
|
||||
Required in production:
|
||||
- `SECRET_KEY_BASE` — Rails secret (generate with `bundle exec rails secret`)
|
||||
- `RAILS_ENV=production`
|
||||
|
||||
Optional OAuth login:
|
||||
- `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET`
|
||||
- `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET`
|
||||
- `OSM_CLIENT_ID` / `OSM_CLIENT_SECRET`
|
||||
|
||||
## PLIST
|
||||
|
||||
The PLIST placeholder needs to be replaced after a successful build:
|
||||
|
||||
```sh
|
||||
doas make fake
|
||||
doas make update-plist
|
||||
```
|
||||
78
geo/mapforge/Makefile
Normal file
78
geo/mapforge/Makefile
Normal file
@ -0,0 +1,78 @@
|
||||
COMMENT = open source web-based GIS vector editor
|
||||
|
||||
# No upstream releases; pin to a git snapshot
|
||||
GIT_COMMIT = 0c0e1387da1910a2a3b60c6d7c48d0552c701a3c
|
||||
SNAP = 20260322
|
||||
PKGNAME = mapforge-0.${SNAP}
|
||||
|
||||
DIST_TUPLE = github mapforge-org mapforge ${GIT_COMMIT} .
|
||||
|
||||
CATEGORIES = geo www
|
||||
|
||||
HOMEPAGE = https://github.com/mapforge-org/mapforge
|
||||
|
||||
# AGPLv3 (source), MPL-2.0 (vendor/javascript)
|
||||
PERMIT_PACKAGE = Yes
|
||||
|
||||
MODULES = lang/ruby
|
||||
MODRUBY_REV = 4.0
|
||||
MODRUBY_HANDLE_FLAVORS = No
|
||||
|
||||
BUNDLE = ${LOCALBASE}/bin/bundle${MODRUBY_BINREV}
|
||||
|
||||
CONFIGURE_STYLE = none
|
||||
NO_TEST = Yes
|
||||
|
||||
# C extensions (rgeo, rgeo-proj4, rszr) make the package arch-dependent
|
||||
COMPILER = base-clang ports-gcc
|
||||
COMPILER_LANGS = c
|
||||
|
||||
# git-sourced gems in Gemfile require git at bundle-install time
|
||||
BUILD_DEPENDS += devel/git
|
||||
|
||||
# rgeo-proj4 C extension links against libproj
|
||||
LIB_DEPENDS += devel/proj
|
||||
# rszr C extension links against ImageMagick
|
||||
LIB_DEPENDS += graphics/ImageMagick
|
||||
|
||||
WANTLIB += proj MagickCore-6.Q16 MagickWand-6.Q16
|
||||
|
||||
# mongod and redis servers are needed at runtime
|
||||
RUN_DEPENDS += databases/mongodb/80 \
|
||||
databases/redis
|
||||
|
||||
APP_DIR = ${PREFIX}/share/mapforge
|
||||
DATA_DIR = ${LOCALSTATEDIR}/mapforge
|
||||
|
||||
SUBST_VARS += APP_DIR DATA_DIR MODRUBY_BINREV
|
||||
|
||||
# --- Gem vendor cache ---
|
||||
# The gem vendor cache must be pre-generated and added as a distfile
|
||||
# before this port can build offline. Steps after "make extract":
|
||||
#
|
||||
# cd ${WRKDIST}
|
||||
# bundle _4.0.3_ config set --local without "development test"
|
||||
# bundle _4.0.3_ package --all --all-platforms --no-install
|
||||
# tar czf ${DISTDIR}/mapforge-gems-${SNAP}.tar.gz vendor/cache/
|
||||
#
|
||||
# Then add to DISTFILES and re-run "make makesum". Until the cache
|
||||
# is generated, bundle install will fetch gems from rubygems.org.
|
||||
|
||||
do-build:
|
||||
cd ${WRKSRC} && \
|
||||
${BUNDLE} config set --local without "development test" && \
|
||||
${BUNDLE} config set --local deployment true && \
|
||||
${BUNDLE} install && \
|
||||
${RUBY} ./bin/bootsnap precompile --gemfile app/ lib/
|
||||
|
||||
do-install:
|
||||
${INSTALL_DATA_DIR} ${WRKINST}${APP_DIR}
|
||||
cd ${WRKSRC} && pax -rw . ${WRKINST}${APP_DIR}/
|
||||
${INSTALL_DATA_DIR} ${WRKINST}${DATA_DIR}/log
|
||||
${INSTALL_DATA_DIR} ${WRKINST}${DATA_DIR}/storage
|
||||
${INSTALL_DATA_DIR} ${WRKINST}${DATA_DIR}/tmp
|
||||
${INSTALL_DATA_DIR} ${WRKINST}${PREFIX}/share/examples/mapforge
|
||||
${INSTALL_SCRIPT} ${FILESDIR}/mapforge.rc \
|
||||
${WRKINST}${PREFIX}/share/examples/mapforge/
|
||||
|
||||
.include <bsd.port.mk>
|
||||
2
geo/mapforge/distinfo
Normal file
2
geo/mapforge/distinfo
Normal file
@ -0,0 +1,2 @@
|
||||
SHA256 (mapforge-org-mapforge-0c0e1387da1910a2a3b60c6d7c48d0552c701a3c.tar.gz) = O8aIwFOQBQH7Q/TcjeEreD4GYqcSMreXQKTmsXphWCc=
|
||||
SIZE (mapforge-org-mapforge-0c0e1387da1910a2a3b60c6d7c48d0552c701a3c.tar.gz) = 50532678
|
||||
21
geo/mapforge/files/mapforge.rc
Normal file
21
geo/mapforge/files/mapforge.rc
Normal file
@ -0,0 +1,21 @@
|
||||
#!/bin/ksh
|
||||
|
||||
daemon="${TRUEPREFIX}/share/mapforge/bin/thrust"
|
||||
daemon_user="_mapforge"
|
||||
daemon_flags=""
|
||||
|
||||
pexp="ruby${MODRUBY_BINREV}.*puma"
|
||||
|
||||
. /etc/rc.d/rc.subr
|
||||
|
||||
rc_bg=YES
|
||||
rc_reload=NO
|
||||
|
||||
rc_pre() {
|
||||
export RAILS_ENV=production
|
||||
export RAILS_LOG_TO_STDOUT=true
|
||||
export BUNDLE_PATH="${TRUEPREFIX}/share/mapforge/vendor/bundle"
|
||||
cd "${TRUEPREFIX}/share/mapforge" || exit 1
|
||||
}
|
||||
|
||||
rc_cmd $1
|
||||
9
geo/mapforge/pkg/DESCR
Normal file
9
geo/mapforge/pkg/DESCR
Normal file
@ -0,0 +1,9 @@
|
||||
Mapforge is a self-hosted web-based GIS application for creating and sharing
|
||||
geospatial data collaboratively. Users can draw shapes, import GeoJSON/GPX/KML
|
||||
files, query OpenStreetMap via the Overpass API, and edit maps together in
|
||||
real time using WebSockets.
|
||||
|
||||
The frontend uses MapLibre GL JS with Stimulus/Hotwire. The backend is a Ruby
|
||||
on Rails application using MongoDB for storage and Redis for caching and
|
||||
real-time synchronisation. Optionally supports GitHub, Google, and
|
||||
OpenStreetMap OAuth2 login.
|
||||
6
geo/mapforge/pkg/PLIST
Normal file
6
geo/mapforge/pkg/PLIST
Normal file
@ -0,0 +1,6 @@
|
||||
@comment TODO: run "make update-plist" after a successful build to generate this file
|
||||
@dir ${APP_DIR}
|
||||
@dir ${DATA_DIR}/log
|
||||
@dir ${DATA_DIR}/storage
|
||||
@dir ${DATA_DIR}/tmp
|
||||
share/examples/mapforge/mapforge.rc
|
||||
Loading…
x
Reference in New Issue
Block a user