feat: Create editors definitions configmaps (#1838)

* feat: Create editors definitions configmaps

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
pull/1844/head
Anatolii Bazko 2024-05-20 14:20:59 +02:00 committed by GitHub
parent 5ad8b51f42
commit 634c6228bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
82 changed files with 1280 additions and 1615 deletions

View File

@ -78,8 +78,10 @@ jobs:
registry: quay.io
- name: Build catalog source
run: |
${GITHUB_WORKSPACE}/build/scripts/release/addDigests.sh -s $(make csv-path CHANNEL=next) -t next
${GITHUB_WORKSPACE}/build/scripts/olm/release-catalog.sh \
./build/scripts/release/editors-definitions.sh add-env-vars
make update-dev-resources
./build/scripts/release/addDigests.sh -s $(make csv-path CHANNEL=next) -t next
./build/scripts/olm/release-catalog.sh \
--channel next \
--catalog-image quay.io/eclipse/eclipse-che-olm-catalog:next-digest \
--bundle-image quay.io/eclipse/eclipse-che-olm-bundle:$(make bundle-version CHANNEL=next)-digest

View File

@ -37,11 +37,11 @@ COPY go.sum go.sum
# Copy the go source
COPY main.go main.go
COPY vendor/ vendor/
COPY mocks/ mocks/
COPY api/ api/
COPY config/ config/
COPY controllers/ controllers/
COPY pkg/ pkg/
COPY editors-definitions /tmp/editors-definitions
# build operator
# to test FIPS compliance, run https://github.com/openshift/check-payload#scan-a-container-or-operator-image against a built image
@ -53,6 +53,7 @@ RUN export ARCH="$(uname -m)" && if [[ ${ARCH} == "x86_64" ]]; then export ARCH=
FROM registry.access.redhat.com/ubi8-minimal:8.9-1161
COPY --from=builder /tmp/header-rewrite-traefik-plugin /tmp/header-rewrite-traefik-plugin
COPY --from=builder /tmp/editors-definitions /tmp/editors-definitions
COPY --from=builder /che-operator/che-operator /manager
ENTRYPOINT ["/manager"]

View File

@ -359,7 +359,7 @@ genenerate-env:
cat $(BASH_ENV_FILE)
install-che-operands: SHELL := /bin/bash
install-che-operands: generate manifests download-kustomize download-gateway-resources
install-che-operands: generate manifests download-kustomize download-gateway-resources copy-editors-definitions
echo "[INFO] Running on $(PLATFORM)"
if [[ ! "$$($(K8S_CLI) get checluster eclipse-che -n $(ECLIPSE_CHE_NAMESPACE) || false )" ]]; then
[[ $(PLATFORM) == "kubernetes" ]] && $(MAKE) install-certmgr
@ -378,6 +378,12 @@ install-che-operands: generate manifests download-kustomize download-gateway-res
$(MAKE) store_tls_cert
$(MAKE) create-checluster-cr
# Copy editors definitions to /tmp/editors-definitions
copy-editors-definitions:
mkdir -p /tmp/editors-definitions
cp -r $(PROJECT_DIR)/editors-definitions/* /tmp/editors-definitions
# Downloads Gateway resources
download-gateway-resources:
GATEWAY_RESOURCES=/tmp/header-rewrite-traefik-plugin

View File

@ -2,7 +2,7 @@
// +build !ignore_autogenerated
//
// Copyright (c) 2019-2023 Red Hat, Inc.
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -2,7 +2,7 @@
// +build !ignore_autogenerated
//
// Copyright (c) 2019-2023 Red Hat, Inc.
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -94,7 +94,7 @@ do
tagOrDigest="${source#*:}"
fi
if [[ ${imageLabel} == "plugin-registry-image" ]] || [[ ${imageLabel} == "devfile-registry-image" ]]; then
if [[ ${imageLabel} == "devfile-registry-image" ]]; then
# Image tag could contains invalid for Env variable name characters, so let's encode it using base32.
# But alphabet of base32 uses one invalid for env variable name character '=' at the end of the line, so let's replace it by '_'.
# To recovery original tag should be done opposite actions: replace '_' to '=', and decode string using 'base32 -d'.

View File

@ -50,13 +50,6 @@ setOperatorImage() {
OPERATOR_IMAGE=$(yq -r '.spec.install.spec.deployments[].spec.template.spec.containers[0].image' "${CSV}")
}
setPluginRegistryList() {
registry=$(yq -r '.spec.install.spec.deployments[].spec.template.spec.containers[].env[] | select(.name | test("RELATED_IMAGE_.*plugin_registry"; "g")) | .value' "${CSV}")
setRegistryImages "${registry}"
PLUGIN_REGISTRY_LIST=${registryImages}
}
setDevfileRegistryList() {
registry=$(yq -r '.spec.install.spec.deployments[].spec.template.spec.containers[].env[] | select(.name | test("RELATED_IMAGE_.*devfile_registry"; "g")) | .value' "${CSV}")
@ -150,9 +143,6 @@ setImagesFromDeploymentEnv
setOperatorImage
echo "${OPERATOR_IMAGE}"
setPluginRegistryList
echo "${PLUGIN_REGISTRY_LIST}"
setDevfileRegistryList
echo "${DEVFILE_REGISTRY_LIST}"
@ -166,10 +156,6 @@ for image in ${REQUIRED_IMAGES}; do
writeDigest "${image}" "required-image"
done
for image in ${PLUGIN_REGISTRY_LIST}; do
writeDigest "${image}" "plugin-registry-image"
done
for image in ${DEVFILE_REGISTRY_LIST}; do
writeDigest "${image}" "devfile-registry-image"
done

View File

@ -0,0 +1,80 @@
#!/bin/bash
#
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
set -e
OPERATOR_REPO=$(dirname "$(dirname "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")")")
EDITORS_DEFINITIONS_DIR="${OPERATOR_REPO}/editors-definitions"
MANAGER_YAML="${OPERATOR_REPO}/config/manager/manager.yaml"
init() {
unset VERSION
unset ENVS
COMMAND=$1
shift
while [[ "$#" -gt 0 ]]; do
case $1 in
'--version') VERSION=$2; shift 1;;
esac
shift 1
done
}
usage () {
echo "Editor definitions utils."
echo
echo "Usage:"
echo -e "\t$0 release --version RELEASE_VERSION"
echo -e "\t$0 add-env-vars"
}
release() {
if [[ ! ${VERSION} ]]; then usage; exit 1; fi
yq -riY ".metadata.attributes.version = \"${VERSION}\"" "${EDITORS_DEFINITIONS_DIR}/che-code-latest.yaml"
yq -riY "(.components[] | select(.name==\"che-code-injector\") | .container.image) = \"quay.io/che-incubator/che-code:${VERSION}\"" "${EDITORS_DEFINITIONS_DIR}/che-code-latest.yaml"
}
addEnvVars() {
for EDITOR_DEFINITION_FILE in $(find "${EDITORS_DEFINITIONS_DIR}" -name "*.yaml"); do
NAME=$(yq -r '.metadata.name' "${EDITOR_DEFINITION_FILE}")
VERSION=$(yq -r '.metadata.attributes.version' "${EDITOR_DEFINITION_FILE}")
for COMPONENT in $(yq -r '.components[] | .name' "${EDITOR_DEFINITION_FILE}"); do
ENV_VALUE=$(yq -r ".components[] | select(.name==\"${COMPONENT}\") | .container.image" "${EDITOR_DEFINITION_FILE}")
ENV_NAME=$(echo "RELATED_IMAGE_editor_definition_${NAME}_${VERSION}_${COMPONENT}" | sed 's|[-\.]|_|g')
if [[ ! ${ENV_VALUE} == "null" ]]; then
ENV="{ name: \"${ENV_NAME}\", value: \"${ENV_VALUE}\"}"
if [[ -z ${ENVS} ]]; then
ENVS="${ENV}"
else
ENVS="${ENVS}, ${ENV}"
fi
fi
done
done
yq -riY "(.spec.template.spec.containers[0].env ) += [${ENVS}]" "${MANAGER_YAML}"
}
init "$@"
pushd "${OPERATOR_REPO}" >/dev/null
case $COMMAND in
'release') release;;
'add-env-vars') addEnvVars;;
*) usage; exit 1;;
esac
popd >/dev/null

View File

@ -179,6 +179,17 @@ replaceTag() {
echo "${1}" | sed -e "s/\(.*:\).*/\1${2}/"
}
releaseEditorsDefinitions() {
echo "[INFO] Releasing editor definitions"
. "${OPERATOR_REPO}/build/scripts/release/editors-definitions.sh" release --version "${RELEASE}"
. "${OPERATOR_REPO}/build/scripts/release/editors-definitions.sh" add-env-vars
git add editors-definitions
git add "${OPERATOR_REPO}/config/manager/manager.yaml"
git commit -m "ci: Release editors definitions to $RELEASE" --signoff
}
updateVersionFile() {
echo "[INFO] updating version.go file"
# change version/version.go file
@ -268,7 +279,7 @@ createPRToMainBranch() {
resetChanges main
local tmpBranch="copy-csv-to-main"
git checkout -B $tmpBranch
git diff refs/heads/${BRANCH}...refs/heads/${RELEASE_BRANCH} ':(exclude)config/manager/manager.yaml' ':(exclude)deploy' ':(exclude)Dockerfile' | git apply -3
git diff refs/heads/${BRANCH}...refs/heads/${RELEASE_BRANCH} ':(exclude)config/manager/manager.yaml' ':(exclude)deploy' ':(exclude)editors-definitions' ':(exclude)Dockerfile' | git apply -3
if git status --porcelain; then
git add -A || true # add new generated CSV files in olm/ folder
git commit -am "ci: Copy "$RELEASE" csv to main" --signoff
@ -291,6 +302,7 @@ run() {
checkoutToReleaseBranch
updateVersionFile
releaseEditorsDefinitions
releaseOperatorCode
if [[ $RELEASE_OLM_FILES == "true" ]]; then
releaseOlmFiles

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
@ -100,7 +100,7 @@ metadata:
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
repository: https://github.com/eclipse-che/che-operator
support: Eclipse Foundation
name: eclipse-che.v7.86.0-867.next
name: eclipse-che.v7.87.0-869.next
namespace: placeholder
spec:
apiservicedefinitions: {}
@ -1032,7 +1032,7 @@ spec:
minKubeVersion: 1.19.0
provider:
name: Eclipse Foundation
version: 7.86.0-867.next
version: 7.87.0-869.next
webhookdefinitions:
- admissionReviewVersions:
- v1

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -0,0 +1,145 @@
#
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
schemaVersion: 2.2.2
metadata:
name: che-code
displayName: VS Code - Open Source
description: Microsoft Visual Studio Code - Open Source IDE for Eclipse Che - Insiders
build
tags:
- Tech-Preview
attributes:
publisher: che-incubator
version: insiders
title: Microsoft Visual Studio Code - Open Source IDE for Eclipse Che - Insiders
build
repository: https://github.com/che-incubator/che-code
firstPublicationDate: '2021-10-31'
icon-mediatype: image/svg+xml
icon-data: |
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.9119 99.3171C72.4869 99.9307 74.2828 99.8914 75.8725 99.1264L96.4608 89.2197C98.6242 88.1787 100 85.9892 100 83.5872V16.4133C100 14.0113 98.6243 11.8218 96.4609 10.7808L75.8725 0.873756C73.7862 -0.130129 71.3446 0.11576 69.5135 1.44695C69.252 1.63711 69.0028 1.84943 68.769 2.08341L29.3551 38.0415L12.1872 25.0096C10.589 23.7965 8.35363 23.8959 6.86933 25.2461L1.36303 30.2549C-0.452552 31.9064 -0.454633 34.7627 1.35853 36.417L16.2471 50.0001L1.35853 63.5832C-0.454633 65.2374 -0.452552 68.0938 1.36303 69.7453L6.86933 74.7541C8.35363 76.1043 10.589 76.2037 12.1872 74.9905L29.3551 61.9587L68.769 97.9167C69.3925 98.5406 70.1246 99.0104 70.9119 99.3171ZM75.0152 27.2989L45.1091 50.0001L75.0152 72.7012V27.2989Z" fill="white"/>
</mask>
<g mask="url(#mask0)">
<path d="M96.4614 10.7962L75.8569 0.875542C73.4719 -0.272773 70.6217 0.211611 68.75 2.08333L1.29858 63.5832C-0.515693 65.2373 -0.513607 68.0937 1.30308 69.7452L6.81272 74.754C8.29793 76.1042 10.5347 76.2036 12.1338 74.9905L93.3609 13.3699C96.086 11.3026 100 13.2462 100 16.6667V16.4275C100 14.0265 98.6246 11.8378 96.4614 10.7962Z" fill="#0065A9"/>
<g filter="url(#filter0_d)">
<path d="M96.4614 89.2038L75.8569 99.1245C73.4719 100.273 70.6217 99.7884 68.75 97.9167L1.29858 36.4169C-0.515693 34.7627 -0.513607 31.9063 1.30308 30.2548L6.81272 25.246C8.29793 23.8958 10.5347 23.7964 12.1338 25.0095L93.3609 86.6301C96.086 88.6974 100 86.7538 100 83.3334V83.5726C100 85.9735 98.6246 88.1622 96.4614 89.2038Z" fill="#007ACC"/>
</g>
<g filter="url(#filter1_d)">
<path d="M75.8578 99.1263C73.4721 100.274 70.6219 99.7885 68.75 97.9166C71.0564 100.223 75 98.5895 75 95.3278V4.67213C75 1.41039 71.0564 -0.223106 68.75 2.08329C70.6219 0.211402 73.4721 -0.273666 75.8578 0.873633L96.4587 10.7807C98.6234 11.8217 100 14.0112 100 16.4132V83.5871C100 85.9891 98.6234 88.1786 96.4586 89.2196L75.8578 99.1263Z" fill="#1F9CF0"/>
</g>
<g style="mix-blend-mode:overlay" opacity="0.25">
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.8511 99.3171C72.4261 99.9306 74.2221 99.8913 75.8117 99.1264L96.4 89.2197C98.5634 88.1787 99.9392 85.9892 99.9392 83.5871V16.4133C99.9392 14.0112 98.5635 11.8217 96.4001 10.7807L75.8117 0.873695C73.7255 -0.13019 71.2838 0.115699 69.4527 1.44688C69.1912 1.63705 68.942 1.84937 68.7082 2.08335L29.2943 38.0414L12.1264 25.0096C10.5283 23.7964 8.29285 23.8959 6.80855 25.246L1.30225 30.2548C-0.513334 31.9064 -0.515415 34.7627 1.29775 36.4169L16.1863 50L1.29775 63.5832C-0.515415 65.2374 -0.513334 68.0937 1.30225 69.7452L6.80855 74.754C8.29285 76.1042 10.5283 76.2036 12.1264 74.9905L29.2943 61.9586L68.7082 97.9167C69.3317 98.5405 70.0638 99.0104 70.8511 99.3171ZM74.9544 27.2989L45.0483 50L74.9544 72.7012V27.2989Z" fill="url(#paint0_linear)"/>
</g>
</g>
<defs>
<filter id="filter0_d" x="-8.39411" y="15.8291" width="116.727" height="92.2456" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset/>
<feGaussianBlur stdDeviation="4.16667"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="overlay" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="60.4167" y="-8.07558" width="47.9167" height="116.151" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset/>
<feGaussianBlur stdDeviation="4.16667"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="overlay" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<linearGradient id="paint0_linear" x1="49.9392" y1="0.257812" x2="49.9392" y2="99.7423" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>
commands:
- id: init-container-command
apply:
component: che-code-injector
- id: init-che-code-command
exec:
component: che-code-runtime-description
commandLine: nohup /checode/entrypoint-volume.sh > /checode/entrypoint-logs.txt
2>&1 &
events:
preStart:
- init-container-command
postStart:
- init-che-code-command
components:
- name: che-code-injector
container:
image: quay.io/che-incubator/che-code:insiders
command:
- /entrypoint-init-container.sh
volumeMounts:
- name: checode
path: /checode
memoryLimit: 256Mi
memoryRequest: 32Mi
cpuLimit: 500m
cpuRequest: 30m
- name: che-code-runtime-description
container:
image: quay.io/devfile/universal-developer-image:latest
memoryLimit: 1024Mi
memoryRequest: 256Mi
cpuLimit: 500m
cpuRequest: 30m
volumeMounts:
- name: checode
path: /checode
endpoints:
- name: che-code
attributes:
type: main
cookiesAuthEnabled: true
discoverable: false
urlRewriteSupported: true
targetPort: 3100
exposure: public
secure: true
protocol: https
- name: code-redirect-1
targetPort: 13131
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
- name: code-redirect-2
targetPort: 13132
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
- name: code-redirect-3
targetPort: 13133
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
attributes:
app.kubernetes.io/component: che-code-runtime
app.kubernetes.io/part-of: che-code.eclipse.org
controller.devfile.io/container-contribution: true
- name: checode
volume: {}

View File

@ -0,0 +1,143 @@
#
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
schemaVersion: 2.2.2
metadata:
name: che-code
displayName: VS Code - Open Source
description: Microsoft Visual Studio Code - Open Source IDE for Eclipse Che
attributes:
publisher: che-incubator
version: latest
title: Microsoft Visual Studio Code - Open Source IDE for Eclipse Che
repository: https://github.com/che-incubator/che-code
firstPublicationDate: '2021-10-31'
icon-mediatype: image/svg+xml
icon-data: |
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.9119 99.3171C72.4869 99.9307 74.2828 99.8914 75.8725 99.1264L96.4608 89.2197C98.6242 88.1787 100 85.9892 100 83.5872V16.4133C100 14.0113 98.6243 11.8218 96.4609 10.7808L75.8725 0.873756C73.7862 -0.130129 71.3446 0.11576 69.5135 1.44695C69.252 1.63711 69.0028 1.84943 68.769 2.08341L29.3551 38.0415L12.1872 25.0096C10.589 23.7965 8.35363 23.8959 6.86933 25.2461L1.36303 30.2549C-0.452552 31.9064 -0.454633 34.7627 1.35853 36.417L16.2471 50.0001L1.35853 63.5832C-0.454633 65.2374 -0.452552 68.0938 1.36303 69.7453L6.86933 74.7541C8.35363 76.1043 10.589 76.2037 12.1872 74.9905L29.3551 61.9587L68.769 97.9167C69.3925 98.5406 70.1246 99.0104 70.9119 99.3171ZM75.0152 27.2989L45.1091 50.0001L75.0152 72.7012V27.2989Z" fill="white"/>
</mask>
<g mask="url(#mask0)">
<path d="M96.4614 10.7962L75.8569 0.875542C73.4719 -0.272773 70.6217 0.211611 68.75 2.08333L1.29858 63.5832C-0.515693 65.2373 -0.513607 68.0937 1.30308 69.7452L6.81272 74.754C8.29793 76.1042 10.5347 76.2036 12.1338 74.9905L93.3609 13.3699C96.086 11.3026 100 13.2462 100 16.6667V16.4275C100 14.0265 98.6246 11.8378 96.4614 10.7962Z" fill="#0065A9"/>
<g filter="url(#filter0_d)">
<path d="M96.4614 89.2038L75.8569 99.1245C73.4719 100.273 70.6217 99.7884 68.75 97.9167L1.29858 36.4169C-0.515693 34.7627 -0.513607 31.9063 1.30308 30.2548L6.81272 25.246C8.29793 23.8958 10.5347 23.7964 12.1338 25.0095L93.3609 86.6301C96.086 88.6974 100 86.7538 100 83.3334V83.5726C100 85.9735 98.6246 88.1622 96.4614 89.2038Z" fill="#007ACC"/>
</g>
<g filter="url(#filter1_d)">
<path d="M75.8578 99.1263C73.4721 100.274 70.6219 99.7885 68.75 97.9166C71.0564 100.223 75 98.5895 75 95.3278V4.67213C75 1.41039 71.0564 -0.223106 68.75 2.08329C70.6219 0.211402 73.4721 -0.273666 75.8578 0.873633L96.4587 10.7807C98.6234 11.8217 100 14.0112 100 16.4132V83.5871C100 85.9891 98.6234 88.1786 96.4586 89.2196L75.8578 99.1263Z" fill="#1F9CF0"/>
</g>
<g style="mix-blend-mode:overlay" opacity="0.25">
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.8511 99.3171C72.4261 99.9306 74.2221 99.8913 75.8117 99.1264L96.4 89.2197C98.5634 88.1787 99.9392 85.9892 99.9392 83.5871V16.4133C99.9392 14.0112 98.5635 11.8217 96.4001 10.7807L75.8117 0.873695C73.7255 -0.13019 71.2838 0.115699 69.4527 1.44688C69.1912 1.63705 68.942 1.84937 68.7082 2.08335L29.2943 38.0414L12.1264 25.0096C10.5283 23.7964 8.29285 23.8959 6.80855 25.246L1.30225 30.2548C-0.513334 31.9064 -0.515415 34.7627 1.29775 36.4169L16.1863 50L1.29775 63.5832C-0.515415 65.2374 -0.513334 68.0937 1.30225 69.7452L6.80855 74.754C8.29285 76.1042 10.5283 76.2036 12.1264 74.9905L29.2943 61.9586L68.7082 97.9167C69.3317 98.5405 70.0638 99.0104 70.8511 99.3171ZM74.9544 27.2989L45.0483 50L74.9544 72.7012V27.2989Z" fill="url(#paint0_linear)"/>
</g>
</g>
<defs>
<filter id="filter0_d" x="-8.39411" y="15.8291" width="116.727" height="92.2456" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset/>
<feGaussianBlur stdDeviation="4.16667"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="overlay" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="60.4167" y="-8.07558" width="47.9167" height="116.151" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset/>
<feGaussianBlur stdDeviation="4.16667"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="overlay" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<linearGradient id="paint0_linear" x1="49.9392" y1="0.257812" x2="49.9392" y2="99.7423" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>
commands:
- id: init-container-command
apply:
component: che-code-injector
- id: init-che-code-command
exec:
component: che-code-runtime-description
commandLine: nohup /checode/entrypoint-volume.sh > /checode/entrypoint-logs.txt
2>&1 &
events:
preStart:
- init-container-command
postStart:
- init-che-code-command
components:
- name: che-code-injector
container:
image: quay.io/che-incubator/che-code:latest
command:
- /entrypoint-init-container.sh
volumeMounts:
- name: checode
path: /checode
memoryLimit: 256Mi
memoryRequest: 32Mi
cpuLimit: 500m
cpuRequest: 30m
- name: che-code-runtime-description
container:
image: quay.io/devfile/universal-developer-image:latest
memoryLimit: 1024Mi
memoryRequest: 256Mi
cpuLimit: 500m
cpuRequest: 30m
volumeMounts:
- name: checode
path: /checode
endpoints:
- name: che-code
attributes:
type: main
cookiesAuthEnabled: true
discoverable: false
urlRewriteSupported: true
targetPort: 3100
exposure: public
secure: true
protocol: https
- name: code-redirect-1
targetPort: 13131
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
- name: code-redirect-2
targetPort: 13132
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
- name: code-redirect-3
targetPort: 13133
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
attributes:
app.kubernetes.io/component: che-code-runtime
app.kubernetes.io/part-of: che-code.eclipse.org
controller.devfile.io/container-contribution: true
- name: checode
volume: {}
attributes:
version: null

View File

@ -0,0 +1,166 @@
#
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
schemaVersion: 2.2.2
metadata:
name: che-idea
displayName: IntelliJ IDEA Community
description: JetBrains IntelliJ IDEA Community IDE for Eclipse Che
tags:
- Tech-Preview
attributes:
publisher: che-incubator
version: latest
title: JetBrains IntelliJ IDEA Community IDE for Eclipse Che
repository: https://github.com/che-incubator/jetbrains-editor-images
firstPublicationDate: '2022-01-11'
icon-mediatype: image/svg+xml
icon-data: |
<svg xmlns="http://www.w3.org/2000/svg" width="70" height="70" fill="none" viewBox="0 0 70 70">
<defs>
<linearGradient id="a" x1="5.17435" x2="40.0136" y1="39.8894" y2="38.1233" gradientUnits="userSpaceOnUse">
<stop offset="0.0910927" stop-color="#FC801D"/>
<stop offset="0.2312" stop-color="#B07F61"/>
<stop offset="0.4086" stop-color="#577DB3"/>
<stop offset="0.5334" stop-color="#1E7CE6"/>
<stop offset="0.5934" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="b" x1="61.991" x2="50.158" y1="36.9152" y2="1.55723" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FE2857"/>
<stop offset="0.0784" stop-color="#CB3979"/>
<stop offset="0.1601" stop-color="#9E4997"/>
<stop offset="0.2474" stop-color="#7557B2"/>
<stop offset="0.3392" stop-color="#5362C8"/>
<stop offset="0.4365" stop-color="#386CDA"/>
<stop offset="0.5414" stop-color="#2373E8"/>
<stop offset="0.6576" stop-color="#1478F2"/>
<stop offset="0.794" stop-color="#0B7BF8"/>
<stop offset="1" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="c" x1="10.0665" x2="53.8764" y1="16.4955" y2="88.9597" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FE2857"/>
<stop offset="0.0800816" stop-color="#FE295F"/>
<stop offset="0.2065" stop-color="#FF2D76"/>
<stop offset="0.3034" stop-color="#FF318C"/>
<stop offset="0.3846" stop-color="#EA3896"/>
<stop offset="0.5532" stop-color="#B248AE"/>
<stop offset="0.7923" stop-color="#5A63D6"/>
<stop offset="1" stop-color="#087CFA"/>
</linearGradient>
</defs>
<path fill="url(#a)" d="M11.2 49.4668L0.699951 41.3001L9 26L18.5 33.5L11.2 49.4668Z"/>
<path fill="#087CFA" d="M69.9999 18.6666L68.8333 59.2666L41.7666 70L27.0666 60.4333L41.7666 37.5L69.9999 18.6666Z"/>
<path fill="url(#b)" d="M70 18.6666L55.5 33L37 15L48.0666 1.16663L70 18.6666Z"/>
<path fill="url(#c)" d="M27.0667 60.4333L5.6 68.3667L10.0333 52.5L15.8667 33.1333L0 27.7667L10.0333 0L33.1333 2.8L54.5 31L55.5 33L27.0667 60.4333Z"/>
<g>
<path fill="#000000" d="M56 14H14V56H56V14Z"/>
</g>
<g>
<path fill="#FFFFFF" d="M27.1366 22.1433V19.25H19.2733V22.1433H21.4666V32.1067H19.2733V34.9767H27.1366V32.1067H24.92V22.1433H27.1366Z"/>
<path fill="#FFFFFF" d="M34.6967 35.21C33.46 35.21 32.4334 34.9767 31.6167 34.51C30.7767 34.0433 30.1 33.4833 29.5634 32.8533L31.7334 30.4267C32.1767 30.9167 32.6434 31.3133 33.0867 31.5933C33.5534 31.8733 34.0434 32.0133 34.6034 32.0133C35.2567 32.0133 35.77 31.8033 36.1434 31.3833C36.5167 30.9633 36.7034 30.31 36.7034 29.4V19.2733H40.25V29.5633C40.25 30.4967 40.1334 31.3133 39.8767 32.0133C39.62 32.7133 39.2467 33.2967 38.78 33.7633C38.29 34.2533 37.7067 34.6033 37.0067 34.86C36.3067 35.0933 35.5367 35.21 34.6967 35.21Z"/>
<path fill="#FFFFFF" d="M34.4166 48.6499H18.6666V51.3332H34.4166V48.6499Z"/>
</g>
</svg>
commands:
- id: init-container-command
apply:
component: che-idea-injector
- id: init-che-idea-command
exec:
component: che-idea-runtime-description
commandLine: nohup /projector/entrypoint-volume.sh > /projector/entrypoint-logs.txt
2>&1 &
events:
preStart:
- init-container-command
postStart:
- init-che-idea-command
components:
- name: che-idea-runtime-description
container:
image: quay.io/devfile/universal-developer-image:latest
env:
- name: PROJECTOR_ASSEMBLY_DIR
value: /projector
- name: PROJECTOR_CONFIG_DIR
value: /home/user/.jetbrains
volumeMounts:
- name: projector-volume
path: /projector
- name: projector-configuration
path: /home/user/.jetbrains
- name: projector-java-configuration
path: /home/user/.java
memoryLimit: 6144Mi
memoryRequest: 2048Mi
cpuLimit: 2000m
cpuRequest: 1500m
endpoints:
- name: intellij
attributes:
type: main
cookiesAuthEnabled: true
discoverable: false
urlRewriteSupported: true
targetPort: 8887
exposure: public
path: /?backgroundColor=434343&wss
secure: true
protocol: https
- name: intellij-redirect-1
targetPort: 13131
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
- name: intellij-redirect-2
targetPort: 13132
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
- name: intellij-redirect-3
targetPort: 13133
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
attributes:
app.kubernetes.io/component: che-idea-runtime
app.kubernetes.io/part-of: che-idea.eclipse.org
controller.devfile.io/container-contribution: true
- name: projector-volume
volume: {}
- name: projector-configuration
volume: {}
- name: projector-java-configuration
volume: {}
- name: che-idea-injector
container:
image: quay.io/che-incubator/che-idea:latest
command:
- /projector/entrypoint-init-container.sh
env:
- name: PROJECTOR_VOLUME_MOUNT
value: /projector-volume
- name: PROJECTOR_ASSEMBLY_DIR
value: /projector
volumeMounts:
- name: projector-volume
path: /projector-volume
memoryLimit: 128Mi
memoryRequest: 32Mi
cpuLimit: 500m
cpuRequest: 30m

View File

@ -0,0 +1,166 @@
#
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
schemaVersion: 2.2.2
metadata:
name: che-idea
displayName: IntelliJ IDEA Community
description: JetBrains IntelliJ IDEA Community IDE for Eclipse Che - next
tags:
- Tech-Preview
attributes:
publisher: che-incubator
version: next
title: JetBrains IntelliJ IDEA Community IDE for Eclipse Che - next
repository: https://github.com/che-incubator/jetbrains-editor-images
firstPublicationDate: '2022-01-11'
icon-mediatype: image/svg+xml
icon-data: |
<svg xmlns="http://www.w3.org/2000/svg" width="70" height="70" fill="none" viewBox="0 0 70 70">
<defs>
<linearGradient id="a" x1="5.17435" x2="40.0136" y1="39.8894" y2="38.1233" gradientUnits="userSpaceOnUse">
<stop offset="0.0910927" stop-color="#FC801D"/>
<stop offset="0.2312" stop-color="#B07F61"/>
<stop offset="0.4086" stop-color="#577DB3"/>
<stop offset="0.5334" stop-color="#1E7CE6"/>
<stop offset="0.5934" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="b" x1="61.991" x2="50.158" y1="36.9152" y2="1.55723" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FE2857"/>
<stop offset="0.0784" stop-color="#CB3979"/>
<stop offset="0.1601" stop-color="#9E4997"/>
<stop offset="0.2474" stop-color="#7557B2"/>
<stop offset="0.3392" stop-color="#5362C8"/>
<stop offset="0.4365" stop-color="#386CDA"/>
<stop offset="0.5414" stop-color="#2373E8"/>
<stop offset="0.6576" stop-color="#1478F2"/>
<stop offset="0.794" stop-color="#0B7BF8"/>
<stop offset="1" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="c" x1="10.0665" x2="53.8764" y1="16.4955" y2="88.9597" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FE2857"/>
<stop offset="0.0800816" stop-color="#FE295F"/>
<stop offset="0.2065" stop-color="#FF2D76"/>
<stop offset="0.3034" stop-color="#FF318C"/>
<stop offset="0.3846" stop-color="#EA3896"/>
<stop offset="0.5532" stop-color="#B248AE"/>
<stop offset="0.7923" stop-color="#5A63D6"/>
<stop offset="1" stop-color="#087CFA"/>
</linearGradient>
</defs>
<path fill="url(#a)" d="M11.2 49.4668L0.699951 41.3001L9 26L18.5 33.5L11.2 49.4668Z"/>
<path fill="#087CFA" d="M69.9999 18.6666L68.8333 59.2666L41.7666 70L27.0666 60.4333L41.7666 37.5L69.9999 18.6666Z"/>
<path fill="url(#b)" d="M70 18.6666L55.5 33L37 15L48.0666 1.16663L70 18.6666Z"/>
<path fill="url(#c)" d="M27.0667 60.4333L5.6 68.3667L10.0333 52.5L15.8667 33.1333L0 27.7667L10.0333 0L33.1333 2.8L54.5 31L55.5 33L27.0667 60.4333Z"/>
<g>
<path fill="#000000" d="M56 14H14V56H56V14Z"/>
</g>
<g>
<path fill="#FFFFFF" d="M27.1366 22.1433V19.25H19.2733V22.1433H21.4666V32.1067H19.2733V34.9767H27.1366V32.1067H24.92V22.1433H27.1366Z"/>
<path fill="#FFFFFF" d="M34.6967 35.21C33.46 35.21 32.4334 34.9767 31.6167 34.51C30.7767 34.0433 30.1 33.4833 29.5634 32.8533L31.7334 30.4267C32.1767 30.9167 32.6434 31.3133 33.0867 31.5933C33.5534 31.8733 34.0434 32.0133 34.6034 32.0133C35.2567 32.0133 35.77 31.8033 36.1434 31.3833C36.5167 30.9633 36.7034 30.31 36.7034 29.4V19.2733H40.25V29.5633C40.25 30.4967 40.1334 31.3133 39.8767 32.0133C39.62 32.7133 39.2467 33.2967 38.78 33.7633C38.29 34.2533 37.7067 34.6033 37.0067 34.86C36.3067 35.0933 35.5367 35.21 34.6967 35.21Z"/>
<path fill="#FFFFFF" d="M34.4166 48.6499H18.6666V51.3332H34.4166V48.6499Z"/>
</g>
</svg>
commands:
- id: init-container-command
apply:
component: che-idea-injector
- id: init-che-idea-command
exec:
component: che-idea-runtime-description
commandLine: nohup /projector/entrypoint-volume.sh > /projector/entrypoint-logs.txt
2>&1 &
events:
preStart:
- init-container-command
postStart:
- init-che-idea-command
components:
- name: che-idea-runtime-description
container:
image: quay.io/devfile/universal-developer-image:latest
env:
- name: PROJECTOR_ASSEMBLY_DIR
value: /projector
- name: PROJECTOR_CONFIG_DIR
value: /home/user/.jetbrains
volumeMounts:
- name: projector-volume
path: /projector
- name: projector-configuration
path: /home/user/.jetbrains
- name: projector-java-configuration
path: /home/user/.java
memoryLimit: 6144Mi
memoryRequest: 2048Mi
cpuLimit: 2000m
cpuRequest: 1500m
endpoints:
- name: intellij
attributes:
type: main
cookiesAuthEnabled: true
discoverable: false
urlRewriteSupported: true
targetPort: 8887
exposure: public
path: /?backgroundColor=434343&wss
secure: true
protocol: https
- name: intellij-redirect-1
targetPort: 13131
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
- name: intellij-redirect-2
targetPort: 13132
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
- name: intellij-redirect-3
targetPort: 13133
exposure: public
protocol: https
attributes:
discoverable: false
urlRewriteSupported: false
attributes:
app.kubernetes.io/component: che-idea-runtime
app.kubernetes.io/part-of: che-idea.eclipse.org
controller.devfile.io/container-contribution: true
- name: projector-volume
volume: {}
- name: projector-configuration
volume: {}
- name: projector-java-configuration
volume: {}
- name: che-idea-injector
container:
image: quay.io/che-incubator/che-idea:next
command:
- /projector/entrypoint-init-container.sh
env:
- name: PROJECTOR_VOLUME_MOUNT
value: /projector-volume
- name: PROJECTOR_ASSEMBLY_DIR
value: /projector
volumeMounts:
- name: projector-volume
path: /projector-volume
memoryLimit: 128Mi
memoryRequest: 32Mi
cpuLimit: 500m
cpuRequest: 30m

View File

@ -0,0 +1,126 @@
#
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
schemaVersion: 2.2.2
metadata:
name: che-idea-server
displayName: IntelliJ IDEA Ultimate (desktop)
description: JetBrains IntelliJ IDEA Ultimate dev server for Eclipse Che - latest
tags:
- Tech-Preview
attributes:
publisher: che-incubator
version: latest
title: JetBrains IntelliJ IDEA Ultimate dev server for Eclipse Che - latest
repository: https://github.com/che-incubator/che-idea-dev-server
firstPublicationDate: '2023-30-11'
icon-mediatype: image/svg+xml
icon-data: |
<svg xmlns="http://www.w3.org/2000/svg" width="70" height="70" fill="none" viewBox="0 0 70 70">
<defs>
<linearGradient id="a" x1="5.17435" x2="40.0136" y1="39.8894" y2="38.1233" gradientUnits="userSpaceOnUse">
<stop offset="0.0910927" stop-color="#FC801D"/>
<stop offset="0.2312" stop-color="#B07F61"/>
<stop offset="0.4086" stop-color="#577DB3"/>
<stop offset="0.5334" stop-color="#1E7CE6"/>
<stop offset="0.5934" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="b" x1="61.991" x2="50.158" y1="36.9152" y2="1.55723" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FE2857"/>
<stop offset="0.0784" stop-color="#CB3979"/>
<stop offset="0.1601" stop-color="#9E4997"/>
<stop offset="0.2474" stop-color="#7557B2"/>
<stop offset="0.3392" stop-color="#5362C8"/>
<stop offset="0.4365" stop-color="#386CDA"/>
<stop offset="0.5414" stop-color="#2373E8"/>
<stop offset="0.6576" stop-color="#1478F2"/>
<stop offset="0.794" stop-color="#0B7BF8"/>
<stop offset="1" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="c" x1="10.0665" x2="53.8764" y1="16.4955" y2="88.9597" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FE2857"/>
<stop offset="0.0800816" stop-color="#FE295F"/>
<stop offset="0.2065" stop-color="#FF2D76"/>
<stop offset="0.3034" stop-color="#FF318C"/>
<stop offset="0.3846" stop-color="#EA3896"/>
<stop offset="0.5532" stop-color="#B248AE"/>
<stop offset="0.7923" stop-color="#5A63D6"/>
<stop offset="1" stop-color="#087CFA"/>
</linearGradient>
</defs>
<path fill="url(#a)" d="M11.2 49.4668L0.699951 41.3001L9 26L18.5 33.5L11.2 49.4668Z"/>
<path fill="#087CFA" d="M69.9999 18.6666L68.8333 59.2666L41.7666 70L27.0666 60.4333L41.7666 37.5L69.9999 18.6666Z"/>
<path fill="url(#b)" d="M70 18.6666L55.5 33L37 15L48.0666 1.16663L70 18.6666Z"/>
<path fill="url(#c)" d="M27.0667 60.4333L5.6 68.3667L10.0333 52.5L15.8667 33.1333L0 27.7667L10.0333 0L33.1333 2.8L54.5 31L55.5 33L27.0667 60.4333Z"/>
<g>
<path fill="#000000" d="M56 14H14V56H56V14Z"/>
</g>
<g>
<path fill="#FFFFFF" d="M27.1366 22.1433V19.25H19.2733V22.1433H21.4666V32.1067H19.2733V34.9767H27.1366V32.1067H24.92V22.1433H27.1366Z"/>
<path fill="#FFFFFF" d="M34.6967 35.21C33.46 35.21 32.4334 34.9767 31.6167 34.51C30.7767 34.0433 30.1 33.4833 29.5634 32.8533L31.7334 30.4267C32.1767 30.9167 32.6434 31.3133 33.0867 31.5933C33.5534 31.8733 34.0434 32.0133 34.6034 32.0133C35.2567 32.0133 35.77 31.8033 36.1434 31.3833C36.5167 30.9633 36.7034 30.31 36.7034 29.4V19.2733H40.25V29.5633C40.25 30.4967 40.1334 31.3133 39.8767 32.0133C39.62 32.7133 39.2467 33.2967 38.78 33.7633C38.29 34.2533 37.7067 34.6033 37.0067 34.86C36.3067 35.0933 35.5367 35.21 34.6967 35.21Z"/>
<path fill="#FFFFFF" d="M34.4166 48.6499H18.6666V51.3332H34.4166V48.6499Z"/>
</g>
</svg>
commands:
- id: inject-editor
apply:
component: editor-injector
- id: start-idea-server
exec:
component: editor-runtime
commandLine: nohup /idea-server/entrypoint-volume.sh > /idea-server/std.out
2>&1 &
events:
preStart:
- inject-editor
postStart:
- start-idea-server
components:
- name: idea-server
volume: {}
- name: editor-injector
container:
image: quay.io/che-incubator/che-idea-dev-server:latest
command:
- /entrypoint-init-container.sh
volumeMounts:
- name: idea-server
path: /idea-server
memoryLimit: 256Mi
memoryRequest: 32Mi
cpuLimit: 500m
cpuRequest: 30m
- name: editor-runtime
container:
image: quay.io/devfile/universal-developer-image:latest
memoryLimit: 6144Mi
memoryRequest: 2048Mi
cpuLimit: 2000m
cpuRequest: 1500m
volumeMounts:
- name: idea-server
path: /idea-server
endpoints:
- name: idea-server
attributes:
type: main
cookiesAuthEnabled: true
discoverable: false
urlRewriteSupported: true
targetPort: 3400
exposure: public
secure: true
protocol: https
attributes:
app.kubernetes.io/component: editor-runtime
app.kubernetes.io/part-of: idea-server.eclipse.org
controller.devfile.io/container-contribution: true

View File

@ -0,0 +1,126 @@
#
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
schemaVersion: 2.2.2
metadata:
name: che-idea-server
displayName: IntelliJ IDEA Ultimate (desktop)
description: JetBrains IntelliJ IDEA Ultimate dev server for Eclipse Che - next
tags:
- Tech-Preview
attributes:
publisher: che-incubator
version: next
title: JetBrains IntelliJ IDEA Ultimate dev server for Eclipse Che - next
repository: https://github.com/che-incubator/che-idea-dev-server
firstPublicationDate: '2023-30-11'
icon-mediatype: image/svg+xml
icon-data: |
<svg xmlns="http://www.w3.org/2000/svg" width="70" height="70" fill="none" viewBox="0 0 70 70">
<defs>
<linearGradient id="a" x1="5.17435" x2="40.0136" y1="39.8894" y2="38.1233" gradientUnits="userSpaceOnUse">
<stop offset="0.0910927" stop-color="#FC801D"/>
<stop offset="0.2312" stop-color="#B07F61"/>
<stop offset="0.4086" stop-color="#577DB3"/>
<stop offset="0.5334" stop-color="#1E7CE6"/>
<stop offset="0.5934" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="b" x1="61.991" x2="50.158" y1="36.9152" y2="1.55723" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FE2857"/>
<stop offset="0.0784" stop-color="#CB3979"/>
<stop offset="0.1601" stop-color="#9E4997"/>
<stop offset="0.2474" stop-color="#7557B2"/>
<stop offset="0.3392" stop-color="#5362C8"/>
<stop offset="0.4365" stop-color="#386CDA"/>
<stop offset="0.5414" stop-color="#2373E8"/>
<stop offset="0.6576" stop-color="#1478F2"/>
<stop offset="0.794" stop-color="#0B7BF8"/>
<stop offset="1" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="c" x1="10.0665" x2="53.8764" y1="16.4955" y2="88.9597" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FE2857"/>
<stop offset="0.0800816" stop-color="#FE295F"/>
<stop offset="0.2065" stop-color="#FF2D76"/>
<stop offset="0.3034" stop-color="#FF318C"/>
<stop offset="0.3846" stop-color="#EA3896"/>
<stop offset="0.5532" stop-color="#B248AE"/>
<stop offset="0.7923" stop-color="#5A63D6"/>
<stop offset="1" stop-color="#087CFA"/>
</linearGradient>
</defs>
<path fill="url(#a)" d="M11.2 49.4668L0.699951 41.3001L9 26L18.5 33.5L11.2 49.4668Z"/>
<path fill="#087CFA" d="M69.9999 18.6666L68.8333 59.2666L41.7666 70L27.0666 60.4333L41.7666 37.5L69.9999 18.6666Z"/>
<path fill="url(#b)" d="M70 18.6666L55.5 33L37 15L48.0666 1.16663L70 18.6666Z"/>
<path fill="url(#c)" d="M27.0667 60.4333L5.6 68.3667L10.0333 52.5L15.8667 33.1333L0 27.7667L10.0333 0L33.1333 2.8L54.5 31L55.5 33L27.0667 60.4333Z"/>
<g>
<path fill="#000000" d="M56 14H14V56H56V14Z"/>
</g>
<g>
<path fill="#FFFFFF" d="M27.1366 22.1433V19.25H19.2733V22.1433H21.4666V32.1067H19.2733V34.9767H27.1366V32.1067H24.92V22.1433H27.1366Z"/>
<path fill="#FFFFFF" d="M34.6967 35.21C33.46 35.21 32.4334 34.9767 31.6167 34.51C30.7767 34.0433 30.1 33.4833 29.5634 32.8533L31.7334 30.4267C32.1767 30.9167 32.6434 31.3133 33.0867 31.5933C33.5534 31.8733 34.0434 32.0133 34.6034 32.0133C35.2567 32.0133 35.77 31.8033 36.1434 31.3833C36.5167 30.9633 36.7034 30.31 36.7034 29.4V19.2733H40.25V29.5633C40.25 30.4967 40.1334 31.3133 39.8767 32.0133C39.62 32.7133 39.2467 33.2967 38.78 33.7633C38.29 34.2533 37.7067 34.6033 37.0067 34.86C36.3067 35.0933 35.5367 35.21 34.6967 35.21Z"/>
<path fill="#FFFFFF" d="M34.4166 48.6499H18.6666V51.3332H34.4166V48.6499Z"/>
</g>
</svg>
commands:
- id: inject-editor
apply:
component: editor-injector
- id: start-idea-server
exec:
component: editor-runtime
commandLine: nohup /idea-server/entrypoint-volume.sh > /idea-server/std.out
2>&1 &
events:
preStart:
- inject-editor
postStart:
- start-idea-server
components:
- name: idea-server
volume: {}
- name: editor-injector
container:
image: quay.io/che-incubator/che-idea-dev-server:next
command:
- /entrypoint-init-container.sh
volumeMounts:
- name: idea-server
path: /idea-server
memoryLimit: 256Mi
memoryRequest: 32Mi
cpuLimit: 500m
cpuRequest: 30m
- name: editor-runtime
container:
image: quay.io/devfile/universal-developer-image:latest
memoryLimit: 6144Mi
memoryRequest: 2048Mi
cpuLimit: 2000m
cpuRequest: 1500m
volumeMounts:
- name: idea-server
path: /idea-server
endpoints:
- name: idea-server
attributes:
type: main
cookiesAuthEnabled: true
discoverable: false
urlRewriteSupported: true
targetPort: 3400
exposure: public
secure: true
protocol: https
attributes:
app.kubernetes.io/component: editor-runtime
app.kubernetes.io/part-of: idea-server.eclipse.org
controller.devfile.io/container-contribution: true

1
go.mod
View File

@ -7,7 +7,6 @@ require (
github.com/devfile/api/v2 v2.2.2
github.com/devfile/devworkspace-operator v0.25.0
github.com/go-logr/logr v1.2.4
github.com/golang/mock v1.5.0
github.com/google/go-cmp v0.6.0
github.com/openshift/api v0.0.0-20200331152225-585af27e34fd
github.com/operator-framework/api v0.10.0

2
go.sum
View File

@ -810,8 +810,6 @@ github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18h
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019-2023 Red Hat, Inc.
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
Copyright (c) 2019-2023 Red Hat, Inc.
Copyright (c) 2019-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2023 Red Hat, Inc.
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/

View File

@ -1,81 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: pkg/util/process.go
// Package mock_util is a generated GoMock package.
package mock_util
import (
reflect "reflect"
gomock "github.com/golang/mock/gomock"
)
// MockRunnable is a mock of Runnable interface
type MockRunnable struct {
ctrl *gomock.Controller
recorder *MockRunnableMockRecorder
}
// MockRunnableMockRecorder is the mock recorder for MockRunnable
type MockRunnableMockRecorder struct {
mock *MockRunnable
}
// NewMockRunnable creates a new mock instance
func NewMockRunnable(ctrl *gomock.Controller) *MockRunnable {
mock := &MockRunnable{ctrl: ctrl}
mock.recorder = &MockRunnableMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockRunnable) EXPECT() *MockRunnableMockRecorder {
return m.recorder
}
// Run mocks base method
func (m *MockRunnable) Run(name string, args ...string) error {
m.ctrl.T.Helper()
varargs := []interface{}{name}
for _, a := range args {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Run", varargs...)
ret0, _ := ret[0].(error)
return ret0
}
// Run indicates an expected call of Run
func (mr *MockRunnableMockRecorder) Run(name interface{}, args ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{name}, args...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockRunnable)(nil).Run), varargs...)
}
// GetStdOut mocks base method
func (m *MockRunnable) GetStdOut() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetStdOut")
ret0, _ := ret[0].(string)
return ret0
}
// GetStdOut indicates an expected call of GetStdOut
func (mr *MockRunnableMockRecorder) GetStdOut() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStdOut", reflect.TypeOf((*MockRunnable)(nil).GetStdOut))
}
// GetStdErr mocks base method
func (m *MockRunnable) GetStdErr() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetStdErr")
ret0, _ := ret[0].(string)
return ret0
}
// GetStdErr indicates an expected call of GetStdErr
func (mr *MockRunnableMockRecorder) GetStdErr() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStdErr", reflect.TypeOf((*MockRunnable)(nil).GetStdErr))
}

