Skip to content

loom bulk

Scaffold a bulk wrapper module from an existing module. The generated loom.jsonnet runs the module once per entry in an items list — the entry shape is derived from the module's declared parameters, so you only maintain the data.

loom bulk <module> [flags]

The module source may be a local path (./my-module) or a git URL (including the //subdir form) — the same forms accepted by loom run.

Flags

FlagDescription
-o, --output dirOutput directory for the generated wrapper (default: current directory)
-n, --name nameWrapper module name (default: bulk-<moduleName>)
--items file.yamlYAML file with a list of param sets to seed the items list
--name-param paramChild param whose value names each entry (default: item index)

Example

Given a module ./onboard-service declaring a required serviceName and a defaulted namespace:

bash
loom bulk ./onboard-service -o ./bulk-onboard

generates ./bulk-onboard/loom.jsonnet:

jsonnet
// Generated by loom bulk from ./onboard-service.
// One entry in `items` = one execution of the child module.
local items = [
  {
    serviceName: 'CHANGEME',  // required
    namespace: 'default',
  },
];

{
  apiVersion: 'loom.rickliujh.github.io/v1beta1',
  kind: 'Loom',
  metadata: { name: 'bulk-onboard-service' },
  spec: {
    modules: [
      {
        name: 'onboard-service' + '-' + std.toString(i),
        source: '../onboard-service',
        params: items[i],
      }
      for i in std.range(0, std.length(items) - 1)
    ],
  },
}

Edit the items list (one object per run), then execute the batch:

bash
loom diff ./bulk-onboard              # preview
loom run ./bulk-onboard               # run all items in order

Seeding items from a file

Skip the CHANGEME placeholder by providing the list up front:

yaml
# items.yaml
- serviceName: payments
  namespace: fintech
- serviceName: billing
  namespace: fintech
- serviceName: auth
  namespace: platform
bash
loom bulk ./onboard-service -o ./bulk-onboard --items items.yaml --name-param serviceName

--name-param serviceName names each child entry after its service (onboard-service-payments, …) instead of an index, which makes run logs and --local-run directories identifiable.

Items are validated against the module's declared params before anything is written: undeclared keys and missing required params fail immediately, mirroring what loom run would reject later.

Behavior notes

  • Never overwrites: if the output directory already contains a loom.yaml or loom.jsonnet, the command fails.
  • Self-verifying: the generated wrapper is loaded back through the standard Jsonnet loader and validator before the command reports success.
  • Placeholder values: required params become 'CHANGEME' (annotated), defaulted params carry their default, dynamic params are omitted (they resolve inside the child at run time).
  • PR topology: if the child module declares its own spec.target, every item produces its own branch and PR; the generated file carries a note explaining how to restructure for a single batch PR. loom bulk never modifies the child module. See Bulk Runs.

Released under the GPL-3.0 License.