From 7153a20e11c665fb23877b5440cd08c58f855aa3 Mon Sep 17 00:00:00 2001
From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com>
Date: Fri, 20 Jan 2023 12:16:34 -0500
Subject: [PATCH] feat!: allow publishing to subset of jsii target languages
for experimental modules (#12)
* add missing test
* add jsii target language option and remove from cdklabs ts project
* fix import order
* add test suite
---
API.md | 75 ++++++++++++++++++++++---------
src/cdklabs.ts | 99 +++++++++++++++++++++++++----------------
test/cdk.test.ts | 25 +++++++++--
test/cdklabs.test.ts | 96 +++++++++++++++++++++++++++++++++++++--
test/private-helpers.ts | 2 +-
5 files changed, 230 insertions(+), 67 deletions(-)
diff --git a/API.md b/API.md
index 13658a6..0fd6d05 100644
--- a/API.md
+++ b/API.md
@@ -2665,6 +2665,7 @@ const cdklabsConstructLibraryOptions: CdklabsConstructLibraryOptions = { ... }
| lambdaOptions
| projen.awscdk.LambdaFunctionCommonOptions
| Common options for all AWS Lambda functions. |
| private
| boolean
| Whether or not this package is private. |
| cdklabsPublishingDefaults
| boolean
| Set default publishing properties. |
+| jsiiTargetLanguages
| JsiiLanguage[]
| Specify specific languages to publish to. |
---
@@ -4995,6 +4996,24 @@ This should be set to false only if you do not plan on releasing the package.
---
+##### `jsiiTargetLanguages`Optional
+
+```typescript
+public readonly jsiiTargetLanguages: JsiiLanguage[];
+```
+
+- *Type:* JsiiLanguage[]
+- *Default:* all jsii target languages
+
+Specify specific languages to publish to.
+
+This can be used when the library
+is experimental only, because stable libraries must publish to all jsii languages.
+This should be used in conjunction with `cdklabsPublishingDefaults: true`; otherwise
+it is a no-op.
+
+---
+
### CdklabsTypeScriptProjectOptions
#### Initializer
@@ -5142,7 +5161,6 @@ const cdklabsTypeScriptProjectOptions: CdklabsTypeScriptProjectOptions = { ... }
| tsconfigDevFile
| string
| The name of the development tsconfig.json file. |
| typescriptVersion
| string
| TypeScript version to use. |
| private
| boolean
| Whether or not this module is private. |
-| cdklabsPublishingDefaults
| boolean
| Set default publishing properties. |
---
@@ -7040,27 +7058,6 @@ for private repositories.
---
-##### `cdklabsPublishingDefaults`Optional
-
-```typescript
-public readonly cdklabsPublishingDefaults: boolean;
-```
-
-- *Type:* boolean
-- *Default:* true
-
-Set default publishing properties.
-
-Setting this property guarantees
-that your project will have reasonable publishing names. You can choose
-to modify them however you wish with the traditional `publishToPypi`,
-`publishToMaven`, `publishToNuget`, and `publishToGo` properties, and
-your configuration will be respected.
-
-This should be set to false only if you do not plan on releasing the package.
-
----
-
### CdkTypeScriptProjectOptions
#### Initializer
@@ -14710,3 +14707,37 @@ this task should synthesize the project files.
---
+## Enums
+
+### JsiiLanguage
+
+#### Members
+
+| **Name** | **Description** |
+| --- | --- |
+| PYTHON
| *No description.* |
+| JAVA
| *No description.* |
+| DOTNET
| *No description.* |
+| GO
| *No description.* |
+
+---
+
+##### `PYTHON`
+
+---
+
+
+##### `JAVA`
+
+---
+
+
+##### `DOTNET`
+
+---
+
+
+##### `GO`
+
+---
+
diff --git a/src/cdklabs.ts b/src/cdklabs.ts
index 245a6b0..0dfdf7e 100644
--- a/src/cdklabs.ts
+++ b/src/cdklabs.ts
@@ -1,6 +1,13 @@
import { UpdateSnapshot } from 'projen/lib/javascript';
import { deepMerge } from 'projen/lib/util';
+export enum JsiiLanguage {
+ PYTHON,
+ JAVA,
+ DOTNET,
+ GO,
+};
+
import {
CdkConstructLibrary,
CdkConstructLibraryOptions,
@@ -30,27 +37,46 @@ const cdklabsDefaultProps = {
defaultReleaseBranch: 'main',
};
-function createCdklabsPublishingDefaults(npmPackageName: string) {
+function createCdklabsPublishingDefaults(npmPackageName: string, langs?: JsiiLanguage[]) {
return {
- publishToPypi: {
- distName: npmPackageName,
- module: changeDelimiter(npmPackageName, '_'),
- },
- publishToMaven: {
- javaPackage: `io.github.cdklabs.${changeDelimiter(npmPackageName, '.')}`,
- mavenGroupId: 'io.github.cdklabs',
- mavenArtifactId: npmPackageName,
- mavenEndpoint: 'https://s01.oss.sonatype.org',
- },
- publishToNuget: {
- dotNetNamespace: `Cdklabs${upperCaseName(npmPackageName)}`,
- packageId: `Cdklabs${upperCaseName(npmPackageName)}`,
- },
- publishToGo: {
- moduleName: `github.com/cdklabs/${npmPackageName}-go`,
- },
+ ...publishLanguageWrapper(JsiiLanguage.PYTHON, {
+ publishToPypi: {
+ distName: npmPackageName,
+ module: changeDelimiter(npmPackageName, '_'),
+ },
+ }),
+ ...publishLanguageWrapper(JsiiLanguage.JAVA, {
+ publishToMaven: {
+ javaPackage: `io.github.cdklabs.${changeDelimiter(npmPackageName, '.')}`,
+ mavenGroupId: 'io.github.cdklabs',
+ mavenArtifactId: npmPackageName,
+ mavenEndpoint: 'https://s01.oss.sonatype.org',
+ },
+ }),
+ ...publishLanguageWrapper(JsiiLanguage.DOTNET, {
+ publishToNuget: {
+ dotNetNamespace: `Cdklabs${upperCaseName(npmPackageName)}`,
+ packageId: `Cdklabs${upperCaseName(npmPackageName)}`,
+ },
+ }),
+ ...publishLanguageWrapper(JsiiLanguage.GO, {
+ publishToGo: {
+ moduleName: `github.com/cdklabs/${npmPackageName}-go`,
+ },
+ }),
};
+ function publishLanguageWrapper(lang: JsiiLanguage, obj: Record) {
+ return publishLanguage(lang) ? obj : {};
+ }
+
+ function publishLanguage(lang: JsiiLanguage): boolean {
+ // langs not specified === all languages published
+ if (!langs) { return true; }
+ if (langs.includes(lang)) { return true; }
+ return false;
+ }
+
function upperCaseName(str: string) {
let words = str.split('-');
words = words.map((w) => w[0].toUpperCase() + w.substring(1));
@@ -75,6 +101,16 @@ export interface CdklabsConstructLibraryOptions extends CdkConstructLibraryOptio
* @default true
*/
readonly cdklabsPublishingDefaults?: boolean;
+
+ /**
+ * Specify specific languages to publish to. This can be used when the library
+ * is experimental only, because stable libraries must publish to all jsii languages.
+ * This should be used in conjunction with `cdklabsPublishingDefaults: true`; otherwise
+ * it is a no-op.
+ *
+ * @default - all jsii target languages
+ */
+ readonly jsiiTargetLanguages?: JsiiLanguage[];
}
/**
@@ -84,10 +120,12 @@ export interface CdklabsConstructLibraryOptions extends CdkConstructLibraryOptio
*/
export class CdklabsConstructLibrary extends CdkConstructLibrary {
constructor(options: CdklabsConstructLibraryOptions) {
- const cdklabsPublishingDefaultProps = (options.cdklabsPublishingDefaults ?? true) ?
- createCdklabsPublishingDefaults(options.name) : {};
+ const cdklabsPublishingDefaultProps: Record = (options.cdklabsPublishingDefaults ?? true) ?
+ createCdklabsPublishingDefaults(options.name, options.jsiiTargetLanguages) : {};
+ // the leftmost object is mutated and returned by deepMerge
const mergedOptions = deepMerge([
+ {},
cdklabsDefaultProps,
cdklabsPublishingDefaultProps,
options,
@@ -98,20 +136,7 @@ export class CdklabsConstructLibrary extends CdkConstructLibrary {
}
}
-export interface CdklabsTypeScriptProjectOptions extends CdkTypeScriptProjectOptions {
- /**
- * Set default publishing properties. Setting this property guarantees
- * that your project will have reasonable publishing names. You can choose
- * to modify them however you wish with the traditional `publishToPypi`,
- * `publishToMaven`, `publishToNuget`, and `publishToGo` properties, and
- * your configuration will be respected.
- *
- * This should be set to false only if you do not plan on releasing the package.
- *
- * @default true
- */
- readonly cdklabsPublishingDefaults?: boolean;
-}
+export interface CdklabsTypeScriptProjectOptions extends CdkTypeScriptProjectOptions { }
/**
* Create a Cdklabs TypeScript Project
@@ -120,12 +145,10 @@ export interface CdklabsTypeScriptProjectOptions extends CdkTypeScriptProjectOpt
*/
export class CdklabsTypeScriptProject extends CdkTypeScriptProject {
constructor(options: CdklabsTypeScriptProjectOptions) {
- const cdklabsPublishingDefaultProps = (options.cdklabsPublishingDefaults ?? true) ?
- createCdklabsPublishingDefaults(options.name) : {};
-
+ // the leftmost object is mutated and returned by deepMerge
const mergedOptions = deepMerge([
+ {},
cdklabsDefaultProps,
- cdklabsPublishingDefaultProps,
options,
cdklabsForcedProps,
]) as CdkConstructLibraryOptions;
diff --git a/test/cdk.test.ts b/test/cdk.test.ts
index 354cf7a..bdaf10c 100644
--- a/test/cdk.test.ts
+++ b/test/cdk.test.ts
@@ -6,7 +6,6 @@ import { CdkConstructLibrary, CdkConstructLibraryOptions, CdkTypeScriptProject,
describe('CdkConstructLibrary', () => {
test('synthesizes with default settings', () => {
const project = new TestCdkConstructLibrary();
-
const outdir = Testing.synth(project);
// defaults to private
@@ -39,8 +38,28 @@ describe('CdkConstructLibrary', () => {
].join('\n'));
});
- test('thorws when a publishing to a subset of languages', () => {
-
+ test('throws when a publishing to a subset of languages', () => {
+ expect(() => {
+ new TestCdkConstructLibrary({
+ stability: Stability.STABLE,
+ publishToPypi: {
+ distName: 'distName',
+ module: 'module',
+ },
+ publishToMaven: {
+ javaPackage: 'javaPackage',
+ mavenArtifactId: 'mavenArtifactId',
+ mavenGroupId: 'mavenGroupId',
+ },
+ publishToNuget: {
+ dotNetNamespace: 'dotNetNamespace',
+ packageId: 'packageId',
+ },
+ });
+ }).toThrowError([
+ 'The project does not pass stability requirements due to the following errors:',
+ ' Publishing Error: project not configured to publish to Go',
+ ].join('\n'));
});
});
});
diff --git a/test/cdklabs.test.ts b/test/cdklabs.test.ts
index f2bb4ef..af31758 100644
--- a/test/cdklabs.test.ts
+++ b/test/cdklabs.test.ts
@@ -1,11 +1,32 @@
import { Testing } from 'projen';
+import { Stability } from 'projen/lib/cdk';
import * as YAML from 'yaml';
-import { CdklabsConstructLibrary, CdklabsConstructLibraryOptions, CdklabsTypeScriptProject, CdklabsTypeScriptProjectOptions } from '../src/cdklabs';
+import { CdklabsConstructLibrary, CdklabsConstructLibraryOptions, CdklabsTypeScriptProject, CdklabsTypeScriptProjectOptions, JsiiLanguage } from '../src/cdklabs';
+
+const publishingTargets = {
+ java: {
+ package: 'io.github.cdklabs.test.construct.library',
+ maven: {
+ groupId: 'io.github.cdklabs',
+ artifactId: 'test-construct-library',
+ },
+ },
+ python: {
+ distName: 'test-construct-library',
+ module: 'test_construct_library',
+ },
+ dotnet: {
+ namespace: 'CdklabsTestConstructLibrary',
+ packageId: 'CdklabsTestConstructLibrary',
+ },
+ go: {
+ moduleName: 'github.com/cdklabs/test-construct-library-go',
+ },
+};
describe('CdklabsConstructLibrary', () => {
test('synthesizes with default settings', () => {
const project = new TestCdkLabsConstructLibrary();
-
const outdir = Testing.synth(project);
const packageJson = outdir['package.json'];
@@ -38,6 +59,75 @@ describe('CdklabsConstructLibrary', () => {
expect(outdir).toMatchSnapshot();
});
+
+ describe('cdklabsPublishingDefaults', () => {
+ test('created by default', () => {
+ const project = new TestCdkLabsConstructLibrary();
+ const outdir = Testing.synth(project);
+ const packageJson = outdir['package.json'];
+
+ // jsii publishing
+ expect(packageJson.jsii?.targets).toEqual(publishingTargets);
+ });
+
+ describe('limiting publishing to a subset of languages', () => {
+ test('can be done in experimental modules', () => {
+ const project = new TestCdkLabsConstructLibrary({
+ stability: Stability.EXPERIMENTAL,
+ jsiiTargetLanguages: [JsiiLanguage.JAVA, JsiiLanguage.PYTHON],
+ });
+ const outdir = Testing.synth(project);
+ const packageJson = outdir['package.json'];
+
+ // jsii publishing
+ expect(packageJson.jsii?.targets).toEqual({
+ ...{ java: publishingTargets.java },
+ ...{ python: publishingTargets.python },
+ });
+ });
+
+ test('throws if done in stable modules', () => {
+ expect(() => {
+ new TestCdkLabsConstructLibrary({
+ stability: Stability.STABLE,
+ jsiiTargetLanguages: [JsiiLanguage.JAVA, JsiiLanguage.PYTHON],
+ });
+ }).toThrowError([
+ 'The project does not pass stability requirements due to the following errors:',
+ ' Publishing Error: project not configured to publish to Nuget',
+ ' Publishing Error: project not configured to publish to Go',
+ ].join('\n'));
+ });
+
+ test('does not throw if custom publishing set', () => {
+ expect(() => {
+ new TestCdkLabsConstructLibrary({
+ stability: Stability.STABLE,
+ jsiiTargetLanguages: [JsiiLanguage.JAVA, JsiiLanguage.PYTHON],
+ publishToNuget: {
+ dotNetNamespace: 'custom-namespace',
+ packageId: 'custom-package',
+ },
+ publishToGo: {
+ moduleName: 'github.com/custom-name',
+ },
+ });
+ }).not.toThrow();
+ });
+
+ test('ignored if cdklabsPublishingDefaults is false', () => {
+ const project = new TestCdkLabsConstructLibrary({
+ cdklabsPublishingDefaults: false,
+ jsiiTargetLanguages: [JsiiLanguage.JAVA, JsiiLanguage.PYTHON],
+ });
+ const outdir = Testing.synth(project);
+ const packageJson = outdir['package.json'];
+
+ // jsii publishing
+ expect(packageJson.jsii?.targets).toEqual({});
+ });
+ });
+ });
});
describe('CdklabsTypeScriptProject', () => {
@@ -100,4 +190,4 @@ class TestCdkLabsTypeScriptProject extends CdklabsTypeScriptProject {
...options,
});
}
-}
\ No newline at end of file
+}
diff --git a/test/private-helpers.ts b/test/private-helpers.ts
index 1ed64eb..044f544 100644
--- a/test/private-helpers.ts
+++ b/test/private-helpers.ts
@@ -8,4 +8,4 @@ export function expectNotPrivate(outdir: Record) {
expect(outdir['.npmignore']).toBeDefined();
expect(outdir['.mergify.yml']).toBeDefined();
expect(outdir['package.json'].private).toBeFalsy();
-}
\ No newline at end of file
+}