@florianpat/lando-core 3.26.3-1florianPat.9 → 3.26.5-1florianPat.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/AGENTS.md +40 -0
  2. package/CHANGELOG.md +11 -1
  3. package/app.js +23 -3
  4. package/builders/lando-compose.js +51 -0
  5. package/components/docker-engine.js +1 -0
  6. package/components/l337-v4.js +2 -2
  7. package/config.yml +6 -6
  8. package/hooks/app-add-2-landonet.js +1 -2
  9. package/hooks/app-add-proxy-2-landonet.js +1 -2
  10. package/hooks/app-add-v3-services.js +7 -7
  11. package/hooks/app-generate-v3-certs.js +2 -0
  12. package/hooks/app-purge-proxy-certs-and-config.js +24 -0
  13. package/hooks/app-start-proxy.js +3 -4
  14. package/hooks/lando-clean-networks.js +5 -1
  15. package/hooks/lando-setup-buildx.js +91 -0
  16. package/hooks/lando-setup-orchestrator.js +2 -2
  17. package/index.js +3 -0
  18. package/jsconfig.json +33 -0
  19. package/lib/app.js +13 -6
  20. package/lib/cli.js +1 -1
  21. package/lib/compose.js +2 -1
  22. package/lib/daemon.js +1 -1
  23. package/lib/lando.js +2 -2
  24. package/netlify.toml +4 -1
  25. package/node_modules/lodash/README.md +2 -2
  26. package/node_modules/lodash/_baseUnset.js +47 -2
  27. package/node_modules/lodash/core.js +1 -1
  28. package/node_modules/lodash/core.min.js +1 -1
  29. package/node_modules/lodash/lodash.js +43 -4
  30. package/node_modules/lodash/lodash.min.js +57 -57
  31. package/node_modules/lodash/package.json +1 -1
  32. package/node_modules/undici/README.md +7 -1
  33. package/node_modules/undici/docs/docs/api/ProxyAgent.md +3 -2
  34. package/node_modules/undici/index-fetch.js +3 -0
  35. package/node_modules/undici/lib/core/errors.js +162 -0
  36. package/node_modules/undici/lib/dispatcher/proxy-agent.js +83 -1
  37. package/node_modules/undici/lib/mock/mock-errors.js +11 -0
  38. package/node_modules/undici/lib/web/fetch/body.js +0 -4
  39. package/node_modules/undici/lib/web/fetch/index.js +16 -10
  40. package/node_modules/undici/lib/web/fetch/response.js +5 -0
  41. package/node_modules/undici/package.json +1 -1
  42. package/node_modules/undici/types/proxy-agent.d.ts +1 -0
  43. package/package.json +12 -8
  44. package/release-aliases/3-EDGE +1 -1
  45. package/release-aliases/3-STABLE +1 -1
  46. package/scripts/install-docker-engine.sh +1 -1
  47. package/scripts/lando-entrypoint.sh +8 -7
  48. package/scripts/load-keys.sh +5 -4
  49. package/scripts/user-perm-helpers.sh +64 -44
  50. package/scripts/user-perms.sh +34 -29
  51. package/tasks/exec.js +0 -1
  52. package/tasks/setup.js +6 -0
  53. package/utils/get-compose-x.js +1 -1
  54. package/utils/get-config-defaults.js +2 -1
  55. package/utils/load-compose-files.js +52 -5
  56. package/utils/load-config-files.js +1 -1
  57. package/builders/_lando-compose.js +0 -11
  58. package/node_modules/lodash/flake.lock +0 -40
  59. package/node_modules/lodash/flake.nix +0 -20
  60. package/node_modules/lodash/release.md +0 -48
  61. package/utils/parse-compose-services.js +0 -31