View File

@ -124,6 +124,7 @@ const (
GatewayAuthenticationContainerName = "oauth-proxy"
GatewayAuthorizationContainerName = "kube-rbac-proxy"
KubernetesImagePullerComponentName = "kubernetes-image-puller"
EditorDefinitionComponentName = "editor-definition"
// common
CheFlavor = "che"

View File

@ -1,51 +0,0 @@
//
// Copyright (c) 2019-2023 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package utils
import (
"bytes"
"os/exec"
)
type Runnable interface {
Run(name string, args ...string) error
GetStdOut() string
GetStdErr() string
}
type Process struct {
cmd *exec.Cmd
stdout bytes.Buffer
stderr bytes.Buffer
}
func NewRunnable() Runnable {
return &Process{}
}
func (p *Process) Run(name string, args ...string) error {
p.cmd = exec.Command(name, args...)
p.stderr.Reset()
p.stdout.Reset()
p.cmd.Stdout = &p.stdout
p.cmd.Stderr = &p.stderr
return p.cmd.Run()
}
func (p *Process) GetStdOut() string {
return string(p.stdout.Bytes())
}
func (p *Process) GetStdErr() string {
return string(p.stderr.Bytes())
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019-2023 Red Hat, Inc.
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
@ -23,4 +23,6 @@ func init() {
infrastructure.InitializeForTesting(infrastructure.OpenShiftv4)
defaults.InitializeForTesting("../../../config/manager/manager.yaml")
editorsDefinitionsDir = "./test-editors-definitions"
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019-2023 Red Hat, Inc.
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
@ -16,6 +16,9 @@ import (
"fmt"
"strings"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"github.com/eclipse-che/che-operator/pkg/common/chetypes"
"github.com/eclipse-che/che-operator/pkg/common/constants"
"github.com/eclipse-che/che-operator/pkg/deploy/gateway"
@ -35,12 +38,25 @@ func NewPluginRegistryReconciler() *PluginRegistryReconciler {
func (p *PluginRegistryReconciler) Reconcile(ctx *chetypes.DeployContext) (reconcile.Result, bool, error) {
if ctx.CheCluster.Spec.Components.PluginRegistry.DisableInternalRegistry {
ctx.CheCluster.Status.PluginRegistryURL = ""
err := deploy.UpdateCheCRStatus(ctx, "PluginRegistryURL", "")
return reconcile.Result{}, err == nil, err
_, _ = deploy.DeleteNamespacedObject(ctx, constants.PluginRegistryName, &corev1.Service{})
_, _ = deploy.DeleteNamespacedObject(ctx, constants.PluginRegistryName, &corev1.ConfigMap{})
_, _ = deploy.DeleteNamespacedObject(ctx, editorsDefinitionsConfigMapName, &corev1.ConfigMap{})
_, _ = deploy.DeleteNamespacedObject(ctx, gateway.GatewayConfigMapNamePrefix+constants.PluginRegistryName, &corev1.ConfigMap{})
_, _ = deploy.DeleteNamespacedObject(ctx, constants.PluginRegistryName, &appsv1.Deployment{})
if ctx.CheCluster.Status.PluginRegistryURL != "" {
ctx.CheCluster.Status.PluginRegistryURL = ""
err := deploy.UpdateCheCRStatus(ctx, "PluginRegistryURL", "")
return reconcile.Result{}, err == nil, err
}
}
done, err := p.syncService(ctx)
done, err := p.syncEditors(ctx)
if !done {
return reconcile.Result{}, false, err
}
done, err = p.syncService(ctx)
if !done {
return reconcile.Result{}, false, err
}

View File

@ -0,0 +1,129 @@
//
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package pluginregistry
import (
"fmt"
"os"
"path/filepath"
"regexp"
"github.com/eclipse-che/che-operator/pkg/common/chetypes"
"github.com/eclipse-che/che-operator/pkg/common/constants"
"github.com/eclipse-che/che-operator/pkg/common/utils"
"github.com/eclipse-che/che-operator/pkg/deploy"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
)
var (
editorsDefinitionsDir = "/tmp/editors-definitions"
editorsDefinitionsConfigMapName = "editors-definitions"
)
func (p *PluginRegistryReconciler) syncEditors(ctx *chetypes.DeployContext) (bool, error) {
editorDefinitions, err := readEditorDefinitions()
if err != nil {
return false, err
}
done, err := syncEditorDefinitions(ctx, editorDefinitions)
if !done {
return false, err
}
return true, nil
}
func readEditorDefinitions() (map[string][]byte, error) {
editorDefinitions := make(map[string][]byte)
files, err := os.ReadDir(editorsDefinitionsDir)
if err != nil {
return editorDefinitions, err
}
for _, file := range files {
if !file.IsDir() {
fileName := file.Name()
editorContent, err := os.ReadFile(filepath.Join(editorsDefinitionsDir, fileName))
if err != nil {
return editorDefinitions, err
}
var devfile map[string]interface{}
err = yaml.Unmarshal(editorContent, &devfile)
if err != nil {
return editorDefinitions, err
}
updateEditorDefinitionImageFromEnv(devfile)
editorContent, err = yaml.Marshal(devfile)
if err != nil {
return editorDefinitions, err
}
editorDefinitions[fileName] = editorContent
}
}
return editorDefinitions, nil
}
func updateEditorDefinitionImageFromEnv(devfile map[string]interface{}) {
notAllowedCharsReg, _ := regexp.Compile("[^a-zA-Z0-9]+")
metadata := devfile["metadata"].(map[string]interface{})
devfileName := metadata["name"].(string)
attributes := metadata["attributes"].(map[string]interface{})
devfileVersion := attributes["version"].(string)
components := devfile["components"].([]interface{})
for _, component := range components {
componentName := component.(map[string]interface{})["name"].(string)
if container, ok := component.(map[string]interface{})["container"].(map[string]interface{}); ok {
imageEnvName := fmt.Sprintf("RELATED_IMAGE_%s_%s_%s", devfileName, devfileVersion, componentName)
imageEnvName = notAllowedCharsReg.ReplaceAllString(imageEnvName, "_")
imageEnvName = utils.GetArchitectureDependentEnvName(imageEnvName)
if imageEnvValue, ok := os.LookupEnv(imageEnvName); ok {
container["image"] = imageEnvValue
}
}
}
}
func syncEditorDefinitions(ctx *chetypes.DeployContext, editorDefinitions map[string][]byte) (bool, error) {
cm := &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: editorsDefinitionsConfigMapName,
Namespace: ctx.CheCluster.Namespace,
Labels: deploy.GetLabels(constants.EditorDefinitionComponentName),
Annotations: map[string]string{},
},
Data: map[string]string{},
}
for fileName, content := range editorDefinitions {
cm.Data[fileName] = string(content)
}
return deploy.Sync(ctx, cm, deploy.ConfigMapDiffOpts)
}

View File

@ -0,0 +1,68 @@
//
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package pluginregistry
import (
"os"
"testing"
"github.com/eclipse-che/che-operator/pkg/common/test"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/yaml"
)
func TestReadEditorDefinitions(t *testing.T) {
err := os.Setenv("RELATED_IMAGE_che_code_1_2_3_component_a", "image-new-a")
assert.NoError(t, err)
defer func() {
_ = os.Setenv("RELATED_IMAGE_che_code_1_2_3_component_a", "")
}()
editorDefinitions, err := readEditorDefinitions()
assert.NoError(t, err)
assert.NotEmpty(t, editorDefinitions)
assert.Equal(t, 1, len(editorDefinitions))
assert.Contains(t, editorDefinitions, "devfile.yaml")
var devfile map[string]interface{}
err = yaml.Unmarshal(editorDefinitions["devfile.yaml"], &devfile)
assert.NoError(t, err)
components := devfile["components"].([]interface{})
component := components[0].(map[string]interface{})
container := component["container"].(map[string]interface{})
assert.Equal(t, "image-new-a", container["image"])
component = components[1].(map[string]interface{})
container = component["container"].(map[string]interface{})
assert.Equal(t, "image-b", container["image"])
component = components[2].(map[string]interface{})
container, ok := component["container"].(map[string]interface{})
assert.False(t, ok)
}
func TestSyncEditorDefinitions(t *testing.T) {
ctx := test.GetDeployContext(nil, []runtime.Object{})
editorDefinitions, err := readEditorDefinitions()
assert.NoError(t, err)
assert.NotEmpty(t, editorDefinitions)
done, err := syncEditorDefinitions(ctx, editorDefinitions)
assert.NoError(t, err)
assert.True(t, done)
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019-2023 Red Hat, Inc.
// Copyright (c) 2019-2024 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
@ -37,6 +37,7 @@ func TestPluginRegistryReconcile(t *testing.T) {
assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.Service{}))
assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.ConfigMap{}))
assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "editors-definitions", Namespace: "eclipse-che"}, &corev1.ConfigMap{}))
assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &appsv1.Deployment{}))
assert.NotEmpty(t, ctx.CheCluster.Status.PluginRegistryURL)
}

