Skip to content

Commit

Permalink
integration: add the basics of cross-integration concerns
Browse files Browse the repository at this point in the history
  • Loading branch information
freben committed Dec 7, 2020
1 parent 040f453 commit b8ecf6f
Show file tree
Hide file tree
Showing 12 changed files with 481 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/nine-forks-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@backstage/integration': minor
---

Add the basics of cross-integration concerns
51 changes: 51 additions & 0 deletions packages/integration/src/ScmIntegrationsImpl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2020 Spotify AB
*
* 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.
*/

import { Config } from '@backstage/config';
import { AzureIntegration } from './azure/AzureIntegration';
import { BitbucketIntegration } from './bitbucket/BitbucketIntegration';
import { GitHubIntegration } from './github/GitHubIntegration';
import { GitLabIntegration } from './gitlab/GitLabIntegration';
import {
ScmIntegration,
ScmIntegrationPredicateTuple,
ScmIntegrations,
} from './types';

export class ScmIntegrationsImpl implements ScmIntegrations {
static fromConfig(config: Config): ScmIntegrationsImpl {
return new ScmIntegrationsImpl([
...AzureIntegration.factory({ config }),
...BitbucketIntegration.factory({ config }),
...GitHubIntegration.factory({ config }),
...GitLabIntegration.factory({ config }),
]);
}

constructor(private readonly integrations: ScmIntegrationPredicateTuple[]) {}

list(): ScmIntegration[] {
return this.integrations.map(i => i.integration);
}

byName(name: string): ScmIntegration | undefined {
return this.integrations.map(i => i.integration).find(i => i.name === name);
}

byUrl(url: string): ScmIntegration | undefined {
return this.integrations.find(i => i.predicate(new URL(url)))?.integration;
}
}
48 changes: 48 additions & 0 deletions packages/integration/src/azure/AzureIntegration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2020 Spotify AB
*
* 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.
*/

import { ConfigReader } from '@backstage/config';
import { AzureIntegration } from './AzureIntegration';

describe('AzureIntegration', () => {
it('has a working factory', () => {
const integrations = AzureIntegration.factory({
config: ConfigReader.fromConfigs([
{
context: '',
data: {
integrations: {
azure: [
{
host: 'h.com',
token: 'token',
},
],
},
},
},
]),
});
expect(integrations.length).toBe(2); // including default
expect(integrations[0].predicate(new URL('https://h.com/a'))).toBe(true);
});

it('returns the basics', () => {
const integration = new AzureIntegration({ host: 'h.com' } as any);
expect(integration.type).toBe('azure');
expect(integration.name).toBe('h.com');
});
});
40 changes: 40 additions & 0 deletions packages/integration/src/azure/AzureIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2020 Spotify AB
*
* 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.
*/

import { ScmIntegration, ScmIntegrationFactory } from '../types';
import { AzureIntegrationConfig, readAzureIntegrationConfigs } from './config';

export class AzureIntegration implements ScmIntegration {
static factory: ScmIntegrationFactory = ({ config }) => {
const configs = readAzureIntegrationConfigs(
config.getOptionalConfigArray('integrations.azure') ?? [],
);
return configs.map(integration => ({
predicate: (url: URL) => url.host === integration.host,
integration: new AzureIntegration(integration),
}));
};

constructor(private readonly config: AzureIntegrationConfig) {}

get type(): string {
return 'azure';
}

get name(): string {
return this.config.host;
}
}
51 changes: 51 additions & 0 deletions packages/integration/src/bitbucket/BitbucketIntegration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2020 Spotify AB
*
* 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.
*/

import { ConfigReader } from '@backstage/config';
import { BitbucketIntegration } from './BitbucketIntegration';