package/AGENTS.md ADDED
@@ -0,0 +1,40 @@
1
+ # AGENTS.md
2
+
3
+ Lando is a local development orchestration tool built around Docker, recipes, and plugin-driven automation for app environments and developer tooling. Lando Core (`@lando/core`) is the event-driven Node.js runtime and plugin base behind the `lando` CLI: it bootstraps config, tasks, engine integration, app loading, and built-in plugin behavior.
4
+
5
+ ## Maintenance
6
+ - Keep this file up to date. If you identify a serious repo-specific gotcha that is likely to trip future agents, update this file in the same change.
7
+
8
+ ## Commands
9
+ - Use `npm`. Node 20 required.
10
+ - Full verification: `npm test`. Focused unit test: `npx mocha --timeout 5000 test/<file>.spec.js`.
11
+ - Integration tests: `npm run test:leia`. **Do not run locally** — they modify the host system and are CI-only.
12
+ - The `.lando.yml` at the project root is solely for docs work (VitePress); it has no relation to app code.
13
+
14
+ ## Architecture
15
+ - `bin/lando` — CLI entrypoint/runtime selector.
16
+ - `lib/lando.js` — package main export; owns bootstrap sequencing.
17
+ - `index.js` — **not** the library entrypoint; it's the core plugin bootstrap that registers default config and lifecycle hooks.
18
+ - Most behavior is wired through events and hook modules, not direct imports. Start with `lib/lando.js`, `app.js`, and `index.js`, then follow `hooks/`.
19
+ - Bootstrap levels: `config → tasks → engine → app`. Tooling commands may only reach `engine` if compose cache exists, so not every CLI path initializes a full app.
20
+
21
+ ## Config And Caches
22
+ - Landofile loading order (from the app root directory): `.lando.base.yml`, `.lando.dist.yml`, `.lando.recipe.yml`, `.lando.upstream.yml`, `.lando.yml`, `.lando.local.yml`, `.lando.user.yml`.
23
+ - CLI relies heavily on task cache and compose cache to decide bootstrap level and available commands.
24
+ - If a command change seems ignored, clear caches with `lando --clear` before assuming the code path is wrong.
25
+
26
+ ## Writing
27
+ - Keep commit messages, PR descriptions, and issue comments concise.
28
+ - User-facing changes only in `CHANGELOG.md`'s `## {{ UNRELEASED_VERSION }}` section; follow the existing bullet and verb style.
29
+
30
+ ## Repo-Specific Gotchas
31
+ - **Packaged binary**: adding runtime-loaded files or new top-level directories requires updating `pkg.assets` and `pkg.scripts` in `package.json`, or they'll be missing from the packaged CLI.
32
+ - **New source directories** must be added to `jsconfig.json` `include`, `package.json` `nyc.include`, and `package.json` `pkg.scripts`.
33
+ - **ESLint**: `require-jsdoc` applies to `FunctionDeclaration` only — arrow functions and expressions do not need JSDoc to pass lint.
34
+ - **`examples/**/README.md`** files are executable Leia specs — edits there affect CI test behavior.
35
+
36
+ ## TypeScript Migration
37
+ - We are incrementally migrating to TypeScript via JSDoc type definitions. Add `@param`, `@return`, `@typedef` to any functions you modify or create.
38
+ - Type definitions go in co-located `.types.js` files (e.g., `utils/foo.types.js` next to `utils/foo.js`).
39
+ - `npm run typecheck` is not gated in CI. Use `npm run typecheck:full` to include node_modules errors.
40
+ - Use proper TypeScript types in JSDoc annotations.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  ## {{ UNRELEASED_VERSION }} - [{{ UNRELEASED_DATE }}]({{ UNRELEASED_LINK }})
2
2
 
