3.3 KB114 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {RepoInfo} from './types';
9
10import {atom} from 'jotai';
11import serverAPI from './ClientToServerAPI';
12import {writeAtom} from './jotaiUtils';
13import {repositoryInfo} from './serverAPIState';
14import {registerDisposable} from './utils';
15
16/**
17 * Hidden master branch config fetched from sitevar.
18 * Maps OD type to list of repo paths where master should be hidden.
19 * Example: {'instagram_www': ['fbsource/fbcode/instagram-server', 'fbsource/www']}
20 */
21export const hiddenMasterBranchConfigAtom = atom<Record<string, Array<string>> | null>(null);
22
23/**
24 * OD type fetched once on startup
25 */
26const odTypeAtom = atom<string | null>(null);
27
28/**
29 * Current working directory from server
30 */
31const cwdAtom = atom<string>('');
32
33/**
34 * Computed atom that determines if master branch should be hidden
35 * based on the fetched config, OD type, and current repo path.
36 */
37export const shouldHideMasterAtom = atom(get => {
38 const config = get(hiddenMasterBranchConfigAtom);
39 const odType = get(odTypeAtom);
40 const cwd = get(cwdAtom);
41 const repoInfo = get(repositoryInfo);
42
43 if (!repoInfo) {
44 return false;
45 }
46
47 return checkShouldHideMaster(config, odType, cwd, repoInfo);
48});
49
50/**
51 * Computed atom that indicates if the hidden master feature is available.
52 * This is true when the sitevar config has been fetched and the current OD type
53 * is enabled in the config.
54 */
55export const hiddenMasterFeatureAvailableAtom = atom(get => {
56 const config = get(hiddenMasterBranchConfigAtom);
57 const odType = get(odTypeAtom);
58 // Feature is available if config exists and current OD type is in the config
59 return config != null && odType != null && odType in config;
60});
61
62/**
63 * Check if master branch should be hidden based on sitevar config and repo path.
64 */
65function checkShouldHideMaster(
66 hiddenMasterBranchConfig: Record<string, Array<string>> | null,
67 odType: string | null,
68 cwd: string,
69 repoInfo: RepoInfo,
70): boolean {
71 if (!hiddenMasterBranchConfig || !odType) {
72 return false;
73 }
74
75 if (repoInfo.type !== 'success') {
76 return false;
77 }
78
79 const repoPaths = hiddenMasterBranchConfig[odType];
80 if (!repoPaths) {
81 return false;
82 }
83
84 const repoRoot = repoInfo.repoRoot;
85
86 // Check if current working directory matches any of the configured paths
87 const shouldHide = repoPaths.some(configPath => {
88 // Strip 'fbsource/' prefix if present to get the relative path
89 const relativePath = configPath.startsWith('fbsource/')
90 ? configPath.substring('fbsource/'.length)
91 : configPath;
92
93 // Construct the full expected path
94 const fullPath = `${repoRoot}/${relativePath}`;
95
96 // Check if current working directory matches the configured path
97 return cwd === fullPath || cwd.startsWith(`${fullPath}/`);
98 });
99
100 return shouldHide;
101}
102
103// Listen for config from server and store it
104registerDisposable(
105 serverAPI,
106 serverAPI.onMessageOfType('fetchedHiddenMasterBranchConfig', data => {
107 // Store the config, OD type, and cwd in atoms for quick access
108 writeAtom(hiddenMasterBranchConfigAtom, data.config || {});
109 writeAtom(odTypeAtom, data.odType || '');
110 writeAtom(cwdAtom, data.cwd);
111 }),
112 import.meta.hot,
113);
114