Commit 12269478 authored by Chido Warambwa's avatar Chido Warambwa Committed by Nicolò Maria Mezzopera

Enabling switching between project-level and instance-level endpoints when...

Enabling switching between project-level and instance-level endpoints when viewing the NPM package registry setup step
parent c430f6b7
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import { GlLink, GlSprintf, GlFormRadioGroup } from '@gitlab/ui';
import { s__ } from '~/locale';
import InstallationTitle from '~/packages_and_registries/package_registry/components/details/installation_title.vue';
......@@ -11,6 +11,8 @@ import {
TRACKING_LABEL_CODE_INSTRUCTION,
NPM_PACKAGE_MANAGER,
YARN_PACKAGE_MANAGER,
PROJECT_PACKAGE_ENDPOINT_TYPE,
INSTANCE_PACKAGE_ENDPOINT_TYPE,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
......@@ -21,8 +23,9 @@ export default {
CodeInstruction,
GlLink,
GlSprintf,
GlFormRadioGroup,
},
inject: ['npmHelpPath', 'npmPath'],
inject: ['npmHelpPath', 'npmPath', 'npmProjectPath'],
props: {
packageEntity: {
type: Object,
......@@ -32,6 +35,7 @@ export default {
data() {
return {
instructionType: NPM_PACKAGE_MANAGER,
packageEndpointType: INSTANCE_PACKAGE_ENDPOINT_TYPE,
};
},
computed: {
......@@ -39,13 +43,13 @@ export default {
return this.npmInstallationCommand(NPM_PACKAGE_MANAGER);
},
npmSetup() {
return this.npmSetupCommand(NPM_PACKAGE_MANAGER);
return this.npmSetupCommand(NPM_PACKAGE_MANAGER, this.packageEndpointType);
},
yarnCommand() {
return this.npmInstallationCommand(YARN_PACKAGE_MANAGER);
},
yarnSetupCommand() {
return this.npmSetupCommand(YARN_PACKAGE_MANAGER);
return this.npmSetupCommand(YARN_PACKAGE_MANAGER, this.packageEndpointType);
},
showNpm() {
return this.instructionType === NPM_PACKAGE_MANAGER;
......@@ -58,14 +62,16 @@ export default {
return `${instruction} ${this.packageEntity.name}`;
},
npmSetupCommand(type) {
npmSetupCommand(type, endpointType) {
const scope = this.packageEntity.name.substring(0, this.packageEntity.name.indexOf('/'));
const npmPathForEndpoint =
endpointType === INSTANCE_PACKAGE_ENDPOINT_TYPE ? this.npmPath : this.npmProjectPath;
if (type === NPM_PACKAGE_MANAGER) {
return `echo ${scope}:registry=${this.npmPath}/ >> .npmrc`;
return `echo ${scope}:registry=${npmPathForEndpoint}/ >> .npmrc`;
}
return `echo \\"${scope}:registry\\" \\"${this.npmPath}/\\" >> .yarnrc`;
return `echo \\"${scope}:registry\\" \\"${npmPathForEndpoint}/\\" >> .yarnrc`;
},
},
packageManagers: {
......@@ -87,6 +93,10 @@ export default {
{ value: NPM_PACKAGE_MANAGER, label: s__('PackageRegistry|Show NPM commands') },
{ value: YARN_PACKAGE_MANAGER, label: s__('PackageRegistry|Show Yarn commands') },
],
packageEndpointTypeOptions: [
{ value: INSTANCE_PACKAGE_ENDPOINT_TYPE, text: s__('PackageRegistry|Instance-level') },
{ value: PROJECT_PACKAGE_ENDPOINT_TYPE, text: s__('PackageRegistry|Project-level') },
],
};
</script>
......@@ -116,6 +126,12 @@ export default {
<h3 class="gl-font-lg">{{ __('Registry setup') }}</h3>
<gl-form-radio-group
:options="$options.packageEndpointTypeOptions"
:checked="packageEndpointType"
@change="packageEndpointType = $event"
/>
<code-instruction
v-if="showNpm"
:instruction="npmSetup"
......
......@@ -86,3 +86,6 @@ export const PACKAGE_PROCESSING_STATUS = 'PROCESSING';
export const NPM_PACKAGE_MANAGER = 'npm';
export const YARN_PACKAGE_MANAGER = 'yarn';
export const PROJECT_PACKAGE_ENDPOINT_TYPE = 'project';
export const INSTANCE_PACKAGE_ENDPOINT_TYPE = 'instance';
......@@ -70,6 +70,7 @@ module PackagesHelper
can_delete: can?(current_user, :destroy_package, project).to_s,
svg_path: image_path('illustrations/no-packages.svg'),
npm_path: package_registry_instance_url(:npm),
npm_project_path: package_registry_project_url(project.id, :npm),
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'),
......
......@@ -370,13 +370,26 @@ in a JavaScript project. You can install a package from the scope of a project o
If multiple packages have the same name and version, when you install a package, the most recently-published package is retrieved.
1. Set the URL for scoped packages by running:
1. Set the URL for scoped packages.
For [instance-level endpoints](#use-the-gitlab-endpoint-for-npm-packages) run:
```shell
npm config set @foo:registry https://gitlab.example.com/api/v4/packages/npm/
```
Replace `@foo` with your scope.
- Replace `@foo` with your scope.
- Replace `gitlab.example.com` with your domain name.
For [project-level endpoints](#use-the-gitlab-endpoint-for-npm-packages) run:
```shell
npm config set @foo:registry https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/
```
- Replace `@foo` with your scope.
- Replace `gitlab.example.com` with your domain name.
- Replace `<your_project_id>` with your project ID, found on the project's home page.
1. Ensure [authentication](#authenticate-to-the-package-registry) is configured.
......
......@@ -24118,6 +24118,9 @@ msgstr ""
msgid "PackageRegistry|Install package version"
msgstr ""
msgid "PackageRegistry|Instance-level"
msgstr ""
msgid "PackageRegistry|Invalid Package: failed metadata extraction"
msgstr ""
......@@ -24163,6 +24166,9 @@ msgstr ""
msgid "PackageRegistry|Pip Command"
msgstr ""
msgid "PackageRegistry|Project-level"
msgstr ""
msgid "PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
......
......@@ -21,6 +21,15 @@ exports[`NpmInstallation renders all the messages 1`] = `
Registry setup
</h3>
<gl-form-radio-group-stub
checked="instance"
disabledfield="disabled"
htmlfield="html"
options="[object Object],[object Object]"
textfield="text"
valuefield="value"
/>
<code-instruction-stub
copytext="Copy npm setup command"
instruction="echo @gitlab-org:registry=npmPath/ >> .npmrc"
......
import { GlFormRadioGroup } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
......@@ -12,6 +13,8 @@ import {
PACKAGE_TYPE_NPM,
NPM_PACKAGE_MANAGER,
YARN_PACKAGE_MANAGER,
PROJECT_PACKAGE_ENDPOINT_TYPE,
INSTANCE_PACKAGE_ENDPOINT_TYPE,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
......@@ -25,12 +28,14 @@ describe('NpmInstallation', () => {
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
const findEndPointTypeSector = () => wrapper.findComponent(GlFormRadioGroup);
function createComponent({ data = {} } = {}) {
wrapper = shallowMountExtended(NpmInstallation, {
provide: {
npmHelpPath: 'npmHelpPath',
npmPath: 'npmPath',
npmProjectPath: 'npmProjectPath',
},
propsData: {
packageEntity,
......@@ -53,6 +58,19 @@ describe('NpmInstallation', () => {
expect(wrapper.element).toMatchSnapshot();
});
describe('endpoint type selector', () => {
it('has the endpoint type selector', () => {
expect(findEndPointTypeSector().exists()).toBe(true);
expect(findEndPointTypeSector().vm.$attrs.checked).toBe(INSTANCE_PACKAGE_ENDPOINT_TYPE);
expect(findEndPointTypeSector().props()).toMatchObject({
options: [
{ value: INSTANCE_PACKAGE_ENDPOINT_TYPE, text: 'Instance-level' },
{ value: PROJECT_PACKAGE_ENDPOINT_TYPE, text: 'Project-level' },
],
});
});
});
describe('install command switch', () => {
it('has the installation title component', () => {
expect(findInstallationTitle().exists()).toBe(true);
......@@ -96,6 +114,28 @@ describe('NpmInstallation', () => {
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
});
it('renders the correct setup command for different endpoint types', async () => {
findEndPointTypeSector().vm.$emit('change', PROJECT_PACKAGE_ENDPOINT_TYPE);
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
instruction: `echo @gitlab-org:registry=npmProjectPath/ >> .npmrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
findEndPointTypeSector().vm.$emit('change', INSTANCE_PACKAGE_ENDPOINT_TYPE);
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
instruction: `echo @gitlab-org:registry=npmPath/ >> .npmrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
});
});
describe('yarn', () => {
......@@ -118,5 +158,27 @@ describe('NpmInstallation', () => {
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
});
it('renders the correct setup command for different endpoint types', async () => {
findEndPointTypeSector().vm.$emit('change', PROJECT_PACKAGE_ENDPOINT_TYPE);
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
instruction: `echo \\"@gitlab-org:registry\\" \\"npmProjectPath/\\" >> .yarnrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
findEndPointTypeSector().vm.$emit('change', INSTANCE_PACKAGE_ENDPOINT_TYPE);
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
instruction: 'echo \\"@gitlab-org:registry\\" \\"npmPath/\\" >> .yarnrc',
multiline: false,
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
});
});
});
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