Commit a1be63b2 authored by Nick Kipling's avatar Nick Kipling Committed by Fatih Acet

Added Conan installation instructions

Created conan_installation component
Updated details component to display instructions
Added url helper
Updated constants and tracking
Added tests
parent 5e046a6c
---
title: Added Conan installation instructions to Conan package details page
merge_request: 22390
author:
type: added
......@@ -13,6 +13,7 @@ import Tracking from '~/tracking';
import PackageInformation from './information.vue';
import NpmInstallation from './npm_installation.vue';
import MavenInstallation from './maven_installation.vue';
import ConanInstallation from './conan_installation.vue';
import Icon from '~/vue_shared/components/icon.vue';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import timeagoMixin from '~/vue_shared/mixins/timeago';
......@@ -33,6 +34,7 @@ export default {
PackageInformation,
NpmInstallation,
MavenInstallation,
ConanInstallation,
},
directives: {
GlTooltip: GlTooltipDirective,
......@@ -80,6 +82,14 @@ export default {
type: String,
required: true,
},
conanPath: {
type: String,
required: true,
},
conanHelpPath: {
type: String,
required: true,
},
},
computed: {
isNpmPackage() {
......@@ -88,6 +98,9 @@ export default {
isMavenPackage() {
return this.packageEntity.package_type === PackageType.MAVEN;
},
isConanPackage() {
return this.packageEntity.package_type === PackageType.CONAN;
},
isValidPackage() {
return Boolean(this.packageEntity.name);
},
......@@ -231,6 +244,13 @@ export default {
:registry-url="mavenPath"
:help-url="mavenHelpPath"
/>
<conan-installation
v-else-if="isConanPackage"
:package-entity="packageEntity"
:registry-url="conanPath"
:help-url="conanHelpPath"
/>
</div>
</div>
......
<script>
import { GlTab, GlTabs } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
import CodeInstruction from './code_instruction.vue';
import Tracking from '~/tracking';
import { TrackingActions, TrackingLabels } from '../constants';
import { generateConanRecipe, trackInstallationTabChange } from '../utils';
export default {
name: 'ConanInstallation',
components: {
CodeInstruction,
GlTab,
GlTabs,
},
mixins: [
Tracking.mixin({
label: TrackingLabels.CONAN_INSTALLATION,
}),
trackInstallationTabChange,
],
props: {
heading: {
type: String,
default: s__('PackageRegistry|Package installation'),
required: false,
},
packageEntity: {
type: Object,
required: true,
},
registryUrl: {
type: String,
required: true,
},
helpUrl: {
type: String,
required: true,
},
},
computed: {
conanCommand() {
const recipe = generateConanRecipe(this.packageEntity);
// eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
return `conan install ${recipe} --remote=gitlab`;
},
setupCommand() {
// eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
return `conan remote add gitlab ${this.registryUrl}`;
},
helpText() {
return sprintf(
s__(
`PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}.`,
),
{
linkStart: `<a href="${this.helpUrl}" target="_blank" rel="noopener noreferer">`,
linkEnd: '</a>',
},
false,
);
},
},
trackingActions: { ...TrackingActions },
};
</script>
<template>
<div class="append-bottom-default">
<gl-tabs @input="trackInstallationTabChange">
<gl-tab :title="s__('PackageRegistry|Installation')" title-item-class="js-installation-tab">
<div class="prepend-left-default append-right-default">
<p class="prepend-top-8 font-weight-bold">{{ s__('PackageRegistry|Conan Command') }}</p>
<code-instruction
:instruction="conanCommand"
:copy-text="s__('PackageRegistry|Copy Conan Command')"
class="js-conan-command"
:tracking-action="$options.trackingActions.COPY_CONAN_COMMAND"
/>
</div>
</gl-tab>
<gl-tab :title="s__('PackageRegistry|Registry Setup')" title-item-class="js-setup-tab">
<div class="prepend-left-default append-right-default">
<p class="prepend-top-8 font-weight-bold">
{{ s__('PackageRegistry|Add Conan Remote') }}
</p>
<code-instruction
:instruction="setupCommand"
:copy-text="s__('PackageRegistry|Copy Conan Setup Command')"
class="js-conan-setup"
:tracking-action="$options.trackingActions.COPY_CONAN_SETUP_COMMAND"
/>
<p v-html="helpText"></p>
</div>
</gl-tab>
</gl-tabs>
</div>
</template>
export const TrackingLabels = {
CODE_INSTRUCTION: 'code_instruction',
CONAN_INSTALLATION: 'conan_installation',
MAVEN_INSTALLATION: 'maven_installation',
NPM_INSTALLATION: 'npm_installation',
};
......@@ -8,6 +9,9 @@ export const TrackingActions = {
INSTALLATION: 'installation',
REGISTRY_SETUP: 'registry_setup',
COPY_CONAN_COMMAND: 'copy_conan_command',
COPY_CONAN_SETUP_COMMAND: 'copy_conan_setup_command',
COPY_MAVEN_XML: 'copy_maven_xml',
COPY_MAVEN_COMMAND: 'copy_maven_command',
COPY_MAVEN_SETUP: 'copy_maven_setup_xml',
......
......@@ -26,6 +26,8 @@ export default () =>
npmHelpPath: dataset.npmHelpPath,
mavenPath: dataset.mavenPath,
mavenHelpPath: dataset.mavenHelpPath,
conanPath: dataset.conanPath,
conanHelpPath: dataset.conanHelpPath,
};
},
render(createElement) {
......@@ -40,6 +42,8 @@ export default () =>
npmHelpPath: this.npmHelpPath,
mavenPath: this.mavenPath,
mavenHelpPath: this.mavenHelpPath,
conanPath: this.conanPath,
conanHelpPath: this.conanHelpPath,
},
});
},
......
......@@ -14,6 +14,10 @@ module EE
::Gitlab::Utils.append_path(::Gitlab.config.gitlab.url, expose_path(api_v4_packages_npm_package_name_path))
end
def conan_package_registry_url
::Gitlab::Utils.append_path(::Gitlab.config.gitlab.url, "api/#{::API::API.version}/packages/conan")
end
def package_registry_project_url(project_id, registry_type = :maven)
project_api_path = expose_path(api_v4_projects_path(id: project_id))
package_registry_project_path = "#{project_api_path}/packages/#{registry_type}"
......
......@@ -14,4 +14,6 @@
npm_help_path: help_page_path('user/packages/npm_registry/index'),
maven_path: package_registry_project_url(@project.id, :maven),
maven_help_path: help_page_path('user/packages/maven_repository/index'),
conan_path: conan_package_registry_url,
conan_help_path: help_page_path('user/packages/conan_repository/index'),
package_file_download_path: download_project_package_file_path(@project, @package_files.first) } }
......@@ -7,7 +7,8 @@ import NpmInstallation from 'ee/packages/details/components/npm_installation.vue
import MavenInstallation from 'ee/packages/details/components/maven_installation.vue';
import * as SharedUtils from 'ee/packages/shared/utils';
import { TrackingActions } from 'ee/packages/shared/constants';
import { mavenPackage, mavenFiles, npmPackage, npmFiles, conanPackage } from '../../mock_data';
import ConanInstallation from 'ee/packages/details/components/conan_installation.vue';
import { conanPackage, mavenPackage, mavenFiles, npmPackage, npmFiles } from '../../mock_data';
describe('PackagesApp', () => {
let wrapper;
......@@ -22,6 +23,8 @@ describe('PackagesApp', () => {
npmHelpPath: 'foo',
mavenPath: 'foo',
mavenHelpPath: 'foo',
conanPath: 'foo',
conanHelpPath: 'foo',
};
function createComponent(props = {}) {
......@@ -42,6 +45,7 @@ describe('PackagesApp', () => {
const packageInformation = index => allPackageInformation().at(index);
const npmInstallation = () => wrapper.find(NpmInstallation);
const mavenInstallation = () => wrapper.find(MavenInstallation);
const conanInstallation = () => wrapper.find(ConanInstallation);
const allFileRows = () => wrapper.findAll('.js-file-row');
const firstFileDownloadLink = () => wrapper.find('.js-file-download');
const deleteButton = () => wrapper.find('.js-delete-button');
......@@ -179,4 +183,12 @@ describe('PackagesApp', () => {
);
});
});
it('renders package installation instructions for conan packages', () => {
createComponent({
packageEntity: conanPackage,
});
expect(conanInstallation()).toExist();
});
});
import { mount } from '@vue/test-utils';
import ConanInstallation from 'ee/packages/details/components/conan_installation.vue';
import { generateConanRecipe } from 'ee/packages/details/utils';
import { conanPackage } from '../../mock_data';
import { registryUrl } from '../mock_data';
import { TrackingActions, TrackingLabels } from 'ee/packages/details/constants';
import Tracking from '~/tracking';
describe('ConanInstallation', () => {
let wrapper;
const defaultProps = {
packageEntity: conanPackage,
registryUrl,
helpUrl: 'foo',
};
const recipe = generateConanRecipe(conanPackage);
const conanInstallationCommandStr = `conan install ${recipe} --remote=gitlab`;
const conanSetupCommandStr = `conan remote add gitlab ${registryUrl}`;
const installationTab = () => wrapper.find('.js-installation-tab > a');
const setupTab = () => wrapper.find('.js-setup-tab > a');
const conanInstallationCommand = () => wrapper.find('.js-conan-command > input');
const conanSetupCommand = () => wrapper.find('.js-conan-setup > input');
function createComponent(props = {}) {
const propsData = {
...defaultProps,
...props,
};
wrapper = mount(ConanInstallation, {
propsData,
});
}
beforeEach(() => {
createComponent();
});
afterEach(() => {
if (wrapper) wrapper.destroy();
});
describe('installation commands', () => {
it('renders the correct command', () => {
expect(conanInstallationCommand().element.value).toBe(conanInstallationCommandStr);
});
});
describe('setup commands', () => {
it('renders the correct command', () => {
expect(conanSetupCommand().element.value).toBe(conanSetupCommandStr);
});
});
describe('tab change tracking', () => {
let eventSpy;
const label = TrackingLabels.CONAN_INSTALLATION;
beforeEach(() => {
eventSpy = jest.spyOn(Tracking, 'event');
});
it('should track when the setup tab is clicked', () => {
setupTab().trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.REGISTRY_SETUP, {
label,
});
});
});
it('should track when the installation tab is clicked', () => {
setupTab().trigger('click');
return wrapper.vm
.$nextTick()
.then(() => {
installationTab().trigger('click');
})
.then(() => {
expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.INSTALLATION, {
label,
});
});
});
});
});
......@@ -12775,6 +12775,18 @@ msgstr ""
msgid "Package was removed"
msgstr ""
msgid "PackageRegistry|Add Conan Remote"
msgstr ""
msgid "PackageRegistry|Conan Command"
msgstr ""
msgid "PackageRegistry|Copy Conan Command"
msgstr ""
msgid "PackageRegistry|Copy Conan Setup Command"
msgstr ""
msgid "PackageRegistry|Copy Maven XML"
msgstr ""
......@@ -12805,6 +12817,9 @@ msgstr ""
msgid "PackageRegistry|Delete package"
msgstr ""
msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
msgstr ""
msgid "PackageRegistry|For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}."
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment