-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# Thanks for opening a Pull Request ## Changes Please outline the reason for the changes you are making: This PR adds the ability to output the scripts in a `depcache` format that's usable with single SPA / systemjs implementations [Change description here] Are there any breaking changes you are aware of in the PR? Not directly. Updating arborist a major version, but its downstream change removed node versions we already didn't support. ## General Checklist * [x] Change is tested locally * [x] Demo is updated to exercise change (if applicable) * [x] [WIP] flag is removed from the title [1]:https://docs.npmjs.com/about-semantic-versioning [2]:https://docs.npmjs.com/cli/deprecate [3]:https://github.com/meltwater/applet-orchard/blob/master/docs/README.md
- Loading branch information
1 parent
6594829
commit 392d5fb
Showing
12 changed files
with
1,734 additions
and
1,766 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import ac from 'argument-contracts'; | ||
import { checkForRequiredInitialization } from '../build-app-output/check-for-required-initialization'; | ||
import { CliOptions, DO_NOT_INJECT } from '../cli-options'; | ||
import fs from 'fs'; | ||
import { getDependencyPackages } from '../build-app-output/get-dependency-packages'; | ||
import { Logger } from '../logger'; | ||
import path from 'path'; | ||
import { readPackageDependencies } from '../build-app-output/read-package-dependencies'; | ||
import { rollupLatestMajorVersions } from '../build-app-output/rollup-latest-major-versions'; | ||
import { throwForConflictingMajorVersions } from '../build-app-output/throw-for-conflicting-major-versions'; | ||
import { throwIfZerothLevelDepNotHighestMajorVersion } from '../build-app-output/throw-if-zeroth-level-dep-not-highest-major-version'; | ||
import { buildDependencyArray } from '../build-app-output/build-dependency-array'; | ||
import { pareDownToKnownPackages } from '../build-app-output/pare-down-to-known-packages'; | ||
import { adjustOrderBasedOnChildDependencies } from '../build-app-output/adjust-order-based-on-child-dependencies'; | ||
import { resolveRequiredDependencyScripts } from './resolve-required-dependency-scripts'; | ||
|
||
const currentWorkingDirectory = process.cwd(); | ||
|
||
export async function buildDepcacheOutput(cliOptions) { | ||
ac.assertType(cliOptions, CliOptions, 'cliOptions'); | ||
|
||
Logger.setLoggingLevel(cliOptions.logging); | ||
Logger.debug(`buildDepcacheOutput: cliOptions: ${JSON.stringify(cliOptions)}`); | ||
|
||
const dependencies = readPackageDependencies(path.join(currentWorkingDirectory, cliOptions.pathToPackageJson)); | ||
Logger.debug('dependencies', JSON.stringify(dependencies, null, 2)); | ||
|
||
const dependencyMap = await getDependencyPackages(cliOptions.dependencyDirectory); | ||
Logger.debug('dependencyMap', JSON.stringify(dependencyMap, null, 2)); | ||
|
||
const npmDependenciesWithChildDependencies = await buildDependencyArray({ | ||
currentWorkingDirectory, | ||
pathToPackageJson: cliOptions.pathToPackageJson | ||
}); | ||
|
||
const paredDownToKnownPackages = pareDownToKnownPackages({ | ||
dependencyMap, | ||
npmDependenciesWithChildDependencies | ||
}); | ||
|
||
Logger.debug('paredDownToKnownPackages', paredDownToKnownPackages); | ||
|
||
const dependenciesReadyForRollup = paredDownToKnownPackages; | ||
|
||
const rolledUpDeps = rollupLatestMajorVersions(dependenciesReadyForRollup); | ||
throwForConflictingMajorVersions({ dependencies: rolledUpDeps, dependencyMap }); | ||
throwIfZerothLevelDepNotHighestMajorVersion(rolledUpDeps); | ||
checkForRequiredInitialization({ dependencies: rolledUpDeps, dependencyMap }); | ||
|
||
const orderedDependencies = adjustOrderBasedOnChildDependencies({ | ||
npmDependenciesWithChildDependencies: rolledUpDeps | ||
}); | ||
|
||
const dependencyScripts = resolveRequiredDependencyScripts({ | ||
dependencies: orderedDependencies, | ||
dependencyMap: { | ||
...dependencyMap | ||
} | ||
}); | ||
|
||
const output = [ | ||
...dependencyScripts | ||
]; | ||
|
||
if (cliOptions.injectFile && cliOptions.injectFile !== DO_NOT_INJECT) { | ||
const fileContentToInjectInto = fs.readFileSync(cliOptions.injectFile, { encoding: 'utf8' }); | ||
const updatedFileContent = fileContentToInjectInto.replace(cliOptions.orchardInjectString, JSON.stringify(output, null, 2)); | ||
fs.writeFileSync(cliOptions.outputFile, updatedFileContent); | ||
} else { | ||
fs.writeFileSync(cliOptions.outputFile, JSON.stringify(output, null, 2)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
import ac from 'argument-contracts'; | ||
import * as AdjustOrderBasedOnChildDependenciesModule from '../build-app-output/adjust-order-based-on-child-dependencies'; | ||
import * as CheckForRequiredInitializationModule from '../build-app-output/check-for-required-initialization'; | ||
import { CliOptions } from '../cli-options'; | ||
import fs from 'fs'; | ||
import * as BuildDependencyArrayModule from '../build-app-output/build-dependency-array'; | ||
import * as GetDependencyPackagesModule from '../build-app-output/get-dependency-packages'; | ||
import { Logger } from '../logger'; | ||
import * as PareDownToKnownPackagesModule from '../build-app-output/pare-down-to-known-packages'; | ||
import path from 'path'; | ||
import * as ReadPackageDependenciesModule from '../build-app-output/read-package-dependencies'; | ||
import * as ResolveRequiredDependencyScriptsModule from './resolve-required-dependency-scripts'; | ||
import * as RollupLatestMajorVersionsModule from '../build-app-output/rollup-latest-major-versions'; | ||
import * as ThrowForConflictingMajorVersionsModule from '../build-app-output/throw-for-conflicting-major-versions'; | ||
import * as ThrowIfZerothLevelDepNotHighestMajorVersionModule from '../build-app-output/throw-if-zeroth-level-dep-not-highest-major-version'; | ||
|
||
import { buildDepcacheOutput } from './index'; | ||
|
||
describe('build depcache output', () => { | ||
let cliOptions; | ||
|
||
beforeEach(() => { | ||
|
||
spyOn(ac, 'assertType'); | ||
spyOn(AdjustOrderBasedOnChildDependenciesModule, 'adjustOrderBasedOnChildDependencies').and.returnValue([]); | ||
spyOn(CheckForRequiredInitializationModule, 'checkForRequiredInitialization'); | ||
spyOn(fs, 'writeFileSync'); | ||
spyOn(BuildDependencyArrayModule, 'buildDependencyArray').and.resolveTo([]); | ||
spyOn(GetDependencyPackagesModule, 'getDependencyPackages').and.resolveTo([]); | ||
spyOn(Logger, 'setLoggingLevel'); | ||
spyOn(PareDownToKnownPackagesModule, 'pareDownToKnownPackages').and.returnValue([]); | ||
spyOn(ReadPackageDependenciesModule, 'readPackageDependencies'); | ||
spyOn(ResolveRequiredDependencyScriptsModule, 'resolveRequiredDependencyScripts').and.returnValue([]); | ||
spyOn(RollupLatestMajorVersionsModule, 'rollupLatestMajorVersions').and.returnValue([]); | ||
spyOn(ThrowForConflictingMajorVersionsModule, 'throwForConflictingMajorVersions'); | ||
spyOn(ThrowIfZerothLevelDepNotHighestMajorVersionModule, 'throwIfZerothLevelDepNotHighestMajorVersion'); | ||
spyOn(Logger, 'debug'); | ||
|
||
cliOptions = new CliOptions({ | ||
excludeDirectDependencies: false, | ||
dependencyDirectory: 'her/there/everywhere', | ||
openFileLimit: 4, | ||
orchardInjectString: '<!-- wat -->', | ||
outputFile: 'plumbus.html', | ||
retryOpenFileSleepDuration: 10, | ||
outputDepcache: true | ||
}); | ||
}); | ||
|
||
it('should assert cliOptions is CliOptions', async () => { | ||
await buildDepcacheOutput(cliOptions); | ||
|
||
expect(ac.assertType).toHaveBeenCalledWith(cliOptions, CliOptions, 'cliOptions'); | ||
}); | ||
|
||
it('should set logging level from cliOptions', async () => { | ||
const logging = 'complete deforestation'; | ||
await buildDepcacheOutput({ | ||
...cliOptions, | ||
logging | ||
}); | ||
|
||
expect(Logger.setLoggingLevel).toHaveBeenCalledWith(logging); | ||
}); | ||
|
||
it('should read package.json dependencies from cliOptions', async () => { | ||
const pathToPackageJson = 'go/here/for/package.json'; | ||
await buildDepcacheOutput({ | ||
...cliOptions, | ||
pathToPackageJson | ||
}); | ||
|
||
expect(ReadPackageDependenciesModule.readPackageDependencies).toHaveBeenCalledWith(path.join(process.cwd(), pathToPackageJson)); | ||
}); | ||
|
||
it('should get array of dependencies', async () => { | ||
const openFileLimit = 'twenty'; | ||
const retryOpenFileSleepDuration = '1 siesta'; | ||
|
||
await buildDepcacheOutput({ | ||
...cliOptions, | ||
openFileLimit, | ||
retryOpenFileSleepDuration | ||
}); | ||
|
||
expect(BuildDependencyArrayModule.buildDependencyArray).toHaveBeenCalledWith(jasmine.objectContaining({ | ||
currentWorkingDirectory: jasmine.any(String), | ||
pathToPackageJson: cliOptions.pathToPackageJson | ||
})); | ||
}); | ||
|
||
it('should rollup major versions', async () => { | ||
const packageDependencies = [1, 2, 3]; | ||
PareDownToKnownPackagesModule.pareDownToKnownPackages.and.returnValue(packageDependencies); | ||
|
||
await buildDepcacheOutput(cliOptions); | ||
|
||
expect(RollupLatestMajorVersionsModule.rollupLatestMajorVersions).toHaveBeenCalledWith(packageDependencies); | ||
}); | ||
|
||
it('should check for package major version conflicts', async () => { | ||
const dependencyMap = { yes: 'maybe..... no' }; | ||
const packageDependencies = [1, 2, 3]; | ||
GetDependencyPackagesModule.getDependencyPackages.and.resolveTo(dependencyMap); | ||
RollupLatestMajorVersionsModule.rollupLatestMajorVersions.and.returnValue(packageDependencies); | ||
|
||
await buildDepcacheOutput(cliOptions); | ||
|
||
expect(ThrowForConflictingMajorVersionsModule.throwForConflictingMajorVersions).toHaveBeenCalledWith({ | ||
dependencies: packageDependencies, | ||
dependencyMap | ||
}); | ||
}); | ||
|
||
it('should check for required initializations', async () => { | ||
const dependencyMap = { yes: 'maybe..... no' }; | ||
const packageDependencies = [3, 2, 1]; | ||
GetDependencyPackagesModule.getDependencyPackages.and.resolveTo(dependencyMap); | ||
RollupLatestMajorVersionsModule.rollupLatestMajorVersions.and.returnValue(packageDependencies); | ||
|
||
await buildDepcacheOutput(cliOptions); | ||
|
||
expect(CheckForRequiredInitializationModule.checkForRequiredInitialization).toHaveBeenCalledWith({ dependencies: packageDependencies, dependencyMap }); | ||
}); | ||
|
||
it('should checkout for package 0 level dependency not major version issues', async () => { | ||
const dependencyMap = { yes: 'maybe..... no' }; | ||
const packageDependencies = [1, 2, 3]; | ||
GetDependencyPackagesModule.getDependencyPackages.and.resolveTo(dependencyMap); | ||
RollupLatestMajorVersionsModule.rollupLatestMajorVersions.and.returnValue(packageDependencies); | ||
|
||
await buildDepcacheOutput(cliOptions); | ||
|
||
expect(ThrowIfZerothLevelDepNotHighestMajorVersionModule.throwIfZerothLevelDepNotHighestMajorVersion).toHaveBeenCalledWith(packageDependencies); | ||
}); | ||
|
||
it('should resolve dependency scripts', async () => { | ||
const dependencyMap = { all: 'The things!' }; | ||
GetDependencyPackagesModule.getDependencyPackages.and.resolveTo(dependencyMap); | ||
|
||
await buildDepcacheOutput(cliOptions); | ||
|
||
expect(ResolveRequiredDependencyScriptsModule.resolveRequiredDependencyScripts).toHaveBeenCalledWith(jasmine.objectContaining({ | ||
dependencyMap: jasmine.objectContaining(dependencyMap) | ||
})); | ||
}); | ||
|
||
it('should resolve dependency tree', async () => { | ||
const packageDependencies = [1, 2, 3]; | ||
AdjustOrderBasedOnChildDependenciesModule.adjustOrderBasedOnChildDependencies.and.returnValue(packageDependencies); | ||
|
||
await buildDepcacheOutput(cliOptions); | ||
|
||
expect(ResolveRequiredDependencyScriptsModule.resolveRequiredDependencyScripts).toHaveBeenCalledWith(jasmine.objectContaining({ | ||
dependencies: packageDependencies | ||
})); | ||
}); | ||
|
||
describe('injection handling', () => { | ||
beforeEach(() => { | ||
spyOn(fs, 'readFileSync'); | ||
}); | ||
|
||
it('should read file to inject to', async () => { | ||
const injectFile = 'inject/file/location.txt'; | ||
fs.readFileSync.and.returnValue(''); | ||
|
||
await buildDepcacheOutput({ | ||
...cliOptions, | ||
injectFile | ||
}); | ||
|
||
expect(fs.readFileSync).toHaveBeenCalledWith(injectFile, { encoding: 'utf8' }); | ||
}); | ||
|
||
it('should inject output into the file', async () => { | ||
const orchardInjectString = 'watwatwatwatwat'; | ||
const outputFile = 'The best output'; | ||
const beforeInjectionLocation = 'This file has been injected into!'; | ||
const afterInjectionLocation = 'YEAH BOIIIIIIIIIII!'; | ||
const fileContent = `${beforeInjectionLocation}${orchardInjectString}${afterInjectionLocation}`; | ||
const output = 'The greatest output Evar'; | ||
fs.readFileSync.and.returnValue(fileContent); | ||
ResolveRequiredDependencyScriptsModule.resolveRequiredDependencyScripts.and.returnValue([output]) | ||
|
||
await buildDepcacheOutput({ | ||
...cliOptions, | ||
injectFile: 'yarp.txt', | ||
orchardInjectString, | ||
outputFile | ||
}); | ||
|
||
|
||
expect(fs.writeFileSync).toHaveBeenCalledWith(outputFile, jasmine.stringMatching(beforeInjectionLocation)); | ||
expect(fs.writeFileSync).toHaveBeenCalledWith(outputFile, jasmine.stringMatching(output)); | ||
expect(fs.writeFileSync).toHaveBeenCalledWith(outputFile, jasmine.stringMatching(afterInjectionLocation)); | ||
}); | ||
}); | ||
|
||
it('should output tags array', async () => { | ||
const outputFile = 'The best output'; | ||
|
||
const dependencyOutput = 'AW YEAH!'; | ||
ResolveRequiredDependencyScriptsModule.resolveRequiredDependencyScripts.and.returnValue([dependencyOutput]) | ||
|
||
await buildDepcacheOutput({ | ||
...cliOptions, | ||
outputFile | ||
}); | ||
|
||
expect(fs.writeFileSync).toHaveBeenCalledWith(outputFile, jasmine.stringMatching(dependencyOutput)); | ||
}); | ||
}); |
31 changes: 31 additions & 0 deletions
31
src/build-depcache-output/resolve-required-dependency-scripts/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import ac from 'argument-contracts'; | ||
import { ExternalPackageEntry } from '../../external-package-entry'; | ||
import { Logger } from '../../logger'; | ||
|
||
function getScripts({ externalPackageEntry, version }) { | ||
ac.assertType(externalPackageEntry, ExternalPackageEntry, 'externalPackageEntry'); | ||
ac.assertString(version, 'version'); | ||
|
||
Logger.info(`Creating scripts for ${externalPackageEntry.packageName}`); | ||
|
||
return externalPackageEntry.getEsmUrls(version); | ||
} | ||
|
||
export function resolveRequiredDependencyScripts({ dependencies, dependencyMap }) { | ||
ac.assertType(dependencies, Object, 'dependencies'); | ||
ac.assertType(dependencyMap, Object, 'dependencyMap'); | ||
|
||
const dependencyScripts = dependencies.reduce((scriptsArray, dependency) => { | ||
if (dependencyMap[dependency.packageName]) { | ||
const scripts = getScripts({ | ||
externalPackageEntry: dependencyMap[dependency.packageName], | ||
version: dependency.version | ||
}); | ||
|
||
return scriptsArray.concat(scripts); | ||
} | ||
return scriptsArray; | ||
}, []); | ||
|
||
return dependencyScripts; | ||
} |
Oops, something went wrong.