View File

@ -0,0 +1,25 @@
#
# Copyright (c) 2019-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
schemaVersion: 2.2.2
metadata:
name: che-code
attributes:
version: 1.2.3
components:
- name: component-a
container:
image: image-a
- name: component-b
container:
image: image-b
- name: component-c

View File

@ -1,12 +0,0 @@
# This is the official list of GoMock authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS files.
# See the latter for an explanation.
# Names should be added to this file as
# Name or Organization <email address>
# The email address is not required for organizations.
# Please keep the list sorted.
Alex Reece <awreece@gmail.com>
Google Inc.

View File

@ -1,37 +0,0 @@
# This is the official list of people who can contribute (and typically
# have contributed) code to the gomock repository.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
#
# The submission process automatically checks to make sure
# that people submitting code are listed in this file (by email address).
#
# Names should be added to this file only after verifying that
# the individual or the individual's organization has agreed to
# the appropriate Contributor License Agreement, found here:
#
# http://code.google.com/legal/individual-cla-v1.0.html
# http://code.google.com/legal/corporate-cla-v1.0.html
#
# The agreement for individuals can be filled out on the web.
#
# When adding J Random Contributor's name to this file,
# either J's name or J's organization's name should be
# added to the AUTHORS file, depending on whether the
# individual or corporate CLA was used.
# Names should be added to this file like so:
# Name <email address>
#
# An entry with two email addresses specifies that the
# first address should be used in the submit logs and
# that the second address should be recognized as the
# same person when interacting with Rietveld.
# Please keep the list sorted.
Aaron Jacobs <jacobsa@google.com> <aaronjjacobs@gmail.com>
Alex Reece <awreece@gmail.com>
David Symonds <dsymonds@golang.org>
Ryan Barrett <ryanb@google.com>

202
vendor/github.com/golang/mock/LICENSE generated vendored
View File

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,433 +0,0 @@
// Copyright 2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package gomock
import (
"fmt"
"reflect"
"strconv"
"strings"
)
// Call represents an expected call to a mock.
type Call struct {
t TestHelper // for triggering test failures on invalid call setup
receiver interface{} // the receiver of the method call
method string // the name of the method
methodType reflect.Type // the type of the method
args []Matcher // the args
origin string // file and line number of call setup
preReqs []*Call // prerequisite calls
// Expectations
minCalls, maxCalls int
numCalls int // actual number made
// actions are called when this Call is called. Each action gets the args and
// can set the return values by returning a non-nil slice. Actions run in the
// order they are created.
actions []func([]interface{}) []interface{}
}
// newCall creates a *Call. It requires the method type in order to support
// unexported methods.
func newCall(t TestHelper, receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call {
t.Helper()
// TODO: check arity, types.
margs := make([]Matcher, len(args))
for i, arg := range args {
if m, ok := arg.(Matcher); ok {
margs[i] = m
} else if arg == nil {
// Handle nil specially so that passing a nil interface value
// will match the typed nils of concrete args.
margs[i] = Nil()
} else {
margs[i] = Eq(arg)
}
}
// callerInfo's skip should be updated if the number of calls between the user's test
// and this line changes, i.e. this code is wrapped in another anonymous function.
// 0 is us, 1 is RecordCallWithMethodType(), 2 is the generated recorder, and 3 is the user's test.
origin := callerInfo(3)
actions := []func([]interface{}) []interface{}{func([]interface{}) []interface{} {
// Synthesize the zero value for each of the return args' types.
rets := make([]interface{}, methodType.NumOut())
for i := 0; i < methodType.NumOut(); i++ {
rets[i] = reflect.Zero(methodType.Out(i)).Interface()
}
return rets
}}
return &Call{t: t, receiver: receiver, method: method, methodType: methodType,
args: margs, origin: origin, minCalls: 1, maxCalls: 1, actions: actions}
}
// AnyTimes allows the expectation to be called 0 or more times
func (c *Call) AnyTimes() *Call {
c.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity
return c
}
// MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called or if MaxTimes
// was previously called with 1, MinTimes also sets the maximum number of calls to infinity.
func (c *Call) MinTimes(n int) *Call {
c.minCalls = n
if c.maxCalls == 1 {
c.maxCalls = 1e8
}
return c
}
// MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called or if MinTimes was
// previously called with 1, MaxTimes also sets the minimum number of calls to 0.
func (c *Call) MaxTimes(n int) *Call {
c.maxCalls = n
if c.minCalls == 1 {
c.minCalls = 0
}
return c
}
// DoAndReturn declares the action to run when the call is matched.
// The return values from this function are returned by the mocked function.
// It takes an interface{} argument to support n-arity functions.
func (c *Call) DoAndReturn(f interface{}) *Call {
// TODO: Check arity and types here, rather than dying badly elsewhere.
v := reflect.ValueOf(f)
c.addAction(func(args []interface{}) []interface{} {
vargs := make([]reflect.Value, len(args))
ft := v.Type()
for i := 0; i < len(args); i++ {
if args[i] != nil {
vargs[i] = reflect.ValueOf(args[i])
} else {
// Use the zero value for the arg.
vargs[i] = reflect.Zero(ft.In(i))
}
}
vrets := v.Call(vargs)
rets := make([]interface{}, len(vrets))
for i, ret := range vrets {
rets[i] = ret.Interface()
}
return rets
})
return c
}
// Do declares the action to run when the call is matched. The function's
// return values are ignored to retain backward compatibility. To use the
// return values call DoAndReturn.
// It takes an interface{} argument to support n-arity functions.
func (c *Call) Do(f interface{}) *Call {
// TODO: Check arity and types here, rather than dying badly elsewhere.
v := reflect.ValueOf(f)
c.addAction(func(args []interface{}) []interface{} {
vargs := make([]reflect.Value, len(args))
ft := v.Type()
for i := 0; i < len(args); i++ {
if args[i] != nil {
vargs[i] = reflect.ValueOf(args[i])
} else {
// Use the zero value for the arg.
vargs[i] = reflect.Zero(ft.In(i))
}
}
v.Call(vargs)
return nil
})
return c
}
// Return declares the values to be returned by the mocked function call.
func (c *Call) Return(rets ...interface{}) *Call {
c.t.Helper()
mt := c.methodType
if len(rets) != mt.NumOut() {
c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d [%s]",
c.receiver, c.method, len(rets), mt.NumOut(), c.origin)
}
for i, ret := range rets {
if got, want := reflect.TypeOf(ret), mt.Out(i); got == want {
// Identical types; nothing to do.
} else if got == nil {
// Nil needs special handling.
switch want.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
// ok
default:
c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable [%s]",
i, c.receiver, c.method, want, c.origin)
}
} else if got.AssignableTo(want) {
// Assignable type relation. Make the assignment now so that the generated code
// can return the values with a type assertion.
v := reflect.New(want).Elem()
v.Set(reflect.ValueOf(ret))
rets[i] = v.Interface()
} else {
c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v [%s]",
i, c.receiver, c.method, got, want, c.origin)
}
}
c.addAction(func([]interface{}) []interface{} {
return rets
})
return c
}
// Times declares the exact number of times a function call is expected to be executed.
func (c *Call) Times(n int) *Call {
c.minCalls, c.maxCalls = n, n
return c
}
// SetArg declares an action that will set the nth argument's value,
// indirected through a pointer. Or, in the case of a slice, SetArg
// will copy value's elements into the nth argument.
func (c *Call) SetArg(n int, value interface{}) *Call {
c.t.Helper()
mt := c.methodType
// TODO: This will break on variadic methods.
// We will need to check those at invocation time.
if n < 0 || n >= mt.NumIn() {
c.t.Fatalf("SetArg(%d, ...) called for a method with %d args [%s]",
n, mt.NumIn(), c.origin)
}
// Permit setting argument through an interface.
// In the interface case, we don't (nay, can't) check the type here.
at := mt.In(n)
switch at.Kind() {
case reflect.Ptr:
dt := at.Elem()
if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) {
c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v [%s]",
n, vt, dt, c.origin)
}
case reflect.Interface:
// nothing to do
case reflect.Slice:
// nothing to do
default:
c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface non-slice type %v [%s]",
n, at, c.origin)
}
c.addAction(func(args []interface{}) []interface{} {
v := reflect.ValueOf(value)
switch reflect.TypeOf(args[n]).Kind() {
case reflect.Slice:
setSlice(args[n], v)
default:
reflect.ValueOf(args[n]).Elem().Set(v)
}
return nil
})
return c
}
// isPreReq returns true if other is a direct or indirect prerequisite to c.
func (c *Call) isPreReq(other *Call) bool {
for _, preReq := range c.preReqs {
if other == preReq || preReq.isPreReq(other) {
return true
}
}
return false
}
// After declares that the call may only match after preReq has been exhausted.
func (c *Call) After(preReq *Call) *Call {
c.t.Helper()
if c == preReq {
c.t.Fatalf("A call isn't allowed to be its own prerequisite")
}
if preReq.isPreReq(c) {
c.t.Fatalf("Loop in call order: %v is a prerequisite to %v (possibly indirectly).", c, preReq)
}
c.preReqs = append(c.preReqs, preReq)
return c
}
// Returns true if the minimum number of calls have been made.
func (c *Call) satisfied() bool {
return c.numCalls >= c.minCalls
}
// Returns true if the maximum number of calls have been made.
func (c *Call) exhausted() bool {
return c.numCalls >= c.maxCalls
}
func (c *Call) String() string {
args := make([]string, len(c.args))
for i, arg := range c.args {
args[i] = arg.String()
}
arguments := strings.Join(args, ", ")
return fmt.Sprintf("%T.%v(%s) %s", c.receiver, c.method, arguments, c.origin)
}
// Tests if the given call matches the expected call.
// If yes, returns nil. If no, returns error with message explaining why it does not match.
func (c *Call) matches(args []interface{}) error {
if !c.methodType.IsVariadic() {
if len(args) != len(c.args) {
return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: %d",
c.origin, len(args), len(c.args))
}
for i, m := range c.args {
if !m.Matches(args[i]) {
return fmt.Errorf(
"expected call at %s doesn't match the argument at index %d.\nGot: %v\nWant: %v",
c.origin, i, formatGottenArg(m, args[i]), m,
)
}
}
} else {
if len(c.args) < c.methodType.NumIn()-1 {
return fmt.Errorf("expected call at %s has the wrong number of matchers. Got: %d, want: %d",
c.origin, len(c.args), c.methodType.NumIn()-1)
}
if len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) {
return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: %d",
c.origin, len(args), len(c.args))
}
if len(args) < len(c.args)-1 {
return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d",
c.origin, len(args), len(c.args)-1)
}
for i, m := range c.args {
if i < c.methodType.NumIn()-1 {
// Non-variadic args
if !m.Matches(args[i]) {
return fmt.Errorf("expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v",
c.origin, strconv.Itoa(i), formatGottenArg(m, args[i]), m)
}
continue
}
// The last arg has a possibility of a variadic argument, so let it branch
// sample: Foo(a int, b int, c ...int)
if i < len(c.args) && i < len(args) {
if m.Matches(args[i]) {
// Got Foo(a, b, c) want Foo(matcherA, matcherB, gomock.Any())
// Got Foo(a, b, c) want Foo(matcherA, matcherB, someSliceMatcher)
// Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC)
// Got Foo(a, b) want Foo(matcherA, matcherB)
// Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD)
continue
}
}
// The number of actual args don't match the number of matchers,
// or the last matcher is a slice and the last arg is not.
// If this function still matches it is because the last matcher
// matches all the remaining arguments or the lack of any.
// Convert the remaining arguments, if any, into a slice of the
// expected type.
vargsType := c.methodType.In(c.methodType.NumIn() - 1)
vargs := reflect.MakeSlice(vargsType, 0, len(args)-i)
for _, arg := range args[i:] {
vargs = reflect.Append(vargs, reflect.ValueOf(arg))
}
if m.Matches(vargs.Interface()) {
// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, gomock.Any())
// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, someSliceMatcher)
// Got Foo(a, b) want Foo(matcherA, matcherB, gomock.Any())
// Got Foo(a, b) want Foo(matcherA, matcherB, someEmptySliceMatcher)
break
}
// Wrong number of matchers or not match. Fail.
// Got Foo(a, b) want Foo(matcherA, matcherB, matcherC, matcherD)
// Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC, matcherD)
// Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD, matcherE)
// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, matcherC, matcherD)
// Got Foo(a, b, c) want Foo(matcherA, matcherB)
return fmt.Errorf("expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v",
c.origin, strconv.Itoa(i), formatGottenArg(m, args[i:]), c.args[i])
}
}
// Check that all prerequisite calls have been satisfied.
for _, preReqCall := range c.preReqs {
if !preReqCall.satisfied() {
return fmt.Errorf("Expected call at %s doesn't have a prerequisite call satisfied:\n%v\nshould be called before:\n%v",
c.origin, preReqCall, c)
}
}
// Check that the call is not exhausted.
if c.exhausted() {
return fmt.Errorf("expected call at %s has already been called the max number of times", c.origin)
}
return nil
}
// dropPrereqs tells the expected Call to not re-check prerequisite calls any
// longer, and to return its current set.
func (c *Call) dropPrereqs() (preReqs []*Call) {
preReqs = c.preReqs
c.preReqs = nil
return
}
func (c *Call) call() []func([]interface{}) []interface{} {
c.numCalls++
return c.actions
}
// InOrder declares that the given calls should occur in order.
func InOrder(calls ...*Call) {
for i := 1; i < len(calls); i++ {
calls[i].After(calls[i-1])
}
}
func setSlice(arg interface{}, v reflect.Value) {
va := reflect.ValueOf(arg)
for i := 0; i < v.Len(); i++ {
va.Index(i).Set(v.Index(i))
}
}
func (c *Call) addAction(action func([]interface{}) []interface{}) {
c.actions = append(c.actions, action)
}
func formatGottenArg(m Matcher, arg interface{}) string {
got := fmt.Sprintf("%v", arg)
if gs, ok := m.(GotFormatter); ok {
got = gs.Got(arg)
}
return got
}

