ember-apply icon indicating copy to clipboard operation
ember-apply copied to clipboard

Add utility for getting the most relevant package.json from an array of packages

Open NullVoxPopuli opened this issue 1 year ago • 1 comments

for example, using @manypkg/get-packages


function getPackageJson(filePath) {
	/**
	 * If the cheapest faster path gives us one result, we can skip the complicated code
	 * for finding which package belongs to a file
	 *
	 * (this is all so we don't need to hit the disk and cause I/O delays for every linted file)
	 */
	const candidates = projects.filter((project) => filePath.startsWith(project.dir));

	if (candidates.length === 1) {
		return candidates[0].packageJson;
	}

	// Find with longest matching path
	// (since project diretories can nest)

	/**
	 * We can have multiple candidates when project directaries nest
	 * e.g.:
	 *   - foo/
	 *       package.json
	 *   - foo/tests/
	 *       package.json
	 *
	 *   If we have a file in foo/tests, we don't want to match foo,
	 *   but it will match in the above.
	 *
	 * We also run in to this situation when we have similarly named projects:
	 * e.g.:
	 *   - foo/
	 *   - foo-other/
	 *
	 *   If we have a file in foo-other, foo will also match
	 */
	let bestMatch = null;
	const fParts = filePath.split('/');

	findBestCandidate: for (const project of candidates) {
		const candidate = project.dir.split('/');
		/**
		 * If the candidate project has a longer path than our file,
		 * our file cannot possibly be within that project
		 */
		if (candidate.length > fParts.length) {
			continue;
		}

		for (let i = 0; i < candidate.length; i++) {
			const cPart = candidate[i];
			const fPart = fParts[i];

			/**
			 * If a folder/segment of the candidate ever does not match
			 * the filePath part, the whole candidate is not worth checking
			 */
			if (cPart !== fPart) {
				continue findBestCandidate;
			}
		}

		/**
		 * If execution makes it past the above loop, the *entire* candidate path is within
		 * the file path.
		 *
		 * If we make it here, we know that we don't have a situation like "foo" vs "foo-other"
		 */
		if (!bestMatch || bestMatch.dir.length < candidate.dir.length) {
			bestMatch = project;
		}
	}

	return bestMatch.packageJson;
}

NullVoxPopuli avatar Jul 11 '24 15:07 NullVoxPopuli

This would also be a good opportunity to switch the workspace discovery code to @manypkg

NullVoxPopuli avatar Jul 11 '24 15:07 NullVoxPopuli