go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/frontend/ui/src/tools/urlHandling/links.ts (about)

     1  // Copyright 2022 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://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,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  import {
    16    ClusterId,
    17    PresubmitRunId,
    18    Variant,
    19  } from '@/proto/go.chromium.org/luci/analysis/proto/v1/common.pb';
    20  import { Changelist, SourceRef } from '@/proto/go.chromium.org/luci/analysis/proto/v1/sources.pb';
    21  
    22  import { variantAsPairs } from '../variant_tools';
    23  
    24  export const linkToCluster = (project: string, c: ClusterId): string => {
    25    if (c.algorithm.startsWith('rules-') || c.algorithm == 'rules') {
    26      return linkToRule(project, c.id);
    27    } else {
    28      const projectEncoded = encodeURIComponent(project);
    29      const algorithmEncoded = encodeURIComponent(c.algorithm);
    30      const idEncoded = encodeURIComponent(c.id);
    31      return `/p/${projectEncoded}/clusters/${algorithmEncoded}/${idEncoded}`;
    32    }
    33  };
    34  
    35  export const linkToRule = (project: string, ruleId: string): string => {
    36    const projectEncoded = encodeURIComponent(project);
    37    const ruleIdEncoded = encodeURIComponent(ruleId);
    38    return `/p/${projectEncoded}/rules/${ruleIdEncoded}`;
    39  };
    40  
    41  export const invocationName = (invocationId: string): string => {
    42    if (invocationId.startsWith('build-')) {
    43      return invocationId.slice('build-'.length);
    44    }
    45    return invocationId;
    46  };
    47  
    48  export const failureLink = (invocationId: string, testId: string, variant?: Variant): string => {
    49    const variantQuery = variantAsPairs(variant).map((vp) => {
    50      return 'V:' + encodeURIComponent(vp.key || '') + '=' + encodeURIComponent(vp.value);
    51    }).join(' ');
    52    const query = `ID:${testId} ${variantQuery}`;
    53    if (invocationId.startsWith('build-')) {
    54      return `https://ci.chromium.org/ui/b/${invocationId.slice('build-'.length)}/test-results?q=${encodeURIComponent(query)}`;
    55    }
    56    return `https://ci.chromium.org/ui/inv/${invocationId}/test-results?q=${encodeURIComponent(query)}`;
    57  };
    58  
    59  export const clLink = (cl: Changelist): string => {
    60    return `https://${cl.host}/c/${cl.change}/${cl.patchset}`;
    61  };
    62  
    63  export const clName = (cl: Changelist): string => {
    64    const host = cl.host.replace('-review.googlesource.com', '');
    65    return `${host}/${cl.change}/${cl.patchset}`;
    66  };
    67  
    68  export const presubmitRunLink = (runId: PresubmitRunId): string => {
    69    return `https://luci-change-verifier.appspot.com/ui/run/${runId.id}`;
    70  };
    71  
    72  export const testHistoryLink = (project: string, testId: string, partialVariant?: Variant): string => {
    73    const query = variantAsPairs(partialVariant).map((vp) => {
    74      return 'V:' + encodeURIComponent(vp.key || '') + '=' + encodeURIComponent(vp.value);
    75    }).join(' ');
    76    return `https://ci.chromium.org/ui/test/${encodeURIComponent(project)}/${encodeURIComponent(testId)}?q=${encodeURIComponent(query)}`;
    77  };
    78  
    79  export const sourceRefLink = (sourceRef: SourceRef) : string => {
    80    if (sourceRef.gitiles) {
    81      return `https://${sourceRef.gitiles.host}/${sourceRef.gitiles.project}/+log/${sourceRef.gitiles.ref}`;
    82    }
    83    return '';
    84  };
    85  
    86  // loginLink constructs a URL to login to LUCI Analysis, with a redirect to
    87  // the given absolute URL (which should start with "/").
    88  export const loginLink = (redirectTarget: string): string => {
    89    return window.loginUrl + '?r=' + encodeURIComponent(redirectTarget);
    90  };
    91  
    92  // logoutLink constructs a URL to logout from LUCI Analysis, with a redirect to
    93  // the given absolute URL (which should start with "/").
    94  export const logoutLink = (redirectTarget: string): string => {
    95    return window.logoutUrl + '?r=' + encodeURIComponent(redirectTarget);
    96  };