• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2023 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15import * as hjson from 'hjson';
16import * as vscode from 'vscode';
17
18/**
19 * Schema for extensions.json
20 */
21export interface ExtensionsJson {
22  recommendations?: string[];
23  unwantedRecommendations?: string[];
24}
25
26/**
27 * Partial schema for the workspace config file
28 */
29interface WorkspaceConfig {
30  extensions?: ExtensionsJson;
31}
32
33// When the project is opened directly (i.e., by opening the repo directory),
34// we have direct access to extensions.json. But if the project is part of a
35// workspace (https://code.visualstudio.com/docs/editor/workspaces), we'll get
36// a combined config that includes the equivalent of extensions.json associated
37// with the "extensions" key. This is taken into consideration only for the sake
38// of completeness; Pigweed doesn't currently support the use of workspaces.
39type LoadableConfig = ExtensionsJson & WorkspaceConfig;
40
41/**
42 * Load a config file that contains extensions.json data. This could be
43 * extensions.json itself, or a workspace file that contains the equivalent.
44 * @param uri - A file path to load
45 * @returns - The extensions.json file data
46 */
47export async function loadExtensionsJson(
48  uri: vscode.Uri,
49): Promise<ExtensionsJson> {
50  const buffer = await vscode.workspace.fs.readFile(uri);
51  const config: LoadableConfig = hjson.parse(buffer.toString());
52
53  if (config.extensions) {
54    return config.extensions;
55  }
56
57  return config as ExtensionsJson;
58}
59
60/**
61 * Find and return the extensions.json data for the project.
62 * @param includeWorkspace - Also search workspace files
63 * @returns The extensions.json file data
64 */
65export async function getExtensionsJson(
66  includeWorkspace = false,
67): Promise<ExtensionsJson | null> {
68  const files = await vscode.workspace.findFiles(
69    '.vscode/extensions.json',
70    '**/node_modules/**',
71  );
72
73  if (includeWorkspace) {
74    const workspaceFile = vscode.workspace.workspaceFile;
75
76    if (workspaceFile) {
77      files.push(workspaceFile);
78    }
79  }
80
81  if (files.length == 0) {
82    return null;
83  } else {
84    if (files.length > 1) {
85      vscode.window.showWarningMessage(
86        'Found multiple extensions.json! Will only use the first.',
87      );
88    }
89
90    return await loadExtensionsJson(files[0]);
91  }
92}
93