Macro Reference
Description: A simple macro processor is added to the header processing. Variables allow a single definition of a value, and the use of derivations. Each header is a macro that can be expanded. Notice that headers that do not start with an upper case character will not be copied to the manifest, so they can be used as working variables. Variables are expanded by enclosing the name of the variable in ${<name>} (curly braces) or $(<name>) (parenthesis). Additionally, square brackets [], angled brackets <>, double guillemets «», and single guillemets ‹› are also allowed for brackets. If brackets are nested, that is $[replace;acaca;a(.*)a;[$1]] will return [cac].
Date: 2019-10-12T20:27:56-04:00

- Supported by OSGi enRoute

- # Macro Reference

  A simple macro processor is added to the header processing. Variables allow a single definition of a value, and the use of derivations. Each header is a macro that can be expanded. Notice that headers that do not start with an upper case character will not be copied to the manifest, so they can be used as working variables. Variables are expanded by enclosing the name of the variable in `${<name>}` (curly braces) or `$(<name>)` (parenthesis). Additionally, square brackets [], angled brackets <>, double guillemets «», and single guillemets ‹› are also allowed for brackets. If brackets are nested, that is $[replace;acaca;a(.*)a;[$1]] will return `[cac]`.

  There are also a number of macros that perform basic functions. All these functions have the following basic syntax:

       macro ::= '${' function '}'
           | '$\[' function '\]'
           | '$(' function ')'
           | '$<' function '>'

       function ::= name ( ';' argument ) *

  For example:

      version=1.23.87.200109111023542
      Bundle-Version= ${version}
      Bundle-Description= This bundle has version ${version}

  ## Macro patterns

  The default macro pattern is the `${...}` pattern, a dollar sign (‘$’) followed by a left curly bracket (‘{‘) and closed by a right curly bracket (‘}’). However, since bndlib is often used inside other systems it also supports alternative macro patterns:

  - `$(...)`,
  - `$<...>`,
  - `$[...]`,
  - `$«..»` (pointing double angle quotation mark \u00AB abd \u00BB), and
  - `$‹...›` (single pointing angle quotation mark)

  ## Arguments

  @Since(“2.3”) Macros can contain arguments. These arguments are available in the expansion as ${0} to ${9}. ${0} is the name of the macro, so the actual arguments start at 1. The name is also available as ${@}. The arguments as an array (without the name of the macro) is available as ${#}. The more traditional * could not be used because it clashes with wildcard keys, it means ALL values.

  For example:

      foo: Hello ${1} -> ${foo;Peter} -> "Hello Peter"

  ## Wildcarded Keys

  Keys can be wildcarded. For example, if you want to set -plugin from different places, then you can set the `plugin.xxx` properties in different places and combine them with `-plugins= ${plugins.*}`.

  ## Expansion of ./

  The `./` sequence is automatically expanded to the current filename when found in a macro source file. This generally what you want but unfortunately not always. The `./` prefix is only replaced when:

  - It is at the start of the expansion, or
  - Preceded by a whitespace.

  So, do you really require the `./` without expansion? If so, then there are the following solutions. The first one is to use another macro to break the sequence:

      .=.
      Some-Header: ${.}/conf/admin.xml

  Alternatively there are a couple of macros that return the given value when called appropriately, and thereby break the sequence:

      Some-Header-1: ${def;.;.}/conf/jetty/admin.xml
      Some-Header-2: ${uniq;.}/conf/jetty/admin.xml
      Some-Header-3: ${unescape;.}/conf/jetty/admin.xml

  ## Booleans

  In many places a header is used to indicate false or true. In those cases we use some heuristics. The header/macro or whatever is false when:

  - not set
  - empty string
  - ‘false’
  - ’!’
  - ‘off’
  - ‘not’

  If the value starts with `!` and text follows, the `!` is removed and the remaining text is interpreted as a boolean and then negated.

  In other cases, the value is considered `true`.

  ## Types

  @TODO

  ## Reference

  apply ';' MACRO (';' LIST)*
    Convert a list to an invoction with arguments
  average (';' LIST )*
    The average of a list, if no members exception is thrown
  basedir
    Get the basedirectory of this processor
  basename ( ';' FILEPATH ) +
    A list of the basename (the final part) of a set of file paths.
  bsn
    Provide the current bsn when a JAR is generated. This can differ from the Project's bsn when there are sub-bundles.
  cat ';' FILEPATH
    The contents of a file
  classes TODO
    A list of class names filtered by a query language
  compare NUMBER NUMBER
    Compare two numbers. 0 is equal, 1 means a > b, -1 is a < b.
  currenttime
    The current epoch time in long integer format
  def ';' KEY (';' STRING)?
    The value of the specified property name or a default if macro is not defined. The default is an empty string if not specified.
  driver ( ';' NAME )?
    the driver of the environment (e.g. gradle, eclipse, intellij)
  ee
    The name of the highest execution environment found in the current JAR
  endswith ';' STRING ';' SUFFIX
    Check if the given string ends with the given prefix
  env ';' KEY (';' STRING)?
    The given environment variable or a default if the environment variable is not defined. The default is an empty string if not specified.
  error ( ';' STRING )*
    Raise an error consisting of all concatenated strings
  exporters ';' PACKAGE
    The list of jars that export the given package
  exports
    A list if exported packages
  extension STRING
    The extension of the given string (the part after the '.') or empty
  fileuri ';' PATH
    Return a file uri for the specified path. Relative paths are resolved against the processor base.
  filter ';' LIST ';' REGEX
    Filters entries in a list that matching a regular expression
  filter ';' LIST ';' REGEX
    Filters entries in a list that matching a regular expression
  find ';' VALUE ';' SEARCHED
    The starting position ofof SEARCHED (not a regex) in VALUE
  findfile ';' PATH ( ';' FILTER )
    A filtered list of relative paths from a directory and its subdirectories
  find ';' VALUE ';' SEARCHED
    The starting position of SEARCHED (not a regex) in VALUE when searching from the end
  findname ';' PATH ( ';' FILTER )
    A list of filtered by name resource paths with optional replacement
  findpath ';' REGEX ( ';' REPLACE )?
    A list of filtered by path resource paths with optional replacement
  first (';' LIST )*
    First element of a list
  fmodified ( ';' RESOURCE )+
    Latest modification date of a list of resources
  foreach ';' MACRO (';' LIST)*
    Iterator over a list, calling a macro with the value and index
  format ';' STRING (';' ANY )*
    Print a formatted string, automatically converting variables to the specified format if possible.
  frange ';' VERSION ( ';' BOOLEAN )?
    a range expression for a filter from a version. By default this is based on consumer compatibility. You can specify a third argument (true) to get provider compatibility.
  gestalt ';' NAME ( ';' NAME (';' ANY )? )?
    provides access to the gestalt properties that describe the environment.
  get ';' INDEX (';' LIST )*
    The element from the concatenated lists at the given index
  githead
    Get the head commit number. Look for a .git/HEAD file, going up in the file hierarchy. Then get this file, and resolve any symbolic reference.
  if ';' STRING ';' STRING ( ';' STRING )?
    Conditional macro that depending on a condition returns either a value for true or optionally for false.
  imports
    A list of the currently imported package names
  indexof ';' STRING (';' LIST )*
    The index of the given string in the list, or -1 if not found
  is ( ';' ANY )*
    Check if the given values are all equal
  isdir ( ';' FILE )+
    True if all given files are directories, false if no file arguments
  isempty ( ';' STRING )*
    True if all given strings are empty
  isfile (';' FILE )+
    Returns true if all given files actually exist and are not a directory or special file.
  isnumber ( ';' STRING )*
    Check if the given strings are numbers
  join ( ';' LIST )+
    Join a number of list/values into a single list
  js (';' JAVASCRIPT )*
    Execute Javascript, return the value of the last expression
  last (';' LIST )*
    Last element of a list
  find ';' VALUE ';' SEARCHED
    The starting position ofof SEARCHED (not a regex) in VALUE
  lastindexof ';' STRING (';' LIST )*
    The last index of the given string in the list, or -1 if not found
  length STRING
    The length of the given string
  literal ';' STRING
    A literal value for the macro, i.e. it surrounds the value with the macro prefix and suffix.
  long2date
    Turn a long time into a date
  lsa ';' DIR (';' INSTRUCTION )
    A list of absolute file paths from the given directory optionally filtered by a set of instructions.
  lsr ';' DIR (';' INSTRUCTION )
    A list of relative file paths from the given directory optionally filtered by a set of instructions.
  map ';' MACRO (';' LIST)*
    Map a list to a new list using a function
  matches STRING REGEX
    Check if the given string matches the regular expression
  maven_version ';' MAVEN-VERSION
    Cleanup a potential maven version to make it match an OSGi Version syntax.
  max (';' LIST )*
    Maximum (string compared) element of a list
  md5 ';' RESOURCE
    The MD5 digest of an existing resource in the JAR
  min (';' LIST )*
    Minimum (string compared) element of a list
  native_capability ( ';' ( 'os.name' | 'os.version' | 'os.processor' ) '=' STRING )*
    Create a Require-Capability header based on the current platform or explicit values
  compare STRING STRING
    Compare two strings. 0 is equal, 1 means a > b, -1 is a < b.
  nmax (';' LIST )*
    Maximum (numerically compared) element of a list
  nmin (';' LIST )*
    Minimum (numerically compared) element of a list
  now ( 'long' | DATEFORMAT )
    Current date and time, default is default Date format. The format can be specified as a long or a date format.
  nsort (';' LIST )+
    Concatenate a set of lists and sort their contents nummerically
  osfile ';' DIR ';' NAME
    Create a path to a file in OS dependent form.
  p_allsourcepath
    Path to all sources
  p_bootclasspath
    The project's boot class path
  p_buildpath
    The project's buildpath
  p_dependson
    Provides a list of project names this project depends on
  p_output
    The absolute path to the project's output/target directory
  p_sourcepath
    The path to the project's source directory.
  p_testpath
    The path of JARs placed on the remote VM's classpath for testing
  packageattribute ';' PACKAGE (';' ATTRIBUTE)?
    The value of a package attribute
  packages
    A list of package names filtered by a query language
  path ( ';' FILES )+
    A list of file paths separated by the platform's path separator.
  pathseparator
    The platform's path separator
  permissions (';' ( 'packages' | 'admin' | 'permissions' ) )+
    A file in the format for the OSGi permissions resource.
  rand (';' MIN ' (;' MAX )?)?
    A random number between 0 and 100, or between the given range (inclusive).
  random
    Generate a random string, which is guaranteed to be a valid Java identifier
  range ';' RANGE_MASK ( ';' VERSION )
    Create a semantic version range out of a version using a mask to control the bump of the ceiling
  reject ';' LIST ';' REGEX
    Rejects a list by matching it against a regular expression
  replace ';' LIST ';' REGEX (';' STRING (';' STRING)? )?
    Replace elements in a list when it matches a regular expression
  repodigests ( ';' NAME )*
    Get the repository digests (describing their contents) for all or the specified names
  repos
    A list of the current repositories
  reverse (';' LIST )*
    A reversed list
  select ';' LIST ';' REGEX
    Selects entries in a list that matching a regular expression
  separator
    The platform file separator
  sha1 ';' RESOURCE
    The SHA-1 digest of an existing resource in the JAR
  size ( ';' LIST )*
    Count the number of elements (of all collections combined)
  sjoin ';' SEPARATOR ( ';' LIST )+
    Join a number of list/values into a single list with a given separator
  sort (';' LIST )+
    Concatenate a set of lists and sort their contents on their string value
  split ';' REGEX (';' STRING )*
    Split a number of strings int a list using a regular expression
  startswith ';' STRING ';' PREFIX
    Check if the given string starts with the given prefix
  sublist ';' START ';' END (';' LIST )*
    Return a sublist of the list
  subst ';' STRING ';' REGEX (';' STRING (';' NUMBER )? )?
    Substitute all the regex matches in the target for the given value; if a count is specified, limit the number of replacements to that count.
  substring ';' STRING ';' START ( ';' END )?
    Return a substring of a given string, negative indexes allowed
  sum (';' LIST )*
    The sum of a list
  system ';' STRING ( ';' STRING )?
    Execute a system command
  system_allow_fail ';' STRING ( ';' STRING )?
    Execute a system command but ignore any failures
  toclasspath ';' LIST ( ';' BOOLEAN )?
    Convert a list of class names to a list of paths.
  toclassname ';' FILES
    Translate a list of relative file paths to class names. The files can either end with .class or .java
  tolower STRING
    Turn a string into an lower case string
  toupper STRING
    Turn a string into an uppercase string
  trim ';' STRING
    Remove whitespace around the given string
  tstamp ( ';' DATEFORMAT ( ';' TIMEZONE ( ';' LONG )? )? )?
    Create a timestamp based on a date format. Default format is "yyyyMMddHHmm"
  unescape ( ';' STRING )*
    The concatenated input will have all \n, \r, \b, \f, and \t replaced with their control code.
  uniq (';' LIST )*
    Concatenate the lists and then remove any duplicates.
  uri ';' URI (';' URI)?
    Resolve a uri against a base uri.
  user ';' KEY ( ';' DEFAULT )?
    A current user setting from the ~/.bnd/settings.json file
  version MASK VERSION?
    Modify a version using a template. This is an alias to the versionmask macro.
  versionmask MASK VERSION?
    Modify a version using a template
  warning ( ';' STRING )*
    Raise an error consisting of all concatenated strings
  workspace
    The absolute file path to the current workspace