diff --git a/docs/guides/deprecations.md b/docs/guides/deprecations.md index 587b269b5..70cf8a59d 100644 --- a/docs/guides/deprecations.md +++ b/docs/guides/deprecations.md @@ -44,6 +44,24 @@ The standalone `sls upgrade` command no longer updates osls and is scheduled for npm install -g osls@latest ``` +
 
+ +## Command `sls uninstall` + +Deprecation code: `STANDALONE_UNINSTALL_COMMAND_DEPRECATED` + +Removal target: osls v4.0.0 + +The top-level standalone `sls uninstall` command is deprecated and scheduled for removal in osls v4.0.0. It only removes the legacy standalone binary directory and does not uninstall npm-installed osls. + +Use your package manager to uninstall npm-installed osls instead: + +```sh +npm uninstall -g osls +``` + +This does not affect `serverless plugin uninstall`. +
 
## Property `console` diff --git a/lib/cli/commands-schema/no-service.js b/lib/cli/commands-schema/no-service.js index 45b75999e..525a88783 100644 --- a/lib/cli/commands-schema/no-service.js +++ b/lib/cli/commands-schema/no-service.js @@ -155,7 +155,7 @@ commands.set('plugin search', { lifecycleEvents: ['upgrade'], }); commands.set('uninstall', { - usage: 'Uninstall osls', + usage: 'Deprecated: uninstall standalone osls binary', isHidden, noSupportNotice, lifecycleEvents: ['uninstall'], diff --git a/lib/plugins/standalone.js b/lib/plugins/standalone.js index bb9debd19..ca08eaff1 100644 --- a/lib/plugins/standalone.js +++ b/lib/plugins/standalone.js @@ -6,6 +6,7 @@ const ServerlessError = require('../serverless-error'); const standaloneUtils = require('../utils/standalone'); const { remove } = require('../utils/fs/remove'); const cliCommandsSchema = require('../cli/commands-schema'); +const logDeprecation = require('../utils/log-deprecation'); const BINARY_PATH = standaloneUtils.path; const mainProgress = progress.get('main'); @@ -19,6 +20,11 @@ const upgradeCommandDeprecationMessage = [ '', 'More info: https://github.com/oss-serverless/osls/blob/main/docs/guides/deprecations.md#STANDALONE_UPGRADE_COMMAND_DEPRECATED', ].join('\n'); +const uninstallCommandDeprecationMessage = [ + 'The top-level standalone `sls uninstall` command is deprecated and scheduled for removal in osls v4.0.0.', + 'It only removes the legacy standalone binary directory and does not uninstall npm-installed osls.', + 'Use your package manager to uninstall npm-installed osls. This does not affect `serverless plugin uninstall`.', +].join('\n'); module.exports = class Standalone { constructor(serverless, cliOptions) { @@ -48,6 +54,7 @@ module.exports = class Standalone { } async uninstall() { + logDeprecation('STANDALONE_UNINSTALL_COMMAND_DEPRECATED', uninstallCommandDeprecationMessage); mainProgress.notice('Uninstalling standalone binary', { isMainEvent: true }); await remove(path.dirname(BINARY_PATH)); log.notice(); diff --git a/test/unit/lib/plugins/standalone.test.js b/test/unit/lib/plugins/standalone.test.js index 4c56d531e..1ff200d71 100644 --- a/test/unit/lib/plugins/standalone.test.js +++ b/test/unit/lib/plugins/standalone.test.js @@ -10,13 +10,14 @@ const { expect } = require('chai'); const { remove } = require('../../../../lib/utils/fs/remove'); -const loadStandalone = ({ binaryPath, removeStub } = {}) => +const loadStandalone = ({ binaryPath, logDeprecationStub, removeStub } = {}) => proxyquire('../../../../lib/plugins/standalone', { '../utils/standalone': { path: binaryPath, resolveLatestTag: sinon.stub().throws(new Error('Unexpected latest tag lookup')), resolveUrl: sinon.stub().throws(new Error('Unexpected download URL lookup')), }, + '../utils/log-deprecation': logDeprecationStub || sinon.stub(), '../utils/fs/remove': { remove: removeStub || remove }, }); @@ -57,14 +58,20 @@ describe('test/unit/lib/plugins/standalone.test.js', () => { it('recursively removes the standalone install directory on uninstall', async () => { const binaryPath = path.join(tmpDir, 'install', 'bin', 'serverless'); + const logDeprecationStub = sinon.stub(); await fsp.mkdir(path.dirname(binaryPath), { recursive: true }); await fsp.writeFile(binaryPath, 'binary'); await fsp.writeFile(path.join(tmpDir, 'install', 'config.json'), '{}'); - const Standalone = loadStandalone({ binaryPath }); + const Standalone = loadStandalone({ binaryPath, logDeprecationStub }); const standalone = new Standalone({ pluginManager: { commandRunStartTime: Date.now() } }, {}); await standalone.uninstall(); + expect(logDeprecationStub).to.have.been.calledOnce; + expect(logDeprecationStub.firstCall.args[0]).to.equal( + 'STANDALONE_UNINSTALL_COMMAND_DEPRECATED' + ); + expect(logDeprecationStub.firstCall.args[1]).to.include('npm-installed osls'); expect(fs.existsSync(path.dirname(binaryPath))).to.equal(false); }); });