diff --git a/package.json b/package.json index a2f64a8fe..7c67a0570 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "one-light-syntax": "file:packages/one-light-syntax", "one-light-ui": "file:packages/one-light-ui", "open-on-github": "https://codeload.github.com/atom/open-on-github/legacy.tar.gz/refs/tags/v1.3.2", - "package-generator": "https://codeload.github.com/atom/package-generator/legacy.tar.gz/refs/tags/v1.3.0", + "package-generator": "file:packages/package-generator", "pathwatcher": "^8.1.2", "postcss": "8.2.10", "postcss-selector-parser": "6.0.4", diff --git a/packages/package-generator/.gitignore b/packages/package-generator/.gitignore new file mode 100644 index 000000000..3c3629e64 --- /dev/null +++ b/packages/package-generator/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/packages/package-generator/CONTRIBUTING.md b/packages/package-generator/CONTRIBUTING.md new file mode 100644 index 000000000..0fd0ad696 --- /dev/null +++ b/packages/package-generator/CONTRIBUTING.md @@ -0,0 +1 @@ +See the [Atom contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md) diff --git a/packages/package-generator/ISSUE_TEMPLATE.md b/packages/package-generator/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..b60bb86c9 --- /dev/null +++ b/packages/package-generator/ISSUE_TEMPLATE.md @@ -0,0 +1,40 @@ + + +### Prerequisites + +* [ ] Put an X between the brackets on this line if you have done all of the following: + * Reproduced the problem in Safe Mode: http://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode + * Followed all applicable steps in the debugging guide: http://flight-manual.atom.io/hacking-atom/sections/debugging/ + * Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq + * Checked that your issue isn't already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom + * Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages + +### Description + +[Description of the issue] + +### Steps to Reproduce + +1. [First Step] +2. [Second Step] +3. [and so on...] + +**Expected behavior:** [What you expect to happen] + +**Actual behavior:** [What actually happens] + +**Reproduces how often:** [What percentage of the time does it reproduce?] + +### Versions + +You can get this information from copy and pasting the output of `atom --version` and `apm --version` from the command line. Also, please include the OS and what version of the OS you're running. + +### Additional Information + +Any additional information, configuration or data that might be necessary to reproduce the issue. diff --git a/packages/package-generator/LICENSE.md b/packages/package-generator/LICENSE.md new file mode 100644 index 000000000..4d231b456 --- /dev/null +++ b/packages/package-generator/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2014 GitHub Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/package-generator/PULL_REQUEST_TEMPLATE.md b/packages/package-generator/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..cdaa94a86 --- /dev/null +++ b/packages/package-generator/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,28 @@ +### Requirements + +* Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. +* All new code requires tests to ensure against regressions + +### Description of the Change + + + +### Alternate Designs + + + +### Benefits + + + +### Possible Drawbacks + + + +### Applicable Issues + + diff --git a/packages/package-generator/README.md b/packages/package-generator/README.md new file mode 100644 index 000000000..066c50f16 --- /dev/null +++ b/packages/package-generator/README.md @@ -0,0 +1,6 @@ +# Package Generator package +[![OS X Build Status](https://travis-ci.org/atom/package-generator.svg?branch=master)](https://travis-ci.org/atom/package-generator) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/7t1i4hdmljhigp9u/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/package-generator/branch/master) [![Dependency Status](https://david-dm.org/atom/package-generator.svg)](https://david-dm.org/atom/package-generator) + + +Generates and opens a new sample package, language, or syntax theme in Atom. diff --git a/packages/package-generator/lib/main.js b/packages/package-generator/lib/main.js new file mode 100644 index 000000000..0b59d38b1 --- /dev/null +++ b/packages/package-generator/lib/main.js @@ -0,0 +1,11 @@ +const PackageGeneratorView = require('./package-generator-view') + +module.exports = { + activate () { + this.view = new PackageGeneratorView() + }, + + deactivate () { + if (this.view) this.view.destroy() + } +} diff --git a/packages/package-generator/lib/package-generator-view.js b/packages/package-generator/lib/package-generator-view.js new file mode 100644 index 000000000..2a22caa02 --- /dev/null +++ b/packages/package-generator/lib/package-generator-view.js @@ -0,0 +1,149 @@ +const path = require('path') +const _ = require('underscore-plus') +const {TextEditor, BufferedProcess, CompositeDisposable, Disposable} = require('atom') +const fs = require('fs-plus') + +module.exports = +class PackageGeneratorView { + constructor () { + this.disposables = new CompositeDisposable() + + this.element = document.createElement('div') + this.element.classList.add('package-generator') + + this.miniEditor = new TextEditor({mini: true}) + this.element.appendChild(this.miniEditor.element) + + this.error = document.createElement('div') + this.error.classList.add('error') + this.element.appendChild(this.error) + + this.message = document.createElement('div') + this.message.classList.add('message') + this.element.appendChild(this.message) + + this.disposables.add(atom.commands.add('atom-workspace', { + 'package-generator:generate-package': () => this.attach('package'), + 'package-generator:generate-language-package': () => this.attach('language'), + 'package-generator:generate-syntax-theme': () => this.attach('theme') + })) + + const blurHandler = () => this.close() + this.miniEditor.element.addEventListener('blur', blurHandler) + this.disposables.add(new Disposable(() => this.miniEditor.element.removeEventListener('blur', blurHandler))) + this.disposables.add(atom.commands.add(this.element, { + 'core:confirm': () => this.confirm(), + 'core:cancel': () => this.close() + })) + } + + destroy () { + if (this.panel != null) this.panel.destroy() + this.disposables.dispose() + } + + attach (mode) { + this.mode = mode + if (this.panel == null) this.panel = atom.workspace.addModalPanel({item: this, visible: false}) + this.previouslyFocusedElement = document.activeElement + this.panel.show() + this.message.textContent = `Enter ${this.mode} path` + if (this.mode === 'package') { + this.setPathText('my-package') + } else if (this.mode === 'language') { + this.setPathText('language-my-language', [9, Infinity]) + } else { + this.setPathText('my-theme-syntax', [0, 8]) + } + this.miniEditor.element.focus() + } + + setPathText (placeholderName, rangeToSelect) { + if (rangeToSelect == null) rangeToSelect = [0, placeholderName.length] + const packagesDirectory = this.getPackagesDirectory() + this.miniEditor.setText(path.join(packagesDirectory, placeholderName)) + const pathLength = this.miniEditor.getText().length + const endOfDirectoryIndex = pathLength - placeholderName.length + this.miniEditor.setSelectedBufferRange([[0, endOfDirectoryIndex + rangeToSelect[0]], [0, endOfDirectoryIndex + rangeToSelect[1]]]) + } + + close () { + if (!this.panel.isVisible()) return + this.panel.hide() + if (this.previouslyFocusedElement != null) this.previouslyFocusedElement.focus() + } + + confirm () { + if (this.validPackagePath()) { + this.createPackageFiles(() => { + const packagePath = this.getPackagePath() + atom.open({pathsToOpen: [packagePath]}) + this.close() + }) + } + } + + getPackagePath () { + const packagePath = fs.normalize(this.miniEditor.getText().trim()) + const packageName = _.dasherize(path.basename(packagePath)) + return path.join(path.dirname(packagePath), packageName) + } + + getPackagesDirectory () { + return process.env.ATOM_REPOS_HOME || atom.config.get('core.projectHome') || path.join(fs.getHomeDirectory(), 'github') + } + + validPackagePath () { + if (fs.existsSync(this.getPackagePath())) { + this.error.textContent = `Path already exists at '${this.getPackagePath()}'` + this.error.style.display = 'block' + return false + } else { + return true + } + } + + getInitOptions (packagePath) { + const options = [`--${this.mode}`, packagePath] + if (this.mode !== 'theme') { + return [...options, '--syntax', atom.config.get('package-generator.packageSyntax')] + } else { + return options + } + } + + initPackage (packagePath, callback) { + const command = ['init'].concat(this.getInitOptions(packagePath)) + this.runCommand(atom.packages.getApmPath(), command, callback) + } + + linkPackage (packagePath, callback) { + const args = ['link'] + if (atom.config.get('package-generator.createInDevMode')) args.push('--dev') + args.push(packagePath.toString()) + + this.runCommand(atom.packages.getApmPath(), args, callback) + } + + isStoredInDotAtom (packagePath) { + const packagesPath = path.join(atom.getConfigDirPath(), 'packages', path.sep) + if (packagePath.startsWith(packagesPath)) return true + + const devPackagesPath = path.join(atom.getConfigDirPath(), 'dev', 'packages', path.sep) + return packagePath.startsWith(devPackagesPath) + } + + createPackageFiles (callback) { + const packagePath = this.getPackagePath() + + if (this.isStoredInDotAtom(packagePath)) { + this.initPackage(packagePath, callback) + } else { + this.initPackage(packagePath, () => this.linkPackage(packagePath, callback)) + } + } + + runCommand (command, args, exit) { + this.process = new BufferedProcess({command, args, exit}) + } +} diff --git a/packages/package-generator/menus/package-generator.cson b/packages/package-generator/menus/package-generator.cson new file mode 100644 index 000000000..882f6a1aa --- /dev/null +++ b/packages/package-generator/menus/package-generator.cson @@ -0,0 +1,10 @@ +'menu': [ + 'label': 'Packages' + 'submenu': [ + 'label': 'Package Generator' + 'submenu': [ + { 'label': 'Generate Atom Package', 'command': 'package-generator:generate-package' } + { 'label': 'Generate Atom Syntax Theme', 'command': 'package-generator:generate-syntax-theme' } + ] + ] +] diff --git a/packages/package-generator/package.json b/packages/package-generator/package.json new file mode 100644 index 000000000..0da345ef0 --- /dev/null +++ b/packages/package-generator/package.json @@ -0,0 +1,53 @@ +{ + "name": "package-generator", + "version": "1.3.0", + "main": "./lib/main", + "description": "Generates and opens a new sample package, language, or syntax theme.", + "license": "MIT", + "activationCommands": { + "atom-workspace": [ + "package-generator:generate-package", + "package-generator:generate-language-package", + "package-generator:generate-syntax-theme" + ] + }, + "dependencies": { + "fs-plus": "^3.0.0", + "temp": "^0.8.1", + "underscore-plus": "^1.0.0" + }, + "repository": "https://github.com/atom/package-generator", + "engines": { + "atom": "*" + }, + "devDependencies": { + "standard": "^10.0.3" + }, + "configSchema": { + "createInDevMode": { + "default": false, + "type": "boolean", + "description": "When disabled, generated packages are linked into Atom in both normal mode and dev mode. When enabled, generated packages are linked into Atom only in dev mode." + }, + "packageSyntax": { + "default": "javascript", + "type": "string", + "enum": [ + "coffeescript", + "javascript" + ], + "description": "The syntax to generate packages with." + } + }, + "standard": { + "env": { + "atomtest": true, + "browser": true, + "jasmine": true, + "node": true + }, + "globals": [ + "atom" + ] + } +} diff --git a/packages/package-generator/spec/async-spec-helpers.js b/packages/package-generator/spec/async-spec-helpers.js new file mode 100644 index 000000000..73002c049 --- /dev/null +++ b/packages/package-generator/spec/async-spec-helpers.js @@ -0,0 +1,103 @@ +/** @babel */ + +export function beforeEach (fn) { + global.beforeEach(function () { + const result = fn() + if (result instanceof Promise) { + waitsForPromise(() => result) + } + }) +} + +export function afterEach (fn) { + global.afterEach(function () { + const result = fn() + if (result instanceof Promise) { + waitsForPromise(() => result) + } + }) +} + +['it', 'fit', 'ffit', 'fffit'].forEach(function (name) { + module.exports[name] = function (description, fn) { + if (fn === undefined) { + global[name](description) + return + } + + global[name](description, function () { + const result = fn() + if (result instanceof Promise) { + waitsForPromise(() => result) + } + }) + } +}) + +export async function conditionPromise (condition, description = 'anonymous condition') { + const startTime = Date.now() + + while (true) { + await timeoutPromise(100) + + if (await condition()) { + return + } + + if (Date.now() - startTime > 5000) { + throw new Error('Timed out waiting on ' + description) + } + } +} + +export function timeoutPromise (timeout) { + return new Promise(function (resolve) { + global.setTimeout(resolve, timeout) + }) +} + +function waitsForPromise (fn) { + const promise = fn() + global.waitsFor('spec promise to resolve', function (done) { + promise.then(done, function (error) { + jasmine.getEnv().currentSpec.fail(error) + done() + }) + }) +} + +export function emitterEventPromise (emitter, event, timeout = 15000) { + return new Promise((resolve, reject) => { + const timeoutHandle = setTimeout(() => { + reject(new Error(`Timed out waiting for '${event}' event`)) + }, timeout) + emitter.once(event, () => { + clearTimeout(timeoutHandle) + resolve() + }) + }) +} + +export function promisify (original) { + return function (...args) { + return new Promise((resolve, reject) => { + args.push((err, ...results) => { + if (err) { + reject(err) + } else { + resolve(...results) + } + }) + + return original(...args) + }) + } +} + +export function promisifySome (obj, fnNames) { + const result = {} + for (const fnName of fnNames) { + result[fnName] = promisify(obj[fnName]) + } + return result +} diff --git a/packages/package-generator/spec/package-generator-spec.js b/packages/package-generator/spec/package-generator-spec.js new file mode 100644 index 000000000..c07ba921c --- /dev/null +++ b/packages/package-generator/spec/package-generator-spec.js @@ -0,0 +1,218 @@ +const path = require('path') +const fs = require('fs-plus') +const temp = require('temp') +const PackageGeneratorView = require('../lib/package-generator-view') + +const {it, fit, ffit, afterEach, beforeEach, conditionPromise} = require('./async-spec-helpers') // eslint-disable-line no-unused-vars + +describe('Package Generator', () => { + let packageGeneratorView = null + + const getWorkspaceView = () => atom.views.getView(atom.workspace) + + const typeToPackageNameMap = new Map([ + ['package', 'my-package'], + ['language', 'language-my-language'], + ['theme', 'my-theme-syntax'] + ]) + + const typeToSelectedTextMap = new Map([ + ['package', 'my-package'], + ['language', 'my-language'], + ['theme', 'my-theme'] + ]) + + beforeEach(async () => { + await atom.workspace.open('sample.js') + + packageGeneratorView = new PackageGeneratorView() + }) + + for (const [type, name] of typeToPackageNameMap) { + describe(`when generating a ${type}`, () => { + it('displays a mini-editor with the correct text and selection', () => { + packageGeneratorView.attach(type) + const editor = packageGeneratorView.miniEditor + expect(editor.getSelectedText()).toEqual(typeToSelectedTextMap.get(type)) + const base = atom.config.get('core.projectHome') + expect(editor.getText()).toEqual(path.join(base, name)) + }) + }) + } + + describe('when ATOM_REPOS_HOME is set', () => { + beforeEach(() => { + process.env.ATOM_REPOS_HOME = '/atom/repos/home' + }) + + afterEach(() => { + delete process.env.ATOM_REPOS_HOME + }) + + it('overrides the default path', () => { + packageGeneratorView.attach('package') + const editor = packageGeneratorView.miniEditor + expect(editor.getSelectedText()).toEqual('my-package') + const base = '/atom/repos/home' + expect(editor.getText()).toEqual(path.join(base, 'my-package')) + }) + }) + + describe('when the modal panel is canceled', () => { + it('detaches from the DOM and focuses the the previously focused element', () => { + jasmine.attachToDOM(getWorkspaceView()) + packageGeneratorView.attach('theme') + expect(packageGeneratorView.previouslyFocusedElement).not.toBeUndefined() + + expect(document.activeElement.closest('atom-text-editor')).toBe(packageGeneratorView.element.querySelector('atom-text-editor')) + + packageGeneratorView.close() + expect(atom.workspace.getModalPanels()[0].isVisible()).toBe(false) + expect(document.activeElement.closest('atom-text-editor')).toBe(atom.views.getView(atom.workspace.getActiveTextEditor())) + }) + }) + + describe('when a package is generated', () => { + let [packageName, packagePath, packageRoot] = [] + + const packageInitCommandFor = (path, type = 'package', syntax = atom.config.get('package-generator.packageSyntax')) => { + if (type !== 'theme') { + return ['init', `--${type}`, path, '--syntax', syntax] + } else { + return ['init', `--${type}`, path] + } + } + + beforeEach(() => { + spyOn(atom, 'open') + + packageRoot = temp.mkdirSync('atom') + packageName = 'sweet-package-dude' + packagePath = path.join(packageRoot, packageName) + fs.removeSync(packageRoot) + }) + + afterEach(() => fs.removeSync(packageRoot)) + + it("forces the package's name to be lowercase with dashes", () => { + packageName = 'CamelCaseIsForTheBirds' + packagePath = path.join(path.dirname(packagePath), packageName) + + packageGeneratorView.attach('package') + const editor = packageGeneratorView.miniEditor + editor.setText(packagePath) + const apmExecute = spyOn(packageGeneratorView, 'runCommand') + packageGeneratorView.confirm() + + expect(apmExecute).toHaveBeenCalled() + expect(apmExecute.mostRecentCall.args[0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.mostRecentCall.args[1]).toEqual(packageInitCommandFor(`${path.join(path.dirname(packagePath), 'camel-case-is-for-the-birds')}`)) + }) + + it("normalizes the package's path", () => { + packagePath = path.join('~', 'the-package') + + packageGeneratorView.attach('package') + const editor = packageGeneratorView.miniEditor + editor.setText(packagePath) + const apmExecute = spyOn(packageGeneratorView, 'runCommand') + packageGeneratorView.confirm() + + expect(apmExecute).toHaveBeenCalled() + expect(apmExecute.mostRecentCall.args[0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.mostRecentCall.args[1]).toEqual(packageInitCommandFor(`${fs.normalize(packagePath)}`)) + }) + + for (const type of typeToPackageNameMap.keys()) { + describe(`when creating a ${type}`, () => { + let apmExecute = null + + const generatePackage = async (insidePackagesDirectory) => { + const editor = packageGeneratorView.miniEditor + spyOn(packageGeneratorView, 'isStoredInDotAtom').andReturn(insidePackagesDirectory) + expect(packageGeneratorView.element.parentElement).toBeTruthy() + editor.setText(packagePath) + apmExecute = spyOn(packageGeneratorView, 'runCommand').andCallFake((command, args, exit) => process.nextTick(() => exit())) + packageGeneratorView.confirm() + await conditionPromise(() => atom.open.callCount === 1) + expect(atom.open).toHaveBeenCalledWith({pathsToOpen: [packagePath]}) + } + + beforeEach(() => { + jasmine.useRealClock() + jasmine.attachToDOM(getWorkspaceView()) + packageGeneratorView.attach(type) + }) + + describe(`when the ${type} is created outside of the packages directory`, () => { + describe('when package-generator.createInDevMode is set to false', () => { + it('calls `apm init` and `apm link`', async () => { + atom.config.set('package-generator.createInDevMode', false) + + await generatePackage(false) + expect(apmExecute.argsForCall[0][0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.argsForCall[0][1]).toEqual(packageInitCommandFor(`${packagePath}`, type)) + expect(apmExecute.argsForCall[1][0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.argsForCall[1][1]).toEqual(['link', `${packagePath}`]) + }) + }) + + describe('when package-generator.createInDevMode is set to true', () => { + it('calls `apm init` and `apm link --dev`', async () => { + atom.config.set('package-generator.createInDevMode', true) + + await generatePackage(false) + expect(apmExecute.argsForCall[0][0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.argsForCall[0][1]).toEqual(packageInitCommandFor(`${packagePath}`, type)) + expect(apmExecute.argsForCall[1][0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.argsForCall[1][1]).toEqual(['link', '--dev', `${packagePath}`]) + }) + }) + }) + + describe(`when the ${type} is created inside the packages directory`, () => { + it('calls `apm init`', async () => { + await generatePackage(true) + expect(apmExecute.argsForCall[0][0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.argsForCall[0][1]).toEqual(packageInitCommandFor(`${packagePath}`, type)) + expect(atom.open.argsForCall[0][0].pathsToOpen[0]).toBe(packagePath) + expect(apmExecute.argsForCall[1]).toBeUndefined() + }) + }) + + describe(`when the ${type} is a coffeescript package`, () => { + it('calls `apm init` with the correct syntax option', async () => { + atom.config.set('package-generator.packageSyntax', 'coffeescript') + await generatePackage(true) + expect(apmExecute.argsForCall[0][0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.argsForCall[0][1]).toEqual(packageInitCommandFor(`${packagePath}`, type, 'coffeescript')) + }) + }) + + describe(`when the ${type} is a javascript package`, () => { + it('calls `apm init` with the correct syntax option', async () => { + atom.config.set('package-generator.packageSyntax', 'javascript') + await generatePackage(true) + expect(apmExecute.argsForCall[0][0]).toBe(atom.packages.getApmPath()) + expect(apmExecute.argsForCall[0][1]).toEqual(packageInitCommandFor(`${packagePath}`, type, 'javascript')) + }) + }) + + describe(`when the ${type} path already exists`, () => { + it('displays an error', () => { + fs.makeTreeSync(packagePath) + + const editor = packageGeneratorView.miniEditor + editor.setText(packagePath) + expect(packageGeneratorView.element.parentElement).toBeTruthy() + expect(packageGeneratorView.element.querySelector('.error').offsetHeight).toBe(0) + + packageGeneratorView.confirm() + expect(packageGeneratorView.element.parentElement).toBeTruthy() + expect(packageGeneratorView.element.querySelector('.error').offsetHeight).not.toBe(0) + }) + }) + }) + } + }) +}) diff --git a/packages/package-generator/styles/package-generator.less b/packages/package-generator/styles/package-generator.less new file mode 100644 index 000000000..14dcf4d3c --- /dev/null +++ b/packages/package-generator/styles/package-generator.less @@ -0,0 +1,3 @@ +.package-generator .error { + display: none; +} diff --git a/yarn.lock b/yarn.lock index efeff9eca..148aa977a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7222,9 +7222,8 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -"package-generator@https://codeload.github.com/atom/package-generator/legacy.tar.gz/refs/tags/v1.3.0": +"package-generator@file:packages/package-generator": version "1.3.0" - resolved "https://codeload.github.com/atom/package-generator/legacy.tar.gz/refs/tags/v1.3.0#ddf15bc1e1a2539b2c4d16ede9ec0cd4cec868e2" dependencies: fs-plus "^3.0.0" temp "^0.8.1"