Skip to content

Commit 2aa32ac

Browse files
committed
Perf testing...
See #1819, #1840.
1 parent 518331e commit 2aa32ac

1 file changed

Lines changed: 144 additions & 0 deletions

File tree

‎src/test/dart_only/perf.test.ts‎

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import * as fs from "fs";
2+
import * as path from "path";
3+
import { FLUTTER_CREATE_PROJECT_TRIGGER_FILE, FLUTTER_STAGEHAND_PROJECT_TRIGGER_FILE } from "../../shared/constants";
4+
import { flatMap } from "../../shared/utils";
5+
import { sortBy } from "../../shared/utils/array";
6+
import { findProjectFolders } from "../../shared/utils/fs";
7+
import glob = require("glob");
8+
9+
describe.only("perf", () => {
10+
it("should be fast", async () => {
11+
const searchLocations = [
12+
"/Users/dantup/Desktop/monorepo_test_1",
13+
"/Users/dantup/Desktop/monorepo_test_2",
14+
"/Users/dantup/Desktop/monorepo_test_3",
15+
"/Users/dantup/Desktop/monorepo_test_4",
16+
"/Users/dantup/Desktop/monorepo_test_5",
17+
];
18+
19+
async function run(name: string, f: (locs: string[]) => string[] | Promise<string[]>): Promise<void> {
20+
const startTime = Date.now();
21+
const projects = await f(searchLocations);
22+
const endTime = Date.now();
23+
24+
console.log(`${name}: ${endTime - startTime}ms (${projects.length} projects)`);
25+
}
26+
27+
await run("Orig", findProjectFolders);
28+
await run("WithoutExists", findProjectFoldersWithoutExists);
29+
await run("Async", findProjectFoldersAsync);
30+
await run("Glob", findProjectFoldersGlob);
31+
await run("GlobSync", findProjectFoldersGlobSync);
32+
});
33+
});
34+
35+
function findProjectFoldersWithoutExists(roots: string[], options: { sort?: boolean, requirePubspec?: boolean } = {}): string[] {
36+
const level2Folders = flatMap(roots, getChildFolders);
37+
const level3Folders = flatMap(level2Folders, getChildFolders);
38+
const allPossibleFolders = roots.concat(level2Folders).concat(level3Folders);
39+
40+
const projectFolders = allPossibleFolders.filter((f) => {
41+
return options && options.requirePubspec
42+
? hasPubspec(f)
43+
: hasPubspec(f) || hasCreateTriggerFile(f) || isFlutterRepo(f);
44+
});
45+
return options && options.sort
46+
? sortBy(projectFolders, (p) => p.toLowerCase())
47+
: projectFolders;
48+
}
49+
50+
async function findProjectFoldersAsync(roots: string[], options: { sort?: boolean, requirePubspec?: boolean } = {}): Promise<string[]> {
51+
const level2Folders = await flatMap(await Promise.all(roots.map(getChildFoldersAsync)), (x) => x);
52+
const level3Folders = await flatMap(await Promise.all(level2Folders.map(getChildFoldersAsync)), (x) => x);
53+
const allPossibleFolders = roots.concat(level2Folders).concat(level3Folders);
54+
55+
const projectFolders: string[] = [];
56+
await Promise.all(allPossibleFolders.map(async (f) => {
57+
const matches = await Promise.all([hasPubspecAsync(f), hasCreateTriggerFileAsync(f), isFlutterRepoAsync(f)]);
58+
if (matches.indexOf(true) !== -1)
59+
projectFolders.push(f);
60+
}));
61+
return projectFolders;
62+
}
63+
64+
async function findProjectFoldersGlob(roots: string[], options: { sort?: boolean, requirePubspec?: boolean } = {}): Promise<string[]> {
65+
const results = await Promise.all(roots.map(findProjectsGlob));
66+
return flatMap(results, (x) => x);
67+
}
68+
69+
function findProjectFoldersGlobSync(roots: string[], options: { sort?: boolean, requirePubspec?: boolean } = {}): string[] {
70+
return flatMap(roots, findProjectsGlobSync);
71+
}
72+
73+
function getChildFolders(parent: string, options?: { allowBin?: boolean, allowCache?: boolean }): string[] {
74+
return fs.readdirSync(parent)
75+
.filter((f) => f !== "bin" || (options && options.allowBin)) // Don't look in bin folders
76+
.filter((f) => f !== "cache" || (options && options.allowCache)) // Don't look in cache folders
77+
.map((item) => path.join(parent, item))
78+
.filter((item) => fs.statSync(item).isDirectory());
79+
}
80+
81+
async function getChildFoldersAsync(parent: string): Promise<string[]> {
82+
return new Promise((resolve, reject) => {
83+
fs.readdir(parent, (err, files) => {
84+
if (err)
85+
return reject(err);
86+
87+
const f = files.filter((f) => f !== "bin") // Don't look in bin folders
88+
.filter((f) => f !== "cache") // Don't look in cache folders
89+
.map((item) => path.join(parent, item))
90+
.filter((item) => fs.statSync(item).isDirectory());
91+
resolve(f);
92+
});
93+
});
94+
}
95+
96+
function hasPubspec(folder: string): boolean {
97+
return fs.existsSync(path.join(folder, "pubspec.yaml"));
98+
}
99+
100+
function hasCreateTriggerFile(folder: string): boolean {
101+
return fs.existsSync(path.join(folder, FLUTTER_CREATE_PROJECT_TRIGGER_FILE))
102+
|| fs.existsSync(path.join(folder, FLUTTER_STAGEHAND_PROJECT_TRIGGER_FILE));
103+
}
104+
105+
function isFlutterRepo(folder: string): boolean {
106+
return fs.existsSync(path.join(folder, "bin/flutter")) && fs.existsSync(path.join(folder, "bin/cache/dart-sdk"));
107+
}
108+
109+
function existsAsync(p: string): Promise<boolean> {
110+
return new Promise((resolve) => fs.exists(p, resolve));
111+
}
112+
113+
async function hasPubspecAsync(folder: string): Promise<boolean> {
114+
return existsAsync(path.join(folder, "pubspec.yaml"));
115+
}
116+
117+
async function hasCreateTriggerFileAsync(folder: string): Promise<boolean> {
118+
return (await Promise.all([
119+
existsAsync(path.join(folder, FLUTTER_CREATE_PROJECT_TRIGGER_FILE)),
120+
existsAsync(path.join(folder, FLUTTER_STAGEHAND_PROJECT_TRIGGER_FILE)),
121+
])).indexOf(true) !== -1;
122+
}
123+
124+
async function isFlutterRepoAsync(folder: string): Promise<boolean> {
125+
return (await Promise.all([
126+
existsAsync(path.join(folder, "bin/flutter")),
127+
existsAsync(path.join(folder, "bin/cache/dart-sdk")),
128+
])).indexOf(true) !== -1;
129+
}
130+
131+
function findProjectsGlob(root: string): Promise<string[]> {
132+
return new Promise<string[]>((resolve, reject) => {
133+
glob("pubspec.yaml", { cwd: root, nosort: true, absolute: true, matchBase: true }, (err, files) => {
134+
if (err)
135+
reject(err);
136+
else
137+
resolve(files);
138+
});
139+
});
140+
}
141+
142+
function findProjectsGlobSync(root: string): string[] {
143+
return glob.sync("pubspec.yaml", { cwd: root, nosort: true, absolute: true, matchBase: true });
144+
}

0 commit comments

Comments
 (0)