describe('BitbucketIntegration', () => {
it('has a working factory', () => {
const integrations = BitbucketIntegration.factory({
config: ConfigReader.fromConfigs([
{
context: '',
data: {
integrations: {
bitbucket: [
{
host: 'h.com',
apiBaseUrl: 'a',
token: 't',
username: 'u',
appPassword: 'p',
},
],
},
},
},
]),
});
expect(integrations.length).toBe(2); // including default
expect(integrations[0].predicate(new URL('https://h.com/a'))).toBe(true);
});

it('returns the basics', () => {
const integration = new BitbucketIntegration({ host: 'h.com' } as any);
expect(integration.type).toBe('bitbucket');
expect(integration.name).toBe('h.com');
});
});
43 changes: 43 additions & 0 deletions packages/integration/src/bitbucket/BitbucketIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2020 Spotify AB
*
* 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.
*/

import { ScmIntegration, ScmIntegrationFactory } from '../types';
import {
BitbucketIntegrationConfig,
readBitbucketIntegrationConfigs,
} from './config';

export class BitbucketIntegration implements ScmIntegration {
static factory: ScmIntegrationFactory = ({ config }) => {
const configs = readBitbucketIntegrationConfigs(
config.getOptionalConfigArray('integrations.bitbucket') ?? [],
);
return configs.map(integration => ({
predicate: (url: URL) => url.host === integration.host,
integration: new BitbucketIntegration(integration),
}));
};

constructor(private readonly config: BitbucketIntegrationConfig) {}

get type(): string {
return 'bitbucket';
}

get name(): string {
return this.config.host;
}
}
50 changes: 50 additions & 0 deletions packages/integration/src/github/GitHubIntegration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2020 Spotify AB
*
* 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.
*/

import { ConfigReader } from '@backstage/config';
import { GitHubIntegration } from './GitHubIntegration';

describe('GitHubIntegration', () => {
it('has a working factory', () => {
const integrations = GitHubIntegration.factory({
config: ConfigReader.fromConfigs([
{
context: '',
data: {
integrations: {
github: [
{
host: 'h.com',
apiBaseUrl: 'a',
rawBaseUrl: 'r',
token: 't',
},
],
},
},
},
]),
});
expect(integrations.length).toBe(2); // including default
expect(integrations[0].predicate(new URL('https://h.com/a'))).toBe(true);
});

it('returns the basics', () => {
const integration = new GitHubIntegration({ host: 'h.com' } as any);
expect(integration.type).toBe('github');
expect(integration.name).toBe('h.com');
});
});
43 changes: 43 additions & 0 deletions packages/integration/src/github/GitHubIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2020 Spotify AB
*
* 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.
*/

import { ScmIntegration, ScmIntegrationFactory } from '../types';
import {
GitHubIntegrationConfig,
readGitHubIntegrationConfigs,
} from './config';

export class GitHubIntegration implements ScmIntegration {
static factory: ScmIntegrationFactory = ({ config }) => {
const configs = readGitHubIntegrationConfigs(
config.getOptionalConfigArray('integrations.github') ?? [],
);
return configs.map(integration => ({
predicate: (url: URL) => url.host === integration.host,
integration: new GitHubIntegration(integration),
}));
};

constructor(private readonly config: GitHubIntegrationConfig) {}

get type(): string {
return 'github';
}

get name(): string {
return this.config.host;
}
}
48 changes: 48 additions & 0 deletions packages/integration/src/gitlab/GitLabIntegration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2020 Spotify AB
*
* 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.
*/

import { ConfigReader } from '@backstage/config';
import { GitLabIntegration } from './GitLabIntegration';

describe('GitLabIntegration', () => {
it('has a working factory', () => {
const integrations = GitLabIntegration.factory({
config: ConfigReader.fromConfigs([
{
context: '',
data: {
integrations: {
gitlab: [
{
host: 'h.com',
token: 't',
},
],
},
},
},
]),
});
expect(integrations.length).toBe(2); // including default
expect(integrations[0].predicate(new URL('https://h.com/a'))).toBe(true);
});

it('returns the basics', () => {
const integration = new GitLabIntegration({ host: 'h.com' } as any);
expect(integration.type).toBe('gitlab');
expect(integration.name).toBe('h.com');
});
});

0 comments on commit b8ecf6f

Please sign in to comment.