Repository: ember-cli/ember-try
Pull request #1030 (2024-12-17 21:19:28)

Remove use of ember-cli `ui` instance
Part of decoupling `ember-try` from `ember-cli`.


Patch:
diff --git a/lib/commands/config.js b/lib/commands/config.js
index ec09281..9415bec 100644
--- a/lib/commands/config.js
+++ b/lib/commands/config.js
@@ -1,6 +1,7 @@
 'use strict';
 
 const debug = require('debug')('ember-try:commands:config');
+const { log } = require('../utils/console');
 
 module.exports = {
   name: 'try:config',
@@ -16,6 +17,6 @@ module.exports = {
       configPath: commandOptions.configPath,
     });
 
-    this.ui.writeLine(JSON.stringify(config, null, 2));
+    log(JSON.stringify(config, null, 2));
   },
 };
diff --git a/lib/commands/try-each.js b/lib/commands/try-each.js
index 9046f94..b58b7a0 100644
--- a/lib/commands/try-each.js
+++ b/lib/commands/try-each.js
@@ -26,7 +26,6 @@ module.exports = {
     debug('Config: %s', JSON.stringify(config));
 
     let tryEachTask = new this._TryEachTask({
-      ui: this.ui,
       project: this.project,
       config,
     });
diff --git a/lib/commands/try-ember.js b/lib/commands/try-ember.js
index be38faf..7ddd955 100644
--- a/lib/commands/try-ember.js
+++ b/lib/commands/try-ember.js
@@ -35,7 +35,6 @@ module.exports = {
     debug('Config: %s', JSON.stringify(config));
 
     let tryEachTask = new this._TryEachTask({
-      ui: this.ui,
       project: this.project,
       config,
     });
diff --git a/lib/commands/try-one.js b/lib/commands/try-one.js
index 3afc87d..6e1fba9 100644
--- a/lib/commands/try-one.js
+++ b/lib/commands/try-one.js
@@ -58,7 +58,6 @@ module.exports = {
     }
 
     let tryEachTask = new this._TryEachTask({
-      ui: this.ui,
       project: this.project,
       config,
       commandArgs,
diff --git a/lib/dependency-manager-adapters/base.js b/lib/dependency-manager-adapters/base.js
index cb95f5f..5df0e1a 100644
--- a/lib/dependency-manager-adapters/base.js
+++ b/lib/dependency-manager-adapters/base.js
@@ -1,12 +1,12 @@
 'use strict';
 
-const chalk = require('chalk');
 const debug = require('debug');
 const { get, set } = require('es-toolkit/compat');
 const fs = require('fs-extra');
 const path = require('node:path');
 const semver = require('semver');
 const Backup = require('../utils/backup');
+const { warn } = require('../utils/console');
 const { LOCKFILE, PACKAGE_JSON } = require('../utils/package-managers');
 
 class BaseAdapter {
@@ -35,8 +35,8 @@ class BaseAdapter {
     this.debugFunction(...args);
   }
 
-  async setup(options = {}) {
-    this._checkForDifferentLockfiles(options.ui);
+  async setup() {
+    this._checkForDifferentLockfiles();
 
     await this.backup.addFiles([PACKAGE_JSON, this.lockfile]);
   }
@@ -87,7 +87,7 @@ class BaseAdapter {
     }
   }
 
-  _checkForDifferentLockfiles(ui) {
+  _checkForDifferentLockfiles() {
     for (const packageManager in LOCKFILE) {
       const lockfile = LOCKFILE[packageManager];
 
@@ -97,10 +97,8 @@ class BaseAdapter {
 
       try {
         if (fs.statSync(path.join(this.cwd, lockfile)).isFile()) {
-          ui.writeLine(
-            chalk.yellow(
-              `Detected a \`${lockfile}\` file. Add \`packageManager: '${packageManager}'\` to your \`config/ember-try.js\` configuration file if you want to use ${packageManager} to install dependencies.`,
-            ),
+          warn(
+            `Detected a \`${lockfile}\` file. Add \`packageManager: '${packageManager}'\` to your \`config/ember-try.js\` configuration file if you want to use ${packageManager} to install dependencies.`,
           );
         }
       } catch {
diff --git a/lib/dependency-manager-adapters/pnpm.js b/lib/dependency-manager-adapters/pnpm.js
index 891f005..79ff443 100644
--- a/lib/dependency-manager-adapters/pnpm.js
+++ b/lib/dependency-manager-adapters/pnpm.js
@@ -10,9 +10,9 @@ module.exports = class PnpmAdapter extends BaseAdapter {
   name = 'pnpm';
   overridesKey = 'pnpm.overrides';
 
-  async setup(options) {
+  async setup() {
     await this._throwOnResolutionMode();
-    await super.setup(options);
+    await super.setup();
   }
 
   /**
diff --git a/lib/dependency-manager-adapters/workspace.js b/lib/dependency-manager-adapters/workspace.js
index 38c0345..522c97e 100644
--- a/lib/dependency-manager-adapters/workspace.js
+++ b/lib/dependency-manager-adapters/workspace.js
@@ -54,8 +54,8 @@ module.exports = class {
     });
   }
 
-  setup(options) {
-    return Promise.all(this._packageAdapters.map((adapter) => adapter.setup(options)));
+  setup() {
+    return Promise.all(this._packageAdapters.map((adapter) => adapter.setup()));
   }
 
   async changeToDependencySet(depSet) {
diff --git a/lib/tasks/try-each.js b/lib/tasks/try-each.js
index ce5269a..97eb577 100644
--- a/lib/tasks/try-each.js
+++ b/lib/tasks/try-each.js
@@ -1,8 +1,8 @@
 'use strict';
 
-const chalk = require('chalk');
 const debug = require('debug')('ember-try:task:try-each');
-const runCommand = require('./../utils/run-command');
+const { error, info, log } = require('../utils/console');
+const runCommand = require('../utils/run-command');
 
 module.exports = class TryEachTask {
   constructor(options) {
@@ -11,7 +11,6 @@ module.exports = class TryEachTask {
     this.config = options.config;
     this.dependencyManagerAdapters = options.dependencyManagerAdapters;
     this.project = options.project;
-    this.ui = options.ui;
   }
 
   async run(scenarios, options) {
@@ -30,14 +29,13 @@ module.exports = class TryEachTask {
       }),
     );
     this.ScenarioManager = new ScenarioManager({
-      ui: this.ui,
       dependencyManagerAdapters,
     });
 
     this._canceling = false;
     this._on('SIGINT', () => {
       this._canceling = true;
-      this.ui.writeLine('\nGracefully shutting down from SIGINT (Ctrl-C)');
+      log('\nGracefully shutting down from SIGINT (Ctrl-C)');
       return this.ScenarioManager.cleanup();
     });
 
@@ -57,11 +55,11 @@ module.exports = class TryEachTask {
 
       return this._exitAsAppropriate(results);
     } catch (err) {
-      this.ui.writeLine(chalk.red('Error!'));
+      error('Error!');
 
       if (err) {
-        this.ui.writeLine(chalk.red(err));
-        this.ui.writeLine(chalk.red(err.stack));
+        error(err);
+        error(err.stack);
       }
 
       return 1; // Signifies exit code
@@ -111,12 +109,12 @@ module.exports = class TryEachTask {
   _writeHeader(text) {
     let count = 75 - text.length;
     let separator = new Array(count + 1).join('=');
-    this.ui.writeLine(chalk.blue(`\n=== ${text} ${separator}\n`));
+    info(`\n=== ${text} ${separator}\n`);
   }
 
   _writeFooter(text) {
-    this.ui.writeLine(chalk.blue(`\n${text}`));
-    this.ui.writeLine(chalk.blue('---\n'));
+    info(`\n${text}`);
+    info('---\n');
   }
 
   _determineCommandFor(scenario) {
@@ -152,7 +150,7 @@ module.exports = class TryEachTask {
   }
 
   _printResults(results) {
-    new this.ResultSummary({ ui: this.ui, results }).print();
+    new this.ResultSummary({ results }).print();
   }
 
   _exitAsAppropriate(results) {
diff --git a/lib/utils/config.js b/lib/utils/config.js
index a6231cb..12ab447 100644
--- a/lib/utils/config.js
+++ b/lib/utils/config.js
@@ -1,8 +1,8 @@
 'use strict';
 
-const chalk = require('chalk');
 const path = require('path');
 const fs = require('fs');
+const { prefix, warn } = require('./console');
 const findByName = require('./find-by-name');
 const debug = require('debug')('ember-try:utils:config');
 
@@ -70,10 +70,8 @@ async function config(options) {
     const [name, oldOption] = packageManager;
 
     if (typeof configData[oldOption] === 'boolean') {
-      console.warn(
-        chalk.yellow(
-          `${chalk.inverse(' ember-try DEPRECATION ')} The \`${oldOption}\` config option is deprecated. Please use \`packageManager: '${name}'\` instead.`,
-        ),
+      warn(
+        `${prefix('ember-try DEPRECATION')} The \`${oldOption}\` config option is deprecated. Please use \`packageManager: '${name}'\` instead.`,
       );
 
       delete configData[oldOption];
diff --git a/lib/utils/console.js b/lib/utils/console.js
new file mode 100644
index 0000000..f5850c5
--- /dev/null
+++ b/lib/utils/console.js
@@ -0,0 +1,51 @@
+const chalk = require('chalk');
+
+let logFunction = originalLogFunction;
+
+function error(message) {
+  logFunction(message, console.error, chalk.red);
+}
+
+function info(message) {
+  logFunction(message, console.info, chalk.blue);
+}
+
+function log(message) {
+  logFunction(message, console.log);
+}
+
+function prefix(string) {
+  return chalk.inverse(` ${string} `);
+}
+
+function success(message) {
+  logFunction(message, console.log, chalk.green);
+}
+
+function warn(message) {
+  logFunction(message, console.warn, chalk.yellow);
+}
+
+function originalLogFunction(message, consoleLogFunction, chalkColorFunction) {
+  consoleLogFunction(chalkColorFunction ? chalkColorFunction(message) : message);
+}
+
+function mockLog(mockedLogFunction) {
+  logFunction = mockedLogFunction;
+}
+
+function restoreLog() {
+  logFunction = originalLogFunction;
+}
+
+module.exports = {
+  error,
+  info,
+  log,
+  prefix,
+  success,
+  warn,
+
+  _mockLog: mockLog,
+  _restoreLog: restoreLog,
+};
diff --git a/lib/utils/result-summary.js b/lib/utils/result-summary.js
index 36d419c..0d22886 100644
--- a/lib/utils/result-summary.js
+++ b/lib/utils/result-summary.js
@@ -2,11 +2,11 @@
 
 const chalk = require('chalk');
 const Table = require('cli-table3');
+const { error, info, log, success } = require('./console');
 
 module.exports = class ResultSummary {
   constructor(options) {
     this.results = options.results;
-    this.ui = options.ui;
   }
 
   print() {
@@ -33,30 +33,28 @@ module.exports = class ResultSummary {
         colorAndMessage = chalk.red(failMessage);
         countFailed++;
       }
-      task.ui.writeLine(colorAndMessage);
-      task.ui.writeLine(`Command run: ${scenario.command}`);
+      log(colorAndMessage);
+      log(`Command run: ${scenario.command}`);
       if (scenario.envState) {
-        task.ui.writeLine(`with env: ${JSON.stringify(scenario.envState, null, 2)}`);
+        log(`with env: ${JSON.stringify(scenario.envState, null, 2)}`);
       }
       task._printDependencyTable(scenario.dependencyState);
     });
 
-    task.ui.writeLine('');
+    log('');
     task._printResultsSummary(countFailed, countPassed, allowedFailCount, this.results.length);
   }
 
   _printResultHeader() {
-    let task = this;
-    task.ui.writeLine('');
-    task.ui.writeLine('------ RESULTS ------');
-    task.ui.writeLine('');
+    log('');
+    log('------ RESULTS ------');
+    log('');
   }
 
   _printDependencyTable(dependencyStatus) {
     if (!dependencyStatus.length) {
       return;
     }
-    let task = this;
     let colorForDepFn;
     let tableRow;
     let table = new Table({
@@ -84,22 +82,21 @@ module.exports = class ResultSummary {
       });
       table.push(tableRow);
     });
-    task.ui.writeLine(table);
-    task.ui.writeLine('');
+    log(table);
+    log('');
   }
 
   _printResultsSummary(countFailed, countPassed, allowedFailCount, total) {
-    let task = this;
     if (countFailed) {
       let failMessage = `${countFailed} scenarios failed`;
       if (allowedFailCount) {
         failMessage = `${failMessage} (${allowedFailCount} allowed)`;
       }
-      task.ui.writeLine(chalk.red(failMessage));
-      task.ui.writeLine(chalk.green(`${countPassed} scenarios succeeded`));
-      task.ui.writeLine(chalk.gray(`${total} scenarios run`));
+      error(failMessage);
+      success(`${countPassed} scenarios succeeded`);
+      info(`${total} scenarios run`);
     } else {
-      task.ui.writeLine(chalk.green(`All ${countPassed} scenarios succeeded`));
+      success(`All ${countPassed} scenarios succeeded`);
     }
   }
 };
diff --git a/lib/utils/scenario-manager.js b/lib/utils/scenario-manager.js
index 9084d2f..9ea99a8 100644
--- a/lib/utils/scenario-manager.js
+++ b/lib/utils/scenario-manager.js
@@ -3,19 +3,17 @@
 module.exports = class ScenarioManager {
   constructor(options) {
     this.dependencyManagerAdapters = options.dependencyManagerAdapters;
-    this.ui = options.ui;
   }
 
   async setup() {
-    let { ui } = this;
-
     for (let depManager of this.dependencyManagerAdapters) {
-      await depManager.setup({ ui });
+      await depManager.setup();
     }
   }
 
   async changeTo(scenario) {
     let results = [];
+
     for (let depManager of this.dependencyManagerAdapters) {
       if (scenario[depManager.configKey]) {
         let depManagerResults = await depManager.changeToDependencySet(


Test patch:
diff --git a/test/tasks/try-each-test.js b/test/tasks/try-each-test.js
index 75b3912..8d97448 100644
--- a/test/tasks/try-each-test.js
+++ b/test/tasks/try-each-test.js
@@ -6,6 +6,7 @@ const path = require('path');
 const fs = require('fs-extra');
 const fixturePackage = require('../fixtures/package.json');
 const writeJSONFile = require('../helpers/write-json-file');
+const { _mockLog, _restoreLog } = require('../../lib/utils/console');
 const { _mockRun, _restoreRun } = require('../../lib/utils/run');
 
 /* Some of the tests in this file intentionally DO NOT stub dependency manager adapter*/
@@ -57,6 +58,7 @@ describe('tryEach', () => {
   });
 
   afterEach(() => {
+    _restoreLog();
     _restoreRun();
     process.chdir(root);
     return fs.remove(tmproot);
@@ -77,9 +79,10 @@ describe('tryEach', () => {
         output.push(log);
       };
 
+      _mockLog(outputFn);
+
       let TryEachTask = require('../../lib/tasks/try-each');
       let tryEachTask = new TryEachTask({
-        ui: { writeLine: outputFn },
         project: { root: tmpdir },
         config,
       });
@@ -132,9 +135,10 @@ describe('tryEach', () => {
         output.push(log);
       };
 
+      _mockLog(outputFn);
+
       let TryEachTask = require('../../lib/tasks/try-each');
       let tryEachTask = new TryEachTask({
-        ui: { writeLine: outputFn },
         project: { root: tmpdir },
         config,
       });
@@ -197,9 +201,10 @@ describe('tryEach', () => {
         output.push(log);
       };
 
+      _mockLog(outputFn);
+
       let TryEachTask = require('../../lib/tasks/try-each');
       let tryEachTask = new TryEachTask({
-        ui: { writeLine: outputFn },
         project: { root: tmpdir },
         config,
         dependencyManagerAdapters: [],
@@ -245,9 +250,10 @@ describe('tryEach', () => {
         output.push(log);
       };
 
+      _mockLog(outputFn);
+
       let TryEachTask = require('../../lib/tasks/try-each');
       let tryEachTask = new TryEachTask({
-        ui: { writeLine: outputFn },
         project: { root: tmpdir },
         config,
         commandArgs: ['ember', 'serve'],
@@ -299,9 +305,10 @@ describe('tryEach', () => {
           output.push(log);
         };
 
+        _mockLog(outputFn);
+
         let TryEachTask = require('../../lib/tasks/try-each');
         let tryEachTask = new TryEachTask({
-          ui: { writeLine: outputFn },
           project: { root: tmpdir },
           config,
           dependencyManagerAdapters: [new StubDependencyAdapter()],
@@ -350,9 +357,10 @@ describe('tryEach', () => {
           output.push(log);
         };
 
+        _mockLog(outputFn);
+
         let TryEachTask = require('../../lib/tasks/try-each');
         let tryEachTask = new TryEachTask({
-          ui: { writeLine: outputFn },
           project: { root: tmpdir },
           config,
           dependencyManagerAdapters: [new StubDependencyAdapter()],
@@ -402,9 +410,10 @@ describe('tryEach', () => {
           output.push(log);
         };
 
+        _mockLog(outputFn);
+
         let TryEachTask = require('../../lib/tasks/try-each');
         let tryEachTask = new TryEachTask({
-          ui: { writeLine: outputFn },
           project: { root: tmpdir },
           config,
           dependencyManagerAdapters: [new StubDependencyAdapter()],
@@ -457,9 +466,10 @@ describe('tryEach', () => {
           output.push(log);
         };
 
+        _mockLog(outputFn);
+
         let TryEachTask = require('../../lib/tasks/try-each');
         let tryEachTask = new TryEachTask({
-          ui: { writeLine: outputFn },
           project: { root: tmpdir },
           config,
           commandArgs: [],
@@ -505,9 +515,10 @@ describe('tryEach', () => {
           output.push(log);
         };
 
+        _mockLog(outputFn);
+
         let TryEachTask = require('../../lib/tasks/try-each');
         let tryEachTask = new TryEachTask({
-          ui: { writeLine: outputFn },
           project: { root: tmpdir },
           config,
           commandArgs: ['ember', 'serve'],
@@ -578,9 +589,10 @@ describe('tryEach', () => {
           output.push(log);
         };
 
+        _mockLog(outputFn);
+
         let TryEachTask = require('../../lib/tasks/try-each');
         let tryEachTask = new TryEachTask({
-          ui: { writeLine: outputFn },
           project: { root: tmpdir },
           config,
           dependencyManagerAdapters: [new StubDependencyAdapter()],
@@ -626,9 +638,10 @@ describe('tryEach', () => {
           output.push(log);
         };
 
+        _mockLog(outputFn);
+
         let TryEachTask = require('../../lib/tasks/try-each');
         let tryEachTask = new TryEachTask({
-          ui: { writeLine: outputFn },
           project: { root: tmpdir },
           config,
           commandArgs: ['ember', 'version', '--verbose', 'true'],
@@ -682,9 +695,10 @@ describe('tryEach', () => {
           output.push(log);
         };
 
+        _mockLog(outputFn);
+
         let TryEachTask = require('../../lib/tasks/try-each');
         let tryEachTask = new TryEachTask({
-          ui: { writeLine: outputFn },
           project: { root: tmpdir },
           config,
           dependencyManagerAdapters: [new StubDependencyAdapter()],
@@ -729,6 +743,8 @@ describe('tryEach', () => {
         output.push(log);
       };
 
+      _mockLog(outputFn);
+
       let scenarios = [];
       let mockRunCommand = function () {
         let currentScenario = process.env.EMBER_TRY_CURRENT_SCENARIO;
@@ -738,7 +754,6 @@ describe('tryEach', () => {
 
       let TryEachTask = require('../../lib/tasks/try-each');
       let tryEachTask = new TryEachTask({
-        ui: { writeLine: outputFn },
         project: { root: tmpdir },
         config,
         dependencyManagerAdapters: [new StubDependencyAdapter()],