Skip to content
Snippets Groups Projects

walint: lint & adjust workadventure maps

walint is intended as a simple linter that will check workadventure maps for common errors, such as non-existent map entrypoints or missing asset files, and additionally suggest changes to improve accessability.

Optionally, it can also adjust maps — e.g. to automatically insert property values or help enforce an event's map policies — and then write them out again, copying all needed assets and minifying the map's json.

Usage

walint --config-file config.json --repository path \
      [--out path] [--json] [--pretty] [--entrypoint main.json]

Options

  • --repository: path to a map repository
  • --entrypoint: entrypoint of a map repository, i.e. a tiled map in its root directory. walint will lint all maps reachable from it. If not given, it defaults to main.json
  • --lintLevel: limit output only to messages that have at most the given level. Valid levels are Info, Suggestion, Warning, Forbidden, Error, Fatal. Defaults to Suggestion if not given.
  • --json: print output as json instead of the normal more human-friendly format
  • --pretty: if used with --json, insert line breaks and indentation to make the output more readable. Otherwise no effect.
  • --out path: write the linted & adjusted repository to the given path. Any json written to this path will be minimised, and only those maps and assets which are reachable from the entrypoint will be writen at all. If not given, walint will only run the linter and do nothing else. If walint encounters any references to local map assets which are not present in the repository, or if the map generates lints above the maximum lint level, it will instead exit with code 1 without touching the output path at all.
  • --config-file file: path to a configuation file. Required (for now).
  • --config json: takes a string which should contain a json object conforming to the same schema as the configuration file, except that all keys are optional. Keys given here will override whatever values are set in the configuration file.

Configuation

Take a look at config.json for an example. Most keys are required, and do not have default values. In config.json, all possible keys are given.

Most options should be reasonably self-explanatory. Note that MaxLintLevel differs from the option --lintLevel: the latter merely determines what is printed (in case json output is not enabled), the former determines the maximum lint level allowed before the linter rejects the map and does not copy it to the path given to --out.

Uri Schemas

walint supports (limited) rewriting of URIs contained in the map json via the UriSchemas option, which takes a map from uri schemas to a rule describing what to do with such links, depending on the scope in which they appear.

walint takes a very reductive view or URIs: schema://domain/tail

Rewrite Rules

For now there are three types of such rules:

  • schema: {"scope":[scopes]}: if in a scope listed in scopes, allow any links of the given schema
  • schema: {"scope":[scopes], "allowed":[allowed], "blocked":[blocked], "prefix":prefix}: if in a scope listed in scopes, prefix any URIs of the given schema with the given prefix, unless the URI's domain occurs in allowed (in which case leave it untouched), or it occurs in blocked, in which case it will be rejected as a lint error.
  • schema: {"scope":[scopes], "subst":{domain: prefix, ...}}: if in a scope listed in scopes and given a URI with the domain domain, concatenate prefix with the tail of this URI.

In case an URI is encountered and there is no applicable rule, it will be rejected (note that this means you'll have to explicitly allow https:// for links!)

For now there are two (useful) scopes: map applies to tiled map links (i.e. exitUrl), and website applies to weblinks (i.e. openWebsite).

Output

By default walint prints lints in a hopefully human-readable manner. Its exit code will be 1 if the maximum lint level set in its config was exceeded, and 0 otherwise. Only in the latter case will it write out an adjusted map respository to the path passed to --out.

If the --json option is given, output to stdout will be printed as json, which should conform to the following schema (here defined in a quasi-haskell syntax):

-- | The main type of walint's output
type Output = 
  { mapLints :: Map FilePath MapLint
  -- ^ an object of per-map lints. Each key is a filepath from the repository's root
  , missingAssets :: List Asset
  -- ^ a list of missing assets
  , missingDeps :: List Entrypoint
  -- ^ a list of other missing dependencies (for now, just entrypoints)
  }

-- | An object containing map lints
type MapLint =
  { general :: List Lint 
  -- ^ general lints (most often empty)
  , layer :: Map Message Where
  -- ^ an object of per-layer lints. Each key is a lint message
  , tileset :: Map Message Where
  -- ^ an object of per-tileset lints. Again, each key is a lint message
  }

-- | Further desription of a single lint
type Where =
  { in :: List String
  -- ^ where did this lint occur? (list of layers / tileset names)
  , level :: Level
  -- ^ what is this lint's level?
  }
  
-- | Valid lint levels. Encoded as strings, listed in order here.
data Level = Info | Suggestion | Warning | Forbidden | Error | Fatal


-- | description of a single (missing) asset
type Asset =
  { asset :: FilePath
  -- ^ the filename, as referenced somewhere within the repository
  , neededBy :: List FilePath
  -- ^ list of filenames of maps which reference this asset
  }

-- | description of a single (missing) entrypoint
type Entrypoint =
  { entrypoint :: String
  -- ^ the entrypoint, as a string, e.g. path/to/map#entrypoint
  , neededBy :: List FilePath 
  -- ^ list of filenames of maps which reference this entrypoint
  }