react-native-platform-override 0.0.0-canary.1016
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.
- package/README.md +105 -0
- package/bin.js +11 -0
- package/lib-commonjs/Api.d.ts +57 -0
- package/lib-commonjs/Api.js +188 -0
- package/lib-commonjs/Api.js.map +1 -0
- package/lib-commonjs/BatchingQueue.d.ts +15 -0
- package/lib-commonjs/BatchingQueue.js +58 -0
- package/lib-commonjs/BatchingQueue.js.map +1 -0
- package/lib-commonjs/Cli.d.ts +7 -0
- package/lib-commonjs/Cli.js +324 -0
- package/lib-commonjs/Cli.js.map +1 -0
- package/lib-commonjs/CrossProcessLock.d.ts +44 -0
- package/lib-commonjs/CrossProcessLock.js +148 -0
- package/lib-commonjs/CrossProcessLock.js.map +1 -0
- package/lib-commonjs/DiffStrategy.d.ts +24 -0
- package/lib-commonjs/DiffStrategy.js +35 -0
- package/lib-commonjs/DiffStrategy.js.map +1 -0
- package/lib-commonjs/FileRepository.d.ts +63 -0
- package/lib-commonjs/FileRepository.js +22 -0
- package/lib-commonjs/FileRepository.js.map +1 -0
- package/lib-commonjs/FileSearch.d.ts +21 -0
- package/lib-commonjs/FileSearch.js +78 -0
- package/lib-commonjs/FileSearch.js.map +1 -0
- package/lib-commonjs/FileSystemRepository.d.ts +21 -0
- package/lib-commonjs/FileSystemRepository.js +63 -0
- package/lib-commonjs/FileSystemRepository.js.map +1 -0
- package/lib-commonjs/GitReactFileRepository.d.ts +57 -0
- package/lib-commonjs/GitReactFileRepository.js +203 -0
- package/lib-commonjs/GitReactFileRepository.js.map +1 -0
- package/lib-commonjs/Hash.d.ts +34 -0
- package/lib-commonjs/Hash.js +82 -0
- package/lib-commonjs/Hash.js.map +1 -0
- package/lib-commonjs/Manifest.d.ts +80 -0
- package/lib-commonjs/Manifest.js +158 -0
- package/lib-commonjs/Manifest.js.map +1 -0
- package/lib-commonjs/Override.d.ts +182 -0
- package/lib-commonjs/Override.js +249 -0
- package/lib-commonjs/Override.js.map +1 -0
- package/lib-commonjs/OverrideFactory.d.ts +33 -0
- package/lib-commonjs/OverrideFactory.js +86 -0
- package/lib-commonjs/OverrideFactory.js.map +1 -0
- package/lib-commonjs/OverridePrompt.d.ts +30 -0
- package/lib-commonjs/OverridePrompt.js +131 -0
- package/lib-commonjs/OverridePrompt.js.map +1 -0
- package/lib-commonjs/PackageUtils.d.ts +15 -0
- package/lib-commonjs/PackageUtils.js +41 -0
- package/lib-commonjs/PackageUtils.js.map +1 -0
- package/lib-commonjs/PathUtils.d.ts +14 -0
- package/lib-commonjs/PathUtils.js +32 -0
- package/lib-commonjs/PathUtils.js.map +1 -0
- package/lib-commonjs/Serialized.d.ts +158 -0
- package/lib-commonjs/Serialized.js +146 -0
- package/lib-commonjs/Serialized.js.map +1 -0
- package/lib-commonjs/UpgradeStrategy.d.ts +39 -0
- package/lib-commonjs/UpgradeStrategy.js +103 -0
- package/lib-commonjs/UpgradeStrategy.js.map +1 -0
- package/lib-commonjs/ValidationStrategy.d.ts +57 -0
- package/lib-commonjs/ValidationStrategy.js +125 -0
- package/lib-commonjs/ValidationStrategy.js.map +1 -0
- package/lib-commonjs/refFromVersion.d.ts +10 -0
- package/lib-commonjs/refFromVersion.js +99 -0
- package/lib-commonjs/refFromVersion.js.map +1 -0
- package/lib-commonjs/scripts/generateManifest.d.ts +7 -0
- package/lib-commonjs/scripts/generateManifest.js +197 -0
- package/lib-commonjs/scripts/generateManifest.js.map +1 -0
- package/lib-commonjs/scripts/hashFile.d.ts +7 -0
- package/lib-commonjs/scripts/hashFile.js +18 -0
- package/lib-commonjs/scripts/hashFile.js.map +1 -0
- package/lib-commonjs/scripts/testLocks.d.ts +1 -0
- package/lib-commonjs/scripts/testLocks.js +30 -0
- package/lib-commonjs/scripts/testLocks.js.map +1 -0
- package/package.json +96 -0
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# react-native-platform-override
|
|
2
|
+
Tools to manage "platform overrides" for out of tree React Native platforms.
|
|
3
|
+
Facilities for inventorying changes and integrating new upstream changes are included.
|
|
4
|
+
|
|
5
|
+
## Override Manifests
|
|
6
|
+
|
|
7
|
+
`react-native-platform-override` operates on a JSON "override manifest" placed
|
|
8
|
+
at the root of an npm package. It is expected that these are named
|
|
9
|
+
`overrides.json`.
|
|
10
|
+
|
|
11
|
+
An example override manifest
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"includePatterns": [
|
|
15
|
+
"src/**"
|
|
16
|
+
],
|
|
17
|
+
"excludePatterns": [
|
|
18
|
+
"src/README.md"
|
|
19
|
+
],
|
|
20
|
+
"baseVersion": "0.0.0-10b4b9505",
|
|
21
|
+
"overrides": [
|
|
22
|
+
{
|
|
23
|
+
"type": "derived",
|
|
24
|
+
"file": ".flowconfig",
|
|
25
|
+
"baseFile": ".flowconfig",
|
|
26
|
+
"baseVersion": "0.0.0-56cf99a96",
|
|
27
|
+
"baseHash": "8eab29258f5ad573e478324f10f850b7ccfb49c7"
|
|
28
|
+
},
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
| Name | Required | Description | Default |
|
|
34
|
+
|-------------------|----------|-----------------------------------------------------------------|----------|
|
|
35
|
+
| `includePatterns` | Optional | A list of globs of files to enforce are listed in the manifest. | `["**"]` |
|
|
36
|
+
| `excludePatterns` | Optional | Globs to be excluded from the above list. | `[]` |
|
|
37
|
+
| `baseVersion` | Optional | The default react-native version of an override | |
|
|
38
|
+
| `overrides` | Required | List of registered overrides, added by the tooling | |
|
|
39
|
+
|
|
40
|
+
## Override Types
|
|
41
|
+
Overrides can be registered as different types, each with differing behavior.
|
|
42
|
+
|
|
43
|
+
| | |
|
|
44
|
+
|----------|------------------------------------------------------------------------------------------------------------------|
|
|
45
|
+
| Platform | Platform-specific logic that doesn't map to an upstream file |
|
|
46
|
+
| Derived | An override derived from an upstream file. Changes to the original file will be merged into the override. |
|
|
47
|
+
| Patch | An upstream file with changes made to it. Changes to the original file will be merged into the override. |
|
|
48
|
+
| Copy | An exact copy of an upstream file or directory. Overrides of this type will remain identical to their originals. |
|
|
49
|
+
|
|
50
|
+
## CLI
|
|
51
|
+
`react-native-platform-override` offers multiple commands to manipulate and verify the override manifest.
|
|
52
|
+
|
|
53
|
+
### `validate`
|
|
54
|
+
Verifies that overrides are recorded and up-to-date.
|
|
55
|
+
|
|
56
|
+
| Option | Required | Description | Default |
|
|
57
|
+
|---------------------|----------|----------------------------------------------------|---------------------------------|
|
|
58
|
+
| `--manifest <file>` | Optional | Path to an override manifest to validate | Package root above cwd |
|
|
59
|
+
| `--version <v>` | Optional | A version of React Native to check against | The currently installed version |
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### `add <override>`
|
|
63
|
+
Adds an override to the manifest, prompting for details.
|
|
64
|
+
|
|
65
|
+
| Option | Required | Description |
|
|
66
|
+
|-------------------|----------|---------------------------|
|
|
67
|
+
| `<override>` | Required | The override to add |
|
|
68
|
+
|
|
69
|
+
### `remove <override>`
|
|
70
|
+
Removes an override to the manifest.
|
|
71
|
+
|
|
72
|
+
| Option | Required | Description |
|
|
73
|
+
|-------------------|----------|---------------------------|
|
|
74
|
+
| `<override>` | Required | The override to remove |
|
|
75
|
+
|
|
76
|
+
### `upgrade`
|
|
77
|
+
Attempts to automatically merge new changes into out-of-date overrides.
|
|
78
|
+
|
|
79
|
+
| Option | Required | Description | Default |
|
|
80
|
+
|---------------------|----------|------------------------------------------------------------|---------------------------------|
|
|
81
|
+
| `--manifest <file>` | Optional | Path to an override manifest to validate | Package root above cwd |
|
|
82
|
+
| `--version <v>` | Optional | A version of React Native to check against | The currently installed version |
|
|
83
|
+
| `--no-conflicts` | Optional | Whether to allow upgraded files to contain conlict markers | `--conflicts` |
|
|
84
|
+
|
|
85
|
+
### `diff <override>`
|
|
86
|
+
Diffs an override against its base file. It it compared to the base file of the override's current version, even if a newer verison of
|
|
87
|
+
react-native is installed.
|
|
88
|
+
|
|
89
|
+
| Option | Required | Description | Default |
|
|
90
|
+
|------------------------|----------|----------------------------------------------------------------------------------------------------------------|---------|
|
|
91
|
+
| `<override>` | Required | The override to diff against | |
|
|
92
|
+
|
|
93
|
+
## GitHub Tokens
|
|
94
|
+
`react-native-platform-override` makes requests to GitHub's API. An OAuth token may optionally be provided by using the `--githubToken`
|
|
95
|
+
parameter or setting the PLATFORM_OVERRIDE_GITHUB_TOKEN environment variable.
|
|
96
|
+
|
|
97
|
+
## Programmatic Use
|
|
98
|
+
`react-native-platform-override` offers a programmatic API with similar capabilities to the CLI. Take a look [here](./src/APi.ts) for details.
|
|
99
|
+
|
|
100
|
+
E.g.
|
|
101
|
+
```js
|
|
102
|
+
import {validateManifest} from 'react-native-platform-override';
|
|
103
|
+
|
|
104
|
+
const validationErrors = await validateManifest({manifestPath: 'src/overrides.json'});
|
|
105
|
+
```
|
package/bin.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*
|
|
5
|
+
* @format
|
|
6
|
+
*/
|
|
7
|
+
import OverrideFactory from './OverrideFactory';
|
|
8
|
+
import Override from './Override';
|
|
9
|
+
import { UpgradeResult } from './UpgradeStrategy';
|
|
10
|
+
import { ValidationError } from './ValidationStrategy';
|
|
11
|
+
export * from './OverrideFactory';
|
|
12
|
+
export * from './Override';
|
|
13
|
+
export * from './refFromVersion';
|
|
14
|
+
export { UpgradeResult, ValidationError };
|
|
15
|
+
/**
|
|
16
|
+
* Check that the given manifest correctly describe overrides and that all
|
|
17
|
+
* overrides are up to date
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateManifest(manifestPath: string, opts?: {
|
|
20
|
+
reactNativeVersion?: string;
|
|
21
|
+
}): Promise<ValidationError[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Return whether the override exists in the manifest
|
|
24
|
+
*/
|
|
25
|
+
export declare function hasOverride(overrideName: string, manifestPath: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Removes an override from the manifest if it exists.
|
|
28
|
+
* @returns whether the override was removed
|
|
29
|
+
*/
|
|
30
|
+
export declare function removeOverride(overrideName: string, manifestPath: string): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Returns a factory to create overrides which may be added to the manifest
|
|
33
|
+
*/
|
|
34
|
+
export declare function getOverrideFactory(manifestPath: string, opts?: {
|
|
35
|
+
reactNativeVersion?: string;
|
|
36
|
+
}): Promise<OverrideFactory>;
|
|
37
|
+
/**
|
|
38
|
+
* Adds an override to the manifest
|
|
39
|
+
*/
|
|
40
|
+
export declare function addOverride(override: Override, manifestPath: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Outputs a patch-style diff of an override compared to its original source
|
|
43
|
+
*/
|
|
44
|
+
export declare function diffOverride(overrideName: string, manifestPath: string): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Receives notifications on progress during override upgrades
|
|
47
|
+
*/
|
|
48
|
+
export type UpgradeProgressListener = (currentOverride: number, totalOverrides: number) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Attempts to automatically merge changes from the current version into
|
|
51
|
+
* out-of-date overrides.
|
|
52
|
+
*/
|
|
53
|
+
export declare function upgradeOverrides(manifestPath: string, opts: {
|
|
54
|
+
allowConflicts: boolean;
|
|
55
|
+
reactNativeVersion?: string;
|
|
56
|
+
progressListener?: UpgradeProgressListener;
|
|
57
|
+
}): Promise<UpgradeResult[]>;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Microsoft Corporation.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*
|
|
6
|
+
* @format
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
25
|
+
if (mod && mod.__esModule) return mod;
|
|
26
|
+
var result = {};
|
|
27
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
28
|
+
__setModuleDefault(result, mod);
|
|
29
|
+
return result;
|
|
30
|
+
};
|
|
31
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
32
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.upgradeOverrides = exports.diffOverride = exports.addOverride = exports.getOverrideFactory = exports.removeOverride = exports.hasOverride = exports.validateManifest = void 0;
|
|
39
|
+
// Typings for "async" confuse this rule
|
|
40
|
+
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
41
|
+
const Serialized = __importStar(require("./Serialized"));
|
|
42
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
43
|
+
const fs_1 = __importDefault(require("@react-native-windows/fs"));
|
|
44
|
+
const path_1 = __importDefault(require("path"));
|
|
45
|
+
const OverrideFactory_1 = require("./OverrideFactory");
|
|
46
|
+
const FileRepository_1 = require("./FileRepository");
|
|
47
|
+
const async_1 = require("async");
|
|
48
|
+
const FileSystemRepository_1 = __importDefault(require("./FileSystemRepository"));
|
|
49
|
+
const GitReactFileRepository_1 = __importDefault(require("./GitReactFileRepository"));
|
|
50
|
+
const Manifest_1 = __importDefault(require("./Manifest"));
|
|
51
|
+
const PackageUtils_1 = require("./PackageUtils");
|
|
52
|
+
// Re-export types used in the public API so external packages don't have to
|
|
53
|
+
// reach into our guts to import them.
|
|
54
|
+
__exportStar(require("./OverrideFactory"), exports);
|
|
55
|
+
__exportStar(require("./Override"), exports);
|
|
56
|
+
__exportStar(require("./refFromVersion"), exports);
|
|
57
|
+
const MAX_CONCURRENT_TASKS = 30;
|
|
58
|
+
/**
|
|
59
|
+
* Check that the given manifest correctly describe overrides and that all
|
|
60
|
+
* overrides are up to date
|
|
61
|
+
*/
|
|
62
|
+
async function validateManifest(manifestPath, opts) {
|
|
63
|
+
const { manifest, overrideRepo, reactRepo } = await createManifestContext(manifestPath, opts);
|
|
64
|
+
return await manifest.validate(overrideRepo, reactRepo);
|
|
65
|
+
}
|
|
66
|
+
exports.validateManifest = validateManifest;
|
|
67
|
+
/**
|
|
68
|
+
* Return whether the override exists in the manifest
|
|
69
|
+
*/
|
|
70
|
+
async function hasOverride(overrideName, manifestPath) {
|
|
71
|
+
const { manifest } = await createManifestContext(manifestPath);
|
|
72
|
+
return manifest.hasOverride(overrideName);
|
|
73
|
+
}
|
|
74
|
+
exports.hasOverride = hasOverride;
|
|
75
|
+
/**
|
|
76
|
+
* Removes an override from the manifest if it exists.
|
|
77
|
+
* @returns whether the override was removed
|
|
78
|
+
*/
|
|
79
|
+
async function removeOverride(overrideName, manifestPath) {
|
|
80
|
+
const { manifest } = await createManifestContext(manifestPath);
|
|
81
|
+
const removed = manifest.removeOverride(overrideName);
|
|
82
|
+
if (removed) {
|
|
83
|
+
await Serialized.writeManifestToFile(manifest.serialize(), manifestPath);
|
|
84
|
+
}
|
|
85
|
+
return removed;
|
|
86
|
+
}
|
|
87
|
+
exports.removeOverride = removeOverride;
|
|
88
|
+
/**
|
|
89
|
+
* Returns a factory to create overrides which may be added to the manifest
|
|
90
|
+
*/
|
|
91
|
+
async function getOverrideFactory(manifestPath, opts) {
|
|
92
|
+
return (await createManifestContext(manifestPath, opts)).overrideFactory;
|
|
93
|
+
}
|
|
94
|
+
exports.getOverrideFactory = getOverrideFactory;
|
|
95
|
+
/**
|
|
96
|
+
* Adds an override to the manifest
|
|
97
|
+
*/
|
|
98
|
+
async function addOverride(override, manifestPath) {
|
|
99
|
+
const { manifest } = await createManifestContext(manifestPath);
|
|
100
|
+
manifest.addOverride(override);
|
|
101
|
+
await Serialized.writeManifestToFile(manifest.serialize(), manifestPath);
|
|
102
|
+
}
|
|
103
|
+
exports.addOverride = addOverride;
|
|
104
|
+
/**
|
|
105
|
+
* Outputs a patch-style diff of an override compared to its original source
|
|
106
|
+
*/
|
|
107
|
+
async function diffOverride(overrideName, manifestPath) {
|
|
108
|
+
const ctx = await createManifestContext(manifestPath);
|
|
109
|
+
const override = ctx.manifest.findOverride(overrideName);
|
|
110
|
+
if (!override) {
|
|
111
|
+
throw new Error(`Could not find override with name "${overrideName}"`);
|
|
112
|
+
}
|
|
113
|
+
return override.diffStrategy().diff(ctx.gitReactRepo, ctx.overrideRepo);
|
|
114
|
+
}
|
|
115
|
+
exports.diffOverride = diffOverride;
|
|
116
|
+
/**
|
|
117
|
+
* Attempts to automatically merge changes from the current version into
|
|
118
|
+
* out-of-date overrides.
|
|
119
|
+
*/
|
|
120
|
+
async function upgradeOverrides(manifestPath, opts) {
|
|
121
|
+
const ctx = await createManifestContext(manifestPath, opts);
|
|
122
|
+
const validationErrors = await ctx.manifest.validate(ctx.overrideRepo, ctx.reactRepo);
|
|
123
|
+
const outOfDateOverrides = validationErrors
|
|
124
|
+
.filter(err => err.type === 'outOfDate')
|
|
125
|
+
.map(err => ctx.manifest.findOverride(err.overrideName));
|
|
126
|
+
// Perform upgrades concurrently so we can take advantage of
|
|
127
|
+
// GitReactFileRepository optimizations when multiple requests are queued at
|
|
128
|
+
// once.
|
|
129
|
+
let i = 0;
|
|
130
|
+
const upgradeResults = await (0, async_1.mapLimit)(outOfDateOverrides, MAX_CONCURRENT_TASKS, async (override) => {
|
|
131
|
+
const upgradeResult = await override
|
|
132
|
+
.upgradeStrategy()
|
|
133
|
+
.upgrade(ctx.gitReactRepo, ctx.overrideRepo, ctx.reactNativeVersion, opts.allowConflicts);
|
|
134
|
+
if (opts.progressListener) {
|
|
135
|
+
opts.progressListener(++i, outOfDateOverrides.length);
|
|
136
|
+
}
|
|
137
|
+
return upgradeResult;
|
|
138
|
+
});
|
|
139
|
+
// Regenerate overrides that are already up to date to update the baseVersion
|
|
140
|
+
// to current. This helps to minimize the numbers of versions we have to
|
|
141
|
+
// check out for future upgrades.
|
|
142
|
+
const upToDateOverrides = [
|
|
143
|
+
...lodash_1.default.difference(ctx.manifest.listOverrides(), validationErrors.map(err => ctx.manifest.findOverride(err.overrideName))).map(ovr => ovr.name()),
|
|
144
|
+
...upgradeResults
|
|
145
|
+
.filter(res => res.filesWritten)
|
|
146
|
+
.map(res => res.overrideName),
|
|
147
|
+
];
|
|
148
|
+
await (0, async_1.eachLimit)(upToDateOverrides, MAX_CONCURRENT_TASKS, async (name) => {
|
|
149
|
+
await ctx.manifest.markUpToDate(name, ctx.overrideFactory);
|
|
150
|
+
});
|
|
151
|
+
ctx.manifest.setBaseVersion(ctx.reactNativeVersion);
|
|
152
|
+
await Serialized.writeManifestToFile(ctx.manifest.serialize(), manifestPath);
|
|
153
|
+
return upgradeResults.sort((a, b) => a.overrideName.localeCompare(b.overrideName, 'en'));
|
|
154
|
+
}
|
|
155
|
+
exports.upgradeOverrides = upgradeOverrides;
|
|
156
|
+
/**
|
|
157
|
+
* Throw if a file doesn't exist, printing an error message on the way
|
|
158
|
+
*/
|
|
159
|
+
async function checkFileExists(friendlyName, filePath) {
|
|
160
|
+
try {
|
|
161
|
+
await fs_1.default.access(filePath);
|
|
162
|
+
}
|
|
163
|
+
catch (ex) {
|
|
164
|
+
throw new Error(`Could not find ${friendlyName} at path '${filePath}'`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Sets up state for a manifest describing overrides at a specified RN version
|
|
169
|
+
*/
|
|
170
|
+
async function createManifestContext(manifestPath, opts) {
|
|
171
|
+
await checkFileExists('manifest', manifestPath);
|
|
172
|
+
const reactNativeVersion = (opts === null || opts === void 0 ? void 0 : opts.reactNativeVersion) || (await (0, PackageUtils_1.getInstalledRNVersion)());
|
|
173
|
+
const overrideDir = path_1.default.dirname(manifestPath);
|
|
174
|
+
const overrideRepo = new FileSystemRepository_1.default(overrideDir);
|
|
175
|
+
const gitReactRepo = await GitReactFileRepository_1.default.createAndInit();
|
|
176
|
+
const reactRepo = (0, FileRepository_1.bindVersion)(gitReactRepo, reactNativeVersion);
|
|
177
|
+
const overrideFactory = new OverrideFactory_1.OverrideFactoryImpl(reactRepo, overrideRepo);
|
|
178
|
+
const manifest = Manifest_1.default.fromSerialized(await Serialized.readManifestFromFile(manifestPath));
|
|
179
|
+
return {
|
|
180
|
+
overrideRepo,
|
|
181
|
+
reactRepo,
|
|
182
|
+
gitReactRepo,
|
|
183
|
+
overrideFactory,
|
|
184
|
+
manifest,
|
|
185
|
+
reactNativeVersion,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=Api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Api.js","sourceRoot":"","sources":["../src/Api.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n *\n * @format\n */\n\n// Typings for \"async\" confuse this rule\n/* eslint-disable @typescript-eslint/no-misused-promises */\n\nimport * as Serialized from './Serialized';\nimport _ from 'lodash';\nimport fs from '@react-native-windows/fs';\nimport path from 'path';\n\nimport OverrideFactory, {OverrideFactoryImpl} from './OverrideFactory';\nimport {\n ReactFileRepository,\n WritableFileRepository,\n bindVersion,\n} from './FileRepository';\nimport {eachLimit, mapLimit} from 'async';\nimport FileSystemRepository from './FileSystemRepository';\nimport GitReactFileRepository from './GitReactFileRepository';\nimport Manifest from './Manifest';\nimport Override from './Override';\nimport {UpgradeResult} from './UpgradeStrategy';\nimport {ValidationError} from './ValidationStrategy';\nimport {getInstalledRNVersion} from './PackageUtils';\n\n// Re-export types used in the public API so external packages don't have to\n// reach into our guts to import them.\nexport * from './OverrideFactory';\nexport * from './Override';\nexport * from './refFromVersion';\nexport {UpgradeResult, ValidationError};\n\nconst MAX_CONCURRENT_TASKS = 30;\n\n/**\n * Check that the given manifest correctly describe overrides and that all\n * overrides are up to date\n */\nexport async function validateManifest(\n manifestPath: string,\n opts?: {\n reactNativeVersion?: string;\n },\n): Promise<ValidationError[]> {\n const {manifest, overrideRepo, reactRepo} = await createManifestContext(\n manifestPath,\n opts,\n );\n return await manifest.validate(overrideRepo, reactRepo);\n}\n\n/**\n * Return whether the override exists in the manifest\n */\nexport async function hasOverride(\n overrideName: string,\n manifestPath: string,\n): Promise<boolean> {\n const {manifest} = await createManifestContext(manifestPath);\n return manifest.hasOverride(overrideName);\n}\n\n/**\n * Removes an override from the manifest if it exists.\n * @returns whether the override was removed\n */\nexport async function removeOverride(\n overrideName: string,\n manifestPath: string,\n): Promise<boolean> {\n const {manifest} = await createManifestContext(manifestPath);\n const removed = manifest.removeOverride(overrideName);\n if (removed) {\n await Serialized.writeManifestToFile(manifest.serialize(), manifestPath);\n }\n\n return removed;\n}\n\n/**\n * Returns a factory to create overrides which may be added to the manifest\n */\nexport async function getOverrideFactory(\n manifestPath: string,\n opts?: {\n reactNativeVersion?: string;\n },\n): Promise<OverrideFactory> {\n return (await createManifestContext(manifestPath, opts)).overrideFactory;\n}\n\n/**\n * Adds an override to the manifest\n */\nexport async function addOverride(\n override: Override,\n manifestPath: string,\n): Promise<void> {\n const {manifest} = await createManifestContext(manifestPath);\n manifest.addOverride(override);\n await Serialized.writeManifestToFile(manifest.serialize(), manifestPath);\n}\n\n/**\n * Outputs a patch-style diff of an override compared to its original source\n */\nexport async function diffOverride(\n overrideName: string,\n manifestPath: string,\n): Promise<string> {\n const ctx = await createManifestContext(manifestPath);\n\n const override = ctx.manifest.findOverride(overrideName);\n if (!override) {\n throw new Error(`Could not find override with name \"${overrideName}\"`);\n }\n\n return override.diffStrategy().diff(ctx.gitReactRepo, ctx.overrideRepo);\n}\n\n/**\n * Receives notifications on progress during override upgrades\n */\nexport type UpgradeProgressListener = (\n currentOverride: number,\n totalOverrides: number,\n) => void;\n\n/**\n * Attempts to automatically merge changes from the current version into\n * out-of-date overrides.\n */\nexport async function upgradeOverrides(\n manifestPath: string,\n opts: {\n allowConflicts: boolean;\n reactNativeVersion?: string;\n progressListener?: UpgradeProgressListener;\n },\n): Promise<UpgradeResult[]> {\n const ctx = await createManifestContext(manifestPath, opts);\n\n const validationErrors = await ctx.manifest.validate(\n ctx.overrideRepo,\n ctx.reactRepo,\n );\n\n const outOfDateOverrides = validationErrors\n .filter(err => err.type === 'outOfDate')\n .map(err => ctx.manifest.findOverride(err.overrideName)!);\n\n // Perform upgrades concurrently so we can take advantage of\n // GitReactFileRepository optimizations when multiple requests are queued at\n // once.\n let i = 0;\n const upgradeResults = await mapLimit<Override, UpgradeResult>(\n outOfDateOverrides,\n MAX_CONCURRENT_TASKS,\n async (override: any) => {\n const upgradeResult = await override\n .upgradeStrategy()\n .upgrade(\n ctx.gitReactRepo,\n ctx.overrideRepo,\n ctx.reactNativeVersion,\n opts.allowConflicts,\n );\n\n if (opts.progressListener) {\n opts.progressListener(++i, outOfDateOverrides.length);\n }\n\n return upgradeResult;\n },\n );\n\n // Regenerate overrides that are already up to date to update the baseVersion\n // to current. This helps to minimize the numbers of versions we have to\n // check out for future upgrades.\n const upToDateOverrides = [\n ..._.difference(\n ctx.manifest.listOverrides(),\n validationErrors.map(err => ctx.manifest.findOverride(err.overrideName)!),\n ).map(ovr => ovr.name()),\n\n ...upgradeResults\n .filter(res => res.filesWritten)\n .map(res => res.overrideName),\n ];\n\n await eachLimit(upToDateOverrides, MAX_CONCURRENT_TASKS, async name => {\n await ctx.manifest.markUpToDate(name, ctx.overrideFactory);\n });\n\n ctx.manifest.setBaseVersion(ctx.reactNativeVersion);\n await Serialized.writeManifestToFile(ctx.manifest.serialize(), manifestPath);\n\n return upgradeResults.sort((a, b) =>\n a.overrideName.localeCompare(b.overrideName, 'en'),\n );\n}\n\n/**\n * Throw if a file doesn't exist, printing an error message on the way\n */\nasync function checkFileExists(friendlyName: string, filePath: string) {\n try {\n await fs.access(filePath);\n } catch (ex) {\n throw new Error(`Could not find ${friendlyName} at path '${filePath}'`);\n }\n}\n\n/**\n * Context describing state centered around a single manifest\n */\ninterface ManifestContext {\n overrideRepo: WritableFileRepository;\n reactRepo: ReactFileRepository;\n gitReactRepo: GitReactFileRepository;\n overrideFactory: OverrideFactory;\n manifest: Manifest;\n reactNativeVersion: string;\n}\n\n/**\n * Sets up state for a manifest describing overrides at a specified RN version\n */\nasync function createManifestContext(\n manifestPath: string,\n opts?: {\n reactNativeVersion?: string;\n },\n): Promise<ManifestContext> {\n await checkFileExists('manifest', manifestPath);\n const reactNativeVersion =\n opts?.reactNativeVersion || (await getInstalledRNVersion());\n\n const overrideDir = path.dirname(manifestPath);\n const overrideRepo = new FileSystemRepository(overrideDir);\n\n const gitReactRepo = await GitReactFileRepository.createAndInit();\n const reactRepo = bindVersion(gitReactRepo, reactNativeVersion);\n\n const overrideFactory = new OverrideFactoryImpl(reactRepo, overrideRepo);\n const manifest = Manifest.fromSerialized(\n await Serialized.readManifestFromFile(manifestPath),\n );\n\n return {\n overrideRepo,\n reactRepo,\n gitReactRepo,\n overrideFactory,\n manifest,\n reactNativeVersion,\n };\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*
|
|
5
|
+
* @format
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Executes actions, attempting to group by a given key
|
|
9
|
+
*/
|
|
10
|
+
export default class BatchingQueue<TKey> {
|
|
11
|
+
private readonly keyedQueues;
|
|
12
|
+
private currentKey?;
|
|
13
|
+
enqueue<T>(key: TKey, action: () => Promise<T>): Promise<T>;
|
|
14
|
+
private pumpQueue;
|
|
15
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Microsoft Corporation.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*
|
|
6
|
+
* @format
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
/**
|
|
10
|
+
* Executes actions, attempting to group by a given key
|
|
11
|
+
*/
|
|
12
|
+
class BatchingQueue {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.keyedQueues = new Map();
|
|
15
|
+
}
|
|
16
|
+
enqueue(key, action) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
if (!this.keyedQueues.has(key)) {
|
|
19
|
+
this.keyedQueues.set(key, []);
|
|
20
|
+
}
|
|
21
|
+
this.keyedQueues.get(key).push(async () => {
|
|
22
|
+
try {
|
|
23
|
+
resolve(await action());
|
|
24
|
+
}
|
|
25
|
+
catch (ex) {
|
|
26
|
+
reject(ex);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
if (!this.currentKey) {
|
|
30
|
+
this.currentKey = key;
|
|
31
|
+
void this.pumpQueue();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async pumpQueue() {
|
|
36
|
+
const currentQueue = this.keyedQueues.get(this.currentKey);
|
|
37
|
+
while (currentQueue.length > 0) {
|
|
38
|
+
await currentQueue.shift()();
|
|
39
|
+
}
|
|
40
|
+
this.keyedQueues.delete(this.currentKey);
|
|
41
|
+
this.currentKey = undefined;
|
|
42
|
+
// If we have more batches, pick the next greedily based on size
|
|
43
|
+
if (this.keyedQueues.size > 0) {
|
|
44
|
+
let nextKey;
|
|
45
|
+
let maxLength = 0;
|
|
46
|
+
this.keyedQueues.forEach((queue, key) => {
|
|
47
|
+
if (queue.length > maxLength) {
|
|
48
|
+
maxLength = queue.length;
|
|
49
|
+
nextKey = key;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
this.currentKey = nextKey;
|
|
53
|
+
return this.pumpQueue();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.default = BatchingQueue;
|
|
58
|
+
//# sourceMappingURL=BatchingQueue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BatchingQueue.js","sourceRoot":"","sources":["../src/BatchingQueue.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAEH;;GAEG;AACH,MAAqB,aAAa;IAAlC;QACmB,gBAAW,GAC1B,IAAI,GAAG,EAAE,CAAC;IAiDd,CAAC;IA9CC,OAAO,CAAI,GAAS,EAAE,MAAwB;QAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAC9B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;aAC/B;YAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBACzC,IAAI;oBACF,OAAO,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC;iBACzB;gBAAC,OAAO,EAAE,EAAE;oBACX,MAAM,CAAC,EAAE,CAAC,CAAC;iBACZ;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBACpB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;gBACtB,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;aACvB;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,UAAW,CAAE,CAAC;QAE7D,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;YAC9B,MAAM,YAAY,CAAC,KAAK,EAAG,EAAE,CAAC;SAC/B;QAED,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,UAAW,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAE5B,gEAAgE;QAChE,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE;YAC7B,IAAI,OAAyB,CAAC;YAC9B,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBACtC,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE;oBAC5B,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;oBACzB,OAAO,GAAG,GAAG,CAAC;iBACf;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC;YAC1B,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;SACzB;IACH,CAAC;CACF;AAnDD,gCAmDC","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n *\n * @format\n */\n\n/**\n * Executes actions, attempting to group by a given key\n */\nexport default class BatchingQueue<TKey> {\n private readonly keyedQueues: Map<TKey, Array<() => Promise<void>>> =\n new Map();\n private currentKey?: TKey;\n\n enqueue<T>(key: TKey, action: () => Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n if (!this.keyedQueues.has(key)) {\n this.keyedQueues.set(key, []);\n }\n\n this.keyedQueues.get(key)!.push(async () => {\n try {\n resolve(await action());\n } catch (ex) {\n reject(ex);\n }\n });\n\n if (!this.currentKey) {\n this.currentKey = key;\n void this.pumpQueue();\n }\n });\n }\n\n private async pumpQueue(): Promise<void> {\n const currentQueue = this.keyedQueues.get(this.currentKey!)!;\n\n while (currentQueue.length > 0) {\n await currentQueue.shift()!();\n }\n\n this.keyedQueues.delete(this.currentKey!);\n this.currentKey = undefined;\n\n // If we have more batches, pick the next greedily based on size\n if (this.keyedQueues.size > 0) {\n let nextKey: TKey | undefined;\n let maxLength = 0;\n this.keyedQueues.forEach((queue, key) => {\n if (queue.length > maxLength) {\n maxLength = queue.length;\n nextKey = key;\n }\n });\n\n this.currentKey = nextKey;\n return this.pumpQueue();\n }\n }\n}\n"]}
|