3
- ## v3.26.3-1florianPat.9 - [February 9, 2026](https://github.com/HDNET/lando-core/releases/tag/v3.26.3-1florianPat.9)
3
+ ## v3.26.5-1florianPat.0 - [May 24, 2026](https://github.com/HDNET/lando-core/releases/tag/v3.26.5-1florianPat.0)
4
+
5
+ ## v3.26.4 - [April 28, 2026](https://github.com/lando/core/releases/tag/v3.26.4)
6
+
7
+ * Fixed `lando ssh` defaulting to a v3 service instead of the v4 `appserver` in mixed-api apps [#461](https://github.com/lando/core/pull/461)
8
+
9
+ ## v3.26.3 - [April 14, 2026](https://github.com/lando/core/releases/tag/v3.26.3)
10
+
11
+ * Fixed crash when `config.yml` is empty instead of containing `{}` [#439](https://github.com/lando/core/issues/439)
12
+ * Updated `lando setup` to install `docker-buildx` if missing
13
+ * Fixed `buildx` built images not being available locally by adding `--load` flag
4
14
 
5
15
  ## v3.26.2 - [December 17, 2025](https://github.com/lando/core/releases/tag/v3.26.2)
6
16
 
package/app.js CHANGED
@@ -137,9 +137,29 @@ module.exports = async (app, lando) => {
137
137
  // Add localhost info to our containers if they are up
138
138
  app.events.on('post-init-engine', async () => await require('./hooks/app-find-localhosts')(app, lando));
139
139
 
140
+ // Set LANDO_DOCKER_DATA_ROOT from docker info
141
+ // @NOTE: post-init-engine is skipped when noEngine is true (eg lando setup) so we dont
142
+ // try to hit docker when its not installed yet. app-find-localhosts above calls engine.list
143
+ // which goes through daemon.up() so docker is guaranteed running by this point.
144
+ app.events.on('post-init-engine', async () => {
145
+ try {
146
+ const info = await lando.engine.docker.info();
147
+ if (!info?.DockerRootDir) {
148
+ throw new Error();
149
+ }
150
+
151
+ app.env.LANDO_DOCKER_DATA_ROOT = info.DockerRootDir;
152
+ } catch (e) {
153
+ app.log.error('could not get docker info for data root');
154
+ }
155
+ });
156
+
140
157
  // override default tooling commands if needed
141
158
  app.events.on('ready', 1, async () => await require('./hooks/app-override-tooling-defaults')(app, lando));
142
159
 
160
+ // Generate certs for v3 SSL services as needed
161
+ app.events.on('ready', 2, async () => await require('./hooks/app-generate-v3-certs')(app, lando));
162
+
143
163
  // set tooling compose cache
144
164
  app.events.on('ready', async () => await require('./hooks/app-set-compose-cache')(app, lando));
145
165
 
@@ -173,9 +193,6 @@ module.exports = async (app, lando) => {
173
193
  // Check for updates if the update cache is empty
174
194
  app.events.on('pre-start', 1, async () => await require('./hooks/app-check-for-updates')(app, lando));
175
195
 
176
- // Generate certs for v3 SSL services as needed
177
- app.events.on('pre-start', 2, async () => await require('./hooks/app-generate-v3-certs')(app, lando));
178
-
179
196
  // If the app already is installed but we can't determine the builtAgainst, then set it to something bogus
180
197
  app.events.on('pre-start', async () => await require('./hooks/app-update-built-against-pre')(app, lando));
181
198
 
@@ -230,6 +247,9 @@ module.exports = async (app, lando) => {
230
247
  // remove tooling cache
231
248
  app.events.on('post-uninstall', async () => await require('./hooks/app-purge-recipe-cache')(app, lando));
232
249
 
250
+ // remove proxy certs and config
251
+ app.events.on('post-uninstall', async () => await require('./hooks/app-purge-proxy-certs-and-config')(app, lando));
252
+
233
253
  // Remove meta cache on destroy
234
254
  app.events.on('post-destroy', async () => await require('./hooks/app-purge-metadata-cache')(app, lando));
235
255
 
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+
5
+ const toArray = value => Array.isArray(value) ? value : [];
6
+
7
+ module.exports = {
8
+ name: 'lando-compose',
9
+ api: 3,
10
+ parent: '_lando',
11
+ builder: parent => class LandoComposeServiceV3 extends parent {
12
+ constructor(id, options = {}) {
13
+ // get the original entrypoint and command from the compose data
14
+ // load-compose-files ensures these are populated from the image if not set in compose
15
+ const composeServices = _.get(options, '_app.composeData[0].data[0].services', {});
16
+ const composeService = _.get(composeServices, options.name, {});
17
+
18
+ const originalEntrypoint = toArray(composeService.entrypoint);
19
+ const originalCommand = toArray(composeService.command);
20
+ const composeWorkingDir = composeService.working_dir || null;
21
+
22
+ if (originalEntrypoint.length === 1 &&
23
+ (originalEntrypoint[0] === '/lando-entrypoint.sh' || originalEntrypoint[0] === '/helpers/lando-entrypoint.sh')
24
+ ) {
25
+ options.landoEntrypoint = false;
26
+ }
27
+ const command = [...originalEntrypoint, ...originalCommand];
28
+
29
+ // If appMount is not explicitly set in options, use the compose working_dir (which
30
+ // load-compose-files resolves from the image if not set in compose), falling back to '/'
31
+ const appMount = options.appMount ?? composeWorkingDir ?? '/';
32
+
33
+ const opts = _.merge({}, {
34
+ // let the parent _lando set entrypoint to /lando-entrypoint.sh
35
+ data: null, // NOTE: Do not create the data volume
36
+ dataHome: null, // NOTE: Do not create the dataHome volume
37
+ appMount,
38
+ sslExpose: false,
39
+ ssl: true,
40
+ }, options);
41
+
42
+ if ((options.landoEntrypoint ?? true) && command.length > 0) {
43
+ opts.overrides = _.merge({}, {command}, options.overrides);
44
+ } else {
45
+ opts.entrypoint = undefined;
46
+ }
47
+
48
+ super(id, opts);
49
+ }
50
+ },
51
+ };
@@ -251,6 +251,7 @@ class DockerEngine extends Dockerode {
251
251
  'buildx',
252
252
  'build',
253
253
  `--file=${dockerfile}`,
254
+ '--load',
254
255
  '--progress=plain',
255
256
  `--tag=${tag}`,
256
257
  context,
@@ -90,7 +90,7 @@ class L337ServiceV4 extends EventEmitter {
90
90
  merge(this.#app.info.find(service => service.service === this.id) ?? {}, data);
91
91
  }
92
92
  this.emit('state', this.#data.info);
93
- this.#app.v4.updateComposeCache();
93
+ if (this.#app.initialized) this.#app.v4.updateComposeCache();
94
94
  }
95
95
 
96
96
  get info() {
@@ -253,7 +253,7 @@ class L337ServiceV4 extends EventEmitter {
253
253
  this.#app.compose = require('../utils/dump-compose-data')(this.#app.composeData, this.#app._dir);
254
254
 
255
255
  // update and log
256
- this.#app.v4.updateComposeCache();
256
+ if (this.#app.initialized) this.#app.v4.updateComposeCache();
257
257
  }
258
258
 
259
259
  // adds files/dirs to the build context
package/config.yml CHANGED
@@ -11,23 +11,23 @@ stats:
11
11
 
12
12
  dockerSupportedVersions:
13
13
  compose:
14
- satisfies: "1.x.x || 2.x.x"
15
- recommendUpdate: "<=2.40.2"
16
- tested: "<=2.40.99"
14
+ satisfies: "1.x.x || <6"
15
+ recommendUpdate: "<=5.1.0"
16
+ tested: "<=5.1.1"
17
17
  link:
18
18
  linux: https://docs.docker.com/compose/install/#install-compose-on-linux-systems
19
19
  darwin: https://docs.docker.com/desktop/install/mac-install/
20
20
  win32: https://docs.docker.com/desktop/install/windows-install/
21
21
  desktop:
22
22
  satisfies: ">=4.0.0 <5"
23
- tested: "<=4.54.99"
24
- recommendUpdate: "<=4.53"
23
+ tested: "<5"
24
+ recommendUpdate: "<=4.66"
25
25
  link:
26
26
  darwin: https://docs.docker.com/desktop/install/mac-install/
27
27
  win32: https://docs.docker.com/desktop/install/windows-install/
28
28
  wsl: https://docs.docker.com/desktop/install/windows-install/
29
29
  engine:
30
30
  satisfies: ">=18 <30"
31
- tested: "<=29.1.99"
31
+ tested: "<30"
32
32
  link:
33
33
  linux: https://docs.docker.com/engine/install/debian/#install-using-the-convenience-script
@@ -15,8 +15,7 @@ module.exports = async (app, lando) => {
15
15
  return landonet.disconnect({Container: container.id, Force: true})
16
16
  // Only throw non not connected errors
17
17
  .catch(error => {
18
- if (!_.includes(error.message, 'is not connected to network') &&
19
- !_.includes(error.message, 'is not connected to the network')) throw error;
18
+ if (!_.includes(error.message, 'is not connected to network')) throw error;
20
19
  })
21
20
  // Connect
22
21
  .then(() => {
@@ -34,8 +34,7 @@ module.exports = async (app, lando) => {
34
34
  return bridgeNet.disconnect({Container: proxyContainer, Force: true})
35
35
  // Only throw non not connected errors
36
36
  .catch(error => {
37
- if (!_.includes(error.message, 'is not connected to network') &&
38
- !_.includes(error.message, 'is not connected to the network')) throw error;
37
+ if (!_.includes(error.message, 'is not connected to network')) throw error;
39
38
  })
40
39
  // Connect
41
40
  .then(() => {
@@ -5,14 +5,14 @@ const _ = require('lodash');
5
5
  module.exports = async (app, lando) => {
6
6
  // add parsed services to app object so we can use them downstream
7
7
  app.cachedInfo = _.get(lando.cache.get(app.composeCache), 'info', []);
8
+ app.config.services = _.mapValues(_.get(app, 'config.services', {}), (service, name) => {
9
+ const composeServices = _.keys(_.get(app, 'composeData[0].data[0].services', {}));
10
+ if (!_.includes(composeServices, name) || service?.api === 4) {
11
+ return service;
12
+ }
13
+ return _.merge({}, {type: 'lando-compose', version: 'custom', api: 3}, service);
14
+ });
8
15
  app.parsedServices = require('../utils/parse-v3-services')(_.get(app, 'config.services', {}), app);
9
- app.parsedServices = app.parsedServices.concat(
10
- require('../utils/parse-compose-services')(
11
- _.get(app, 'config.services', {}),
12
- _.keys(_.get(app, 'composeData[0].data[0].services', {})),
13
- app,
14
- ),
15
- );
16
16
  app.parsedV3Services = _(app.parsedServices).filter(service => service.api === 3).value();
17
17
  app.servicesList = app.parsedV3Services.map(service => service.name);
18
18
 
@@ -15,6 +15,8 @@ const parseUrls = (urls = []) => {
15
15
  };
16
16
 
17
17
  module.exports = async (app, lando) => {
18
+ if (lando.cache.get(app.composeCache)) return;
19
+
18
20
  const certServices = app.info
19
21
  .filter(service => service.hasCerts === true)
20
22
  .map(service => ({
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const remove = require('../utils/remove');
6
+
7
+ module.exports = async (app, lando) => {
8
+ const certsDir = path.join(lando.config.userConfRoot, 'certs');
9
+ const proxyConfigDir = lando.config.proxyConfigDir;
10
+
11
+ for (const dir of [certsDir, proxyConfigDir]) {
12
+ if (!fs.existsSync(dir)) continue;
13
+ fs.readdirSync(dir)
14
+ .filter(f => f.includes(`.${app.project}.`))
15
+ .forEach(f => {
16
+ try {
17
+ remove(path.join(dir, f));
18
+ app.log.debug('removed proxy cert/config %s', f);
19
+ } catch {
20
+ app.log.debug('could not remove proxy cert/config %s', f);
21
+ }
22
+ });
23
+ }
24
+ };
@@ -281,10 +281,9 @@ module.exports = async (app, lando) => {
281
281
  }
282
282
 
283
283
  // Get list of services that *should* have certs for SSL
284
- const sslReady = _(_.get(app, 'config.services', []))
285
- .map((data, name) => _.merge({}, data, {name}))
286
- .filter(data => data.ssl)
287
- .map(data => data.name)
284
+ const sslReady = _(app.info)
285
+ .filter(data => data?.hasCerts)
286
+ .map(data => data.service)
288
287
  .value();
289
288
 
290
289
  // Make sure we augment ssl ready if we have served by candidates
@@ -3,7 +3,10 @@
3
3
  // Modules
4
4
  const _ = require('lodash');
5
5
 
6
- module.exports = async lando => lando.engine.getNetworks().then(networks => {
6
+ module.exports = async lando => {
7
+ if (lando.cache.get('_.networks.checked')) return;
8
+ lando.cache.set('_.networks.checked', true);
9
+ return lando.engine.getNetworks().then(networks => {
7
10
  if (_.size(networks) >= lando.config.networkLimit) {
8
11
  // Warn user about this action
9
12
  lando.log.warn('Lando has detected you are at Docker\'s network limit!');
@@ -37,3 +40,4 @@ module.exports = async lando => lando.engine.getNetworks().then(networks => {
37
40
  });
38
41
  }
39
42
  });
43
+ };
@@ -0,0 +1,91 @@
1
+ 'use strict';
2
+
3
+ const axios = require('../utils/get-axios')();
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ /*
8
+ * Helper to get buildx download url
9
+ */
10
+ const getBuildxDownloadUrl = (version = '0.30.1') => {
11
+ const arch = process.arch === 'arm64' ? 'arm64' : 'amd64';
12
+
13
+ switch (process.platform) {
14
+ case 'darwin':
15
+ return `https://github.com/docker/buildx/releases/download/v${version}/buildx-v${version}.darwin-${arch}`;
16
+ case 'linux':
17
+ return `https://github.com/docker/buildx/releases/download/v${version}/buildx-v${version}.linux-${arch}`;
18
+ case 'win32':
19
+ return `https://github.com/docker/buildx/releases/download/v${version}/buildx-v${version}.windows-${arch}.exe`;
20
+ }
21
+ };
22
+
23
+ /*
24
+ * Helper to get buildx download destination
25
+ */
26
+ const getBuildxDownloadDest = home => {
27
+ const dir = path.join(home, '.docker', 'cli-plugins');
28
+ switch (process.platform) {
29
+ case 'linux':
30
+ case 'darwin':
31
+ return path.join(dir, 'docker-buildx');
32
+ case 'win32':
33
+ return path.join(dir, 'docker-buildx.exe');
34
+ }
35
+ };
36
+
37
+ module.exports = async (lando, options) => {
38
+ const debug = require('../utils/debug-shim')(lando.log);
39
+ const {color} = require('listr2');
40
+
41
+ // get stuff from config/opts
42
+ const {home} = lando.config;
43
+ const {buildx} = options;
44
+
45
+ // if buildx is set to false allow it to be skipped
46
+ if (buildx === false) return;
47
+
48
+ const dest = getBuildxDownloadDest(home);
49
+ const url = getBuildxDownloadUrl(buildx);
50
+
51
+ options.tasks.push({
52
+ title: `Downloading buildx`,
53
+ id: 'setup-buildx',
54
+ dependsOn: ['setup-build-engine'],
55
+ description: '@lando/buildx (docker-buildx)',
56
+ version: `Docker Buildx v${buildx}`,
57
+ hasRun: async () => {
58
+ try {
59
+ await require('../utils/run-command')('docker', ['buildx', 'version'], {debug});
60
+ return true;
61
+ } catch {
62
+ return false;
63
+ }
64
+ },
65
+ canRun: async () => {
66
+ // throw error if we cannot ping the download link
67
+ await axios.head(url);
68
+ // true if we get here
69
+ return true;
70
+ },
71
+ task: async (ctx, task) => new Promise((resolve, reject) => {
72
+ // ensure the cli-plugins directory exists
73
+ fs.mkdirSync(path.dirname(dest), {recursive: true});
74
+
75
+ const download = require('../utils/download-x')(url, {debug, dest, test: ['version']});
76
+ // success
77
+ download.on('done', data => {
78
+ task.title = `Installed buildx (Docker Buildx) to ${dest}`;
79
+ resolve(data);
80
+ });
81
+ // handle errors
82
+ download.on('error', error => {
83
+ reject(error);
84
+ });
85
+ // update title to reflect download progress
86
+ download.on('progress', progress => {
87
+ task.title = `Downloading buildx ${color.dim(`[${progress.percentage}%]`)}`;
88
+ });
89
+ }),
90
+ });
91
+ };
@@ -7,7 +7,7 @@ const path = require('path');
7
7
  /*
8
8
  * Helper to get docker compose v2 download url
9
9
  */
10
- const getComposeDownloadUrl = (version = '2.40.3') => {
10
+ const getComposeDownloadUrl = (version = '5.1.1') => {
11
11
  const mv = version.split('.')[0] > 1 ? '2' : '1';
12
12
  const arch = process.arch === 'arm64' ? 'aarch64' : 'x86_64';
13
13
  const toggle = `${process.platform}-${mv}`;
@@ -31,7 +31,7 @@ const getComposeDownloadUrl = (version = '2.40.3') => {
31
31
  /*
32
32
  * Helper to get docker compose v2 download destination
33
33
  */
34
- const getComposeDownloadDest = (base, version = '2.31.0') => {
34
+ const getComposeDownloadDest = (base, version = '5.1.1') => {
35
35
  switch (process.platform) {
36
36
  case 'linux':
37
37
  case 'darwin':
package/index.js CHANGED
@@ -97,6 +97,9 @@ module.exports = async lando => {
97
97
  // ensure we setup docker-compose if needed
98
98
  lando.events.once('pre-setup', async options => await require('./hooks/lando-setup-orchestrator')(lando, options));
99
99
 
100
+ // ensure we setup buildx if needed
101
+ lando.events.once('pre-setup', async options => await require('./hooks/lando-setup-buildx')(lando, options));
102
+
100
103
  // ensure we setup landonet
101
104
  lando.events.once('pre-setup', async options => await require('./hooks/lando-setup-landonet')(lando, options));
102
105
 
package/jsconfig.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": true,
4
+ "checkJs": true,
5
+ "noEmit": true,
6
+ "skipLibCheck": true,
7
+ "strict": false,
8
+ "moduleResolution": "node",
9
+ "ignoreDeprecations": "6.0",
10
+ "target": "es2022",
11
+ "resolveJsonModule": true
12
+ },
13
+ "include": [
14
+ "app.js",
15
+ "index.js",
16
+ "builders/**/*.js",
17
+ "components/**/*.js",
18
+ "experimental/**/*.js",
19
+ "hooks/**/*.js",
20
+ "inits/**/*.js",
21
+ "lib/**/*.js",
22
+ "messages/**/*.js",
23
+ "packages/**/*.js",
24
+ "plugins/**/*.js",
25
+ "renderers/**/*.js",
26
+ "sources/**/*.js",
27
+ "tasks/**/*.js",
28
+ "utils/**/*.js"
29
+ ],
30
+ "exclude": [
31
+ "node_modules"
32
+ ]
33
+ }
package/lib/app.js CHANGED
@@ -300,8 +300,11 @@ module.exports = class App {
300
300
  _.get(this, 'config.compose', []),
301
301
  this.root,
302
302
  this._dir,
303
- (composeFiles, outputFilePath) =>
304
- this.engine.getComposeConfig({compose: composeFiles, project: this.project, outputFilePath, opts: {envFiles: composeEnvFiles}}),
303
+ this.engine,
304
+ this.project,
305
+ composeEnvFiles,
306
+ this.log,
307
+ _.get(this, '_config.orchestratorSeparator', '_'),
305
308
  ))
306
309
  .then(composeFileData => {
307
310
  this.composeData = [new this.ComposeService('compose', {}, ...composeFileData)];
@@ -381,11 +384,15 @@ module.exports = class App {
381
384
 
382
385
  // reset the default service to the primary v4 service if we only have v4 services
383
386
  if (this._serviceApi === 4) this._defaultService = this.v4.primaryService.name;
384
- // reset the default service to the first v3 service if there is no appserver
385
- else if (this.serviceGroups['3'].length > 0 && !_.find(this.serviceGroups['3'], {service: 'appserver'})) {
387
+ // reset the default service to the first v3 service if there is no appserver in v3 or v4
388
+ else if (this.serviceGroups['3'].length > 0
389
+ && !_.find(this.serviceGroups['3'], {service: 'appserver'})
390
+ && !_.find(this.serviceGroups['4'], {service: 'appserver'})) {
386
391
  this._defaultService = this.serviceGroups['3'][0].service;
387
- // reset the default service to the first compose service if there is no appserver
388
- } else if (this.serviceGroups.compose.length > 0 && !_.find(this.serviceGroups.compose, {service: 'appserver'})) {
392
+ // reset the default service to the first compose service if there is no appserver in compose or v4
393
+ } else if (this.serviceGroups.compose.length > 0
394
+ && !_.find(this.serviceGroups.compose, {service: 'appserver'})
395
+ && !_.find(this.serviceGroups['4'], {service: 'appserver'})) {
389
396
  this._defaultService = this.serviceGroups.compose[0].service;
390
397
  }
391
398
 
package/lib/cli.js CHANGED
@@ -560,7 +560,7 @@ module.exports = class Cli {
560
560
  const Yaml = require(`../lib/yaml`);
561
561
  const yaml = new Yaml();
562
562
  const configFile = path.join(this.defaultConfig().userConfRoot, 'config.yml');
563
- const config = (fs.existsSync(configFile)) ? yaml.load(configFile) : {};
563
+ const config = (fs.existsSync(configFile)) ? yaml.load(configFile) || {} : {};
564
564
  const file = yaml.dump(configFile, _.assign({}, config, data));
565
565
  return yaml.load(file);
566
566
  }
package/lib/compose.js CHANGED
@@ -15,6 +15,7 @@ const composeFlags = {
15
15
  noTTY: '-T',
16
16
  pull: '--pull',
17
17
  q: '--quiet',
18
+ quietPull: '--quiet-pull',
18
19
  recreate: '--force-recreate',
19
20
  removeOrphans: '--remove-orphans',
20
21
  rm: '--rm',
@@ -33,7 +34,7 @@ const composeFlagOptionMapping = {
33
34
  ps: ['q'],
34
35
  pull: ['q', 'ignoreBuildable'],
35
36
  rm: ['force', 'volumes'],
36
- up: ['background', 'detach', 'noRecreate', 'noDeps', 'pull', 'q', 'recreate', 'removeOrphans', 'timestamps'],
37
+ up: ['background', 'detach', 'noRecreate', 'noDeps', 'pull', 'q', 'recreate', 'removeOrphans', 'timestamps', 'quietPull'],
37
38
  config: ['outputFilePath', 'q'],
38
39
  };
39
40
 
package/lib/daemon.js CHANGED
@@ -54,7 +54,7 @@ module.exports = class LandoDaemon {
54
54
  log = new Log(),
55
55
  context = 'node',
56
56
  compose = require('../utils/get-compose-x')(),
57
- orchestratorVersion = '2.40.3',
57
+ orchestratorVersion = '5.1.1',
58
58
  userConfRoot = path.join(os.homedir(), '.lando'),
59
59
  ) {
60
60
  this.cache = cache;
package/lib/lando.js CHANGED
@@ -402,7 +402,7 @@ module.exports = class Lando {
402
402
  caKey = this.config.caKey,
403
403
  domains = [],
404
404
  organization = 'Lando Alliance',
405
- validity = 365,
405
+ validity = 3650,
406
406
  } = {}) {
407
407
  const read = require('../utils/read-file');
408
408
  const write = require('../utils/write-file');
@@ -465,7 +465,7 @@ module.exports = class Lando {
465
465
  }
466
466
 
467
467
  // Load the config and augment so we can get an App
468
- const config = lmerge({}, ..._.map(landoFiles, file => yaml.load(file)));
468
+ const config = lmerge({}, ..._.map(landoFiles, file => yaml.load(file) || {}));
469
469
  this.log.info('loading app %s from config files', config.name, landoFiles);
470
470
  // Return us some app!
471
471
  const App = require('./app');
package/netlify.toml CHANGED
@@ -30,7 +30,10 @@
30
30
  "overrides",
31
31
  "fragment-check",
32
32
  "sqlshack",
33
- "/v/"
33
+ "/v/",
34
+ "dockerfile-release-notes",
35
+ "jeffgeerling.com",
36
+ "hub.docker.com",
34
37
  ]
35
38
  skipPatterns = [
36
39
  ".gif",
@@ -1,4 +1,4 @@
1
- # lodash v4.17.21
1
+ # lodash v4.17.23
2
2
 
3
3
  The [Lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules.
4
4
 
@@ -28,7 +28,7 @@ var at = require('lodash/at');
28
28
  var curryN = require('lodash/fp/curryN');
29
29
  ```
30
30
 
31
- See the [package source](https://github.com/lodash/lodash/tree/4.17.21-npm) for more details.
31
+ See the [package source](https://github.com/lodash/lodash/tree/4.17.23-npm) for more details.
32
32
 
33
33
  **Note:**<br>
34
34
  Install [n_](https://www.npmjs.com/package/n_) for Lodash use in the Node.js < 6 REPL.