View File

@ -1,112 +0,0 @@
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package gomock
import (
"bytes"
"fmt"
)
// callSet represents a set of expected calls, indexed by receiver and method
// name.
type callSet struct {
// Calls that are still expected.
expected map[callSetKey][]*Call
// Calls that have been exhausted.
exhausted map[callSetKey][]*Call
}
// callSetKey is the key in the maps in callSet
type callSetKey struct {
receiver interface{}
fname string
}
func newCallSet() *callSet {
return &callSet{make(map[callSetKey][]*Call), make(map[callSetKey][]*Call)}
}
// Add adds a new expected call.
func (cs callSet) Add(call *Call) {
key := callSetKey{call.receiver, call.method}
m := cs.expected
if call.exhausted() {
m = cs.exhausted
}
m[key] = append(m[key], call)
}
// Remove removes an expected call.
func (cs callSet) Remove(call *Call) {
key := callSetKey{call.receiver, call.method}
calls := cs.expected[key]
for i, c := range calls {
if c == call {
// maintain order for remaining calls
cs.expected[key] = append(calls[:i], calls[i+1:]...)
cs.exhausted[key] = append(cs.exhausted[key], call)
break
}
}
}
// FindMatch searches for a matching call. Returns error with explanation message if no call matched.
func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) (*Call, error) {
key := callSetKey{receiver, method}
// Search through the expected calls.
expected := cs.expected[key]
var callsErrors bytes.Buffer
for _, call := range expected {
err := call.matches(args)
if err != nil {
_, _ = fmt.Fprintf(&callsErrors, "\n%v", err)
} else {
return call, nil
}
}
// If we haven't found a match then search through the exhausted calls so we
// get useful error messages.
exhausted := cs.exhausted[key]
for _, call := range exhausted {
if err := call.matches(args); err != nil {
_, _ = fmt.Fprintf(&callsErrors, "\n%v", err)
continue
}
_, _ = fmt.Fprintf(
&callsErrors, "all expected calls for method %q have been exhausted", method,
)
}
if len(expected)+len(exhausted) == 0 {
_, _ = fmt.Fprintf(&callsErrors, "there are no expected calls of the method %q for that receiver", method)
}
return nil, fmt.Errorf(callsErrors.String())
}
// Failures returns the calls that are not satisfied.
func (cs callSet) Failures() []*Call {
failures := make([]*Call, 0, len(cs.expected))
for _, calls := range cs.expected {
for _, call := range calls {
if !call.satisfied() {
failures = append(failures, call)
}
}
}
return failures
}

View File

@ -1,333 +0,0 @@
// Copyright 2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package gomock is a mock framework for Go.
//
// Standard usage:
// (1) Define an interface that you wish to mock.
// type MyInterface interface {
// SomeMethod(x int64, y string)
// }
// (2) Use mockgen to generate a mock from the interface.
// (3) Use the mock in a test:
// func TestMyThing(t *testing.T) {
// mockCtrl := gomock.NewController(t)
// defer mockCtrl.Finish()
//
// mockObj := something.NewMockMyInterface(mockCtrl)
// mockObj.EXPECT().SomeMethod(4, "blah")
// // pass mockObj to a real object and play with it.
// }
//
// By default, expected calls are not enforced to run in any particular order.
// Call order dependency can be enforced by use of InOrder and/or Call.After.
// Call.After can create more varied call order dependencies, but InOrder is
// often more convenient.
//
// The following examples create equivalent call order dependencies.
//
// Example of using Call.After to chain expected call order:
//
// firstCall := mockObj.EXPECT().SomeMethod(1, "first")
// secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall)
// mockObj.EXPECT().SomeMethod(3, "third").After(secondCall)
//
// Example of using InOrder to declare expected call order:
//
// gomock.InOrder(
// mockObj.EXPECT().SomeMethod(1, "first"),
// mockObj.EXPECT().SomeMethod(2, "second"),
// mockObj.EXPECT().SomeMethod(3, "third"),
// )
package gomock
import (
"context"
"fmt"
"reflect"
"runtime"
"sync"
)
// A TestReporter is something that can be used to report test failures. It
// is satisfied by the standard library's *testing.T.
type TestReporter interface {
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
}
// TestHelper is a TestReporter that has the Helper method. It is satisfied
// by the standard library's *testing.T.
type TestHelper interface {
TestReporter
Helper()
}
// cleanuper is used to check if TestHelper also has the `Cleanup` method. A
// common pattern is to pass in a `*testing.T` to
// `NewController(t TestReporter)`. In Go 1.14+, `*testing.T` has a cleanup
// method. This can be utilized to call `Finish()` so the caller of this library
// does not have to.
type cleanuper interface {
Cleanup(func())
}
// A Controller represents the top-level control of a mock ecosystem. It
// defines the scope and lifetime of mock objects, as well as their
// expectations. It is safe to call Controller's methods from multiple
// goroutines. Each test should create a new Controller and invoke Finish via
// defer.
//
// func TestFoo(t *testing.T) {
// ctrl := gomock.NewController(t)
// defer ctrl.Finish()
// // ..
// }
//
// func TestBar(t *testing.T) {
// t.Run("Sub-Test-1", st) {
// ctrl := gomock.NewController(st)
// defer ctrl.Finish()
// // ..
// })
// t.Run("Sub-Test-2", st) {
// ctrl := gomock.NewController(st)
// defer ctrl.Finish()
// // ..
// })
// })
type Controller struct {
// T should only be called within a generated mock. It is not intended to
// be used in user code and may be changed in future versions. T is the
// TestReporter passed in when creating the Controller via NewController.
// If the TestReporter does not implement a TestHelper it will be wrapped
// with a nopTestHelper.
T TestHelper
mu sync.Mutex
expectedCalls *callSet
finished bool
}
// NewController returns a new Controller. It is the preferred way to create a
// Controller.
//
// New in go1.14+, if you are passing a *testing.T into this function you no
// longer need to call ctrl.Finish() in your test methods
func NewController(t TestReporter) *Controller {
h, ok := t.(TestHelper)
if !ok {
h = &nopTestHelper{t}
}
ctrl := &Controller{
T: h,
expectedCalls: newCallSet(),
}
if c, ok := isCleanuper(ctrl.T); ok {
c.Cleanup(func() {
ctrl.T.Helper()
ctrl.finish(true, nil)
})
}
return ctrl
}
type cancelReporter struct {
t TestHelper
cancel func()
}
func (r *cancelReporter) Errorf(format string, args ...interface{}) {
r.t.Errorf(format, args...)
}
func (r *cancelReporter) Fatalf(format string, args ...interface{}) {
defer r.cancel()
r.t.Fatalf(format, args...)
}
func (r *cancelReporter) Helper() {
r.t.Helper()
}
// WithContext returns a new Controller and a Context, which is cancelled on any
// fatal failure.
func WithContext(ctx context.Context, t TestReporter) (*Controller, context.Context) {
h, ok := t.(TestHelper)
if !ok {
h = &nopTestHelper{t: t}
}
ctx, cancel := context.WithCancel(ctx)
return NewController(&cancelReporter{t: h, cancel: cancel}), ctx
}
type nopTestHelper struct {
t TestReporter
}
func (h *nopTestHelper) Errorf(format string, args ...interface{}) {
h.t.Errorf(format, args...)
}
func (h *nopTestHelper) Fatalf(format string, args ...interface{}) {
h.t.Fatalf(format, args...)
}
func (h nopTestHelper) Helper() {}
// RecordCall is called by a mock. It should not be called by user code.
func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
ctrl.T.Helper()
recv := reflect.ValueOf(receiver)
for i := 0; i < recv.Type().NumMethod(); i++ {
if recv.Type().Method(i).Name == method {
return ctrl.RecordCallWithMethodType(receiver, method, recv.Method(i).Type(), args...)
}
}
ctrl.T.Fatalf("gomock: failed finding method %s on %T", method, receiver)
panic("unreachable")
}
// RecordCallWithMethodType is called by a mock. It should not be called by user code.
func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call {
ctrl.T.Helper()
call := newCall(ctrl.T, receiver, method, methodType, args...)
ctrl.mu.Lock()
defer ctrl.mu.Unlock()
ctrl.expectedCalls.Add(call)
return call
}
// Call is called by a mock. It should not be called by user code.
func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
ctrl.T.Helper()
// Nest this code so we can use defer to make sure the lock is released.
actions := func() []func([]interface{}) []interface{} {
ctrl.T.Helper()
ctrl.mu.Lock()
defer ctrl.mu.Unlock()
expected, err := ctrl.expectedCalls.FindMatch(receiver, method, args)
if err != nil {
// callerInfo's skip should be updated if the number of calls between the user's test
// and this line changes, i.e. this code is wrapped in another anonymous function.
// 0 is us, 1 is controller.Call(), 2 is the generated mock, and 3 is the user's test.
origin := callerInfo(3)
ctrl.T.Fatalf("Unexpected call to %T.%v(%v) at %s because: %s", receiver, method, args, origin, err)
}
// Two things happen here:
// * the matching call no longer needs to check prerequite calls,
// * and the prerequite calls are no longer expected, so remove them.
preReqCalls := expected.dropPrereqs()
for _, preReqCall := range preReqCalls {
ctrl.expectedCalls.Remove(preReqCall)
}
actions := expected.call()
if expected.exhausted() {
ctrl.expectedCalls.Remove(expected)
}
return actions
}()
var rets []interface{}
for _, action := range actions {
if r := action(args); r != nil {
rets = r
}
}
return rets
}
// Finish checks to see if all the methods that were expected to be called
// were called. It should be invoked for each Controller. It is not idempotent
// and therefore can only be invoked once.
func (ctrl *Controller) Finish() {
// If we're currently panicking, probably because this is a deferred call.
// This must be recovered in the deferred function.
err := recover()
ctrl.finish(false, err)
}
func (ctrl *Controller) finish(cleanup bool, panicErr interface{}) {
ctrl.T.Helper()
ctrl.mu.Lock()
defer ctrl.mu.Unlock()
if ctrl.finished {
if _, ok := isCleanuper(ctrl.T); !ok {
ctrl.T.Fatalf("Controller.Finish was called more than once. It has to be called exactly once.")
}
return
}
ctrl.finished = true
// Short-circuit, pass through the panic.
if panicErr != nil {
panic(panicErr)
}
// Check that all remaining expected calls are satisfied.
failures := ctrl.expectedCalls.Failures()
for _, call := range failures {
ctrl.T.Errorf("missing call(s) to %v", call)
}
if len(failures) != 0 {
if !cleanup {
ctrl.T.Fatalf("aborting test due to missing call(s)")
return
}
ctrl.T.Errorf("aborting test due to missing call(s)")
}
}
// callerInfo returns the file:line of the call site. skip is the number
// of stack frames to skip when reporting. 0 is callerInfo's call site.
func callerInfo(skip int) string {
if _, file, line, ok := runtime.Caller(skip + 1); ok {
return fmt.Sprintf("%s:%d", file, line)
}
return "unknown file"
}
// isCleanuper checks it if t's base TestReporter has a Cleanup method.
func isCleanuper(t TestReporter) (cleanuper, bool) {
tr := unwrapTestReporter(t)
c, ok := tr.(cleanuper)
return c, ok
}
// unwrapTestReporter unwraps TestReporter to the base implementation.
func unwrapTestReporter(t TestReporter) TestReporter {
tr := t
switch nt := t.(type) {
case *cancelReporter:
tr = nt.t
if h, check := tr.(*nopTestHelper); check {
tr = h.t
}
case *nopTestHelper:
tr = nt.t
default:
// not wrapped
}
return tr
}

View File

@ -1,269 +0,0 @@
// Copyright 2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package gomock
import (
"fmt"
"reflect"
"strings"
)
// A Matcher is a representation of a class of values.
// It is used to represent the valid or expected arguments to a mocked method.
type Matcher interface {
// Matches returns whether x is a match.
Matches(x interface{}) bool
// String describes what the matcher matches.
String() string
}
// WantFormatter modifies the given Matcher's String() method to the given
// Stringer. This allows for control on how the "Want" is formatted when
// printing .
func WantFormatter(s fmt.Stringer, m Matcher) Matcher {
type matcher interface {
Matches(x interface{}) bool
}
return struct {
matcher
fmt.Stringer
}{
matcher: m,
Stringer: s,
}
}
// StringerFunc type is an adapter to allow the use of ordinary functions as
// a Stringer. If f is a function with the appropriate signature,
// StringerFunc(f) is a Stringer that calls f.
type StringerFunc func() string
// String implements fmt.Stringer.
func (f StringerFunc) String() string {
return f()
}
// GotFormatter is used to better print failure messages. If a matcher
// implements GotFormatter, it will use the result from Got when printing
// the failure message.
type GotFormatter interface {
// Got is invoked with the received value. The result is used when
// printing the failure message.
Got(got interface{}) string
}
// GotFormatterFunc type is an adapter to allow the use of ordinary
// functions as a GotFormatter. If f is a function with the appropriate
// signature, GotFormatterFunc(f) is a GotFormatter that calls f.
type GotFormatterFunc func(got interface{}) string
// Got implements GotFormatter.
func (f GotFormatterFunc) Got(got interface{}) string {
return f(got)
}
// GotFormatterAdapter attaches a GotFormatter to a Matcher.
func GotFormatterAdapter(s GotFormatter, m Matcher) Matcher {
return struct {
GotFormatter
Matcher
}{
GotFormatter: s,
Matcher: m,
}
}
type anyMatcher struct{}
func (anyMatcher) Matches(interface{}) bool {
return true
}
func (anyMatcher) String() string {
return "is anything"
}
type eqMatcher struct {
x interface{}
}
func (e eqMatcher) Matches(x interface{}) bool {
// In case, some value is nil
if e.x == nil || x == nil {
return reflect.DeepEqual(e.x, x)
}
// Check if types assignable and convert them to common type
x1Val := reflect.ValueOf(e.x)
x2Val := reflect.ValueOf(x)
if x1Val.Type().AssignableTo(x2Val.Type()) {
x1ValConverted := x1Val.Convert(x2Val.Type())
return reflect.DeepEqual(x1ValConverted.Interface(), x2Val.Interface())
}
return false
}
func (e eqMatcher) String() string {
return fmt.Sprintf("is equal to %v", e.x)
}
type nilMatcher struct{}
func (nilMatcher) Matches(x interface{}) bool {
if x == nil {
return true
}
v := reflect.ValueOf(x)
switch v.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map,
reflect.Ptr, reflect.Slice:
return v.IsNil()
}
return false
}
func (nilMatcher) String() string {
return "is nil"
}
type notMatcher struct {
m Matcher
}
func (n notMatcher) Matches(x interface{}) bool {
return !n.m.Matches(x)
}
func (n notMatcher) String() string {
// TODO: Improve this if we add a NotString method to the Matcher interface.
return "not(" + n.m.String() + ")"
}
type assignableToTypeOfMatcher struct {
targetType reflect.Type
}
func (m assignableToTypeOfMatcher) Matches(x interface{}) bool {
return reflect.TypeOf(x).AssignableTo(m.targetType)
}
func (m assignableToTypeOfMatcher) String() string {
return "is assignable to " + m.targetType.Name()
}
type allMatcher struct {
matchers []Matcher
}
func (am allMatcher) Matches(x interface{}) bool {
for _, m := range am.matchers {
if !m.Matches(x) {
return false
}
}
return true
}
func (am allMatcher) String() string {
ss := make([]string, 0, len(am.matchers))
for _, matcher := range am.matchers {
ss = append(ss, matcher.String())
}
return strings.Join(ss, "; ")
}
type lenMatcher struct {
i int
}
func (m lenMatcher) Matches(x interface{}) bool {
v := reflect.ValueOf(x)
switch v.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == m.i
default:
return false
}
}
func (m lenMatcher) String() string {
return fmt.Sprintf("has length %d", m.i)
}
// Constructors
// All returns a composite Matcher that returns true if and only all of the
// matchers return true.
func All(ms ...Matcher) Matcher { return allMatcher{ms} }
// Any returns a matcher that always matches.
func Any() Matcher { return anyMatcher{} }
// Eq returns a matcher that matches on equality.
//
// Example usage:
// Eq(5).Matches(5) // returns true
// Eq(5).Matches(4) // returns false
func Eq(x interface{}) Matcher { return eqMatcher{x} }
// Len returns a matcher that matches on length. This matcher returns false if
// is compared to a type that is not an array, chan, map, slice, or string.
func Len(i int) Matcher {
return lenMatcher{i}
}
// Nil returns a matcher that matches if the received value is nil.
//
// Example usage:
// var x *bytes.Buffer
// Nil().Matches(x) // returns true
// x = &bytes.Buffer{}
// Nil().Matches(x) // returns false
func Nil() Matcher { return nilMatcher{} }
// Not reverses the results of its given child matcher.
//
// Example usage:
// Not(Eq(5)).Matches(4) // returns true
// Not(Eq(5)).Matches(5) // returns false
func Not(x interface{}) Matcher {
if m, ok := x.(Matcher); ok {
return notMatcher{m}
}
return notMatcher{Eq(x)}
}
// AssignableToTypeOf is a Matcher that matches if the parameter to the mock
// function is assignable to the type of the parameter to this function.
//
// Example usage:
// var s fmt.Stringer = &bytes.Buffer{}
// AssignableToTypeOf(s).Matches(time.Second) // returns true
// AssignableToTypeOf(s).Matches(99) // returns false
//
// var ctx = reflect.TypeOf((*context.Context)(nil)).Elem()
// AssignableToTypeOf(ctx).Matches(context.Background()) // returns true
func AssignableToTypeOf(x interface{}) Matcher {
if xt, ok := x.(reflect.Type); ok {
return assignableToTypeOfMatcher{xt}
}
return assignableToTypeOfMatcher{reflect.TypeOf(x)}
}

3
vendor/modules.txt vendored
View File

@ -80,9 +80,6 @@ github.com/gogo/protobuf/sortkeys
# github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da => github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
## explicit
github.com/golang/groupcache/lru
# github.com/golang/mock v1.5.0
## explicit; go 1.11
github.com/golang/mock/gomock
# github.com/golang/protobuf v1.5.3 => github.com/golang/protobuf v1.4.3
## explicit; go 1.9
github.com/golang/protobuf/jsonpb