Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: parse proto packages without namespace correctly #202

Merged
merged 6 commits into from
Jan 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions typescript/src/schema/naming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,20 @@ export class Naming {
throw new Error('Protos provided have different proto packages.');
}
const rootPackage = prefix.replace(/\.$/, '');

// Define the regular expression to match a version component
// (e.g. "v1", "v1beta4", etc.).
const pattern = /^((?:[a-z0-9_.]+?)\.)?([a-z0-9_]+)(?:\.(v[0-9]+(p[0-9]+)?((alpha|beta)[0-9]+)?[^.]*))?$/;
const match = rootPackage.match(pattern);
if (!match) {
const segments = rootPackage.split('.');
if (!segments || segments.length < 2) {
throw new Error(`Cannot parse package name ${rootPackage}.`);
}
const [, namespaces, name, version] = match;
if (!namespaces) {
const version = segments[segments.length - 1];
// version should follow the pattern of 'v1' or 'v1alpha1'
const versionPattern = /^((v[0-9]+(p[0-9]+)?((alpha|beta)[0-9]+)?[^.]*))?$/;
if (!version.match(versionPattern)) {
throw new Error(
`Cannot parse package name ${rootPackage}: namespace is not defined.`
`Cannot parse package name ${rootPackage}: version does not match ${versionPattern}.`
);
}
const name = segments[segments.length - 2];
const namespaces = segments.slice(0, -2).join('.');
this.name = name.capitalize();
this.productName = this.name;
this.namespace = namespaces.replace(/\.$/, '').split('.');
Expand Down
15 changes: 15 additions & 0 deletions typescript/test/unit/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,21 @@ describe('schema/api.ts', () => {
assert.deepStrictEqual(api.mainServiceName, 'AService');
});

it('should return correct mainServiceName for API without namespace', () => {
const fd1 = new plugin.google.protobuf.FileDescriptorProto();
fd1.name = 'service/v1/test.proto';
fd1.package = 'service.v1';
fd1.service = [new plugin.google.protobuf.ServiceDescriptorProto()];
fd1.service[0].name = 'Service';
fd1.service[0].options = {
'.google.api.defaultHost': 'hostname.example.com:443',
};
const api = new API([fd1], 'service.v1', {
grpcServiceConfig: new plugin.grpc.service_config.ServiceConfig(),
});
assert.deepStrictEqual(api.mainServiceName, 'Service');
});

it('should return main service name specificed as an option', () => {
const fd1 = new plugin.google.protobuf.FileDescriptorProto();
fd1.name = 'google/cloud/test/v1/test.proto';
Expand Down
24 changes: 24 additions & 0 deletions typescript/test/unit/naming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,30 @@ describe('schema/naming.ts', () => {
assert.strictEqual(naming.protoPackage, 'google.namespace.service.v1beta1');
});

it('parses name correctly 2', () => {
const descriptor1 = new plugin.google.protobuf.FileDescriptorProto();
descriptor1.package = 'service.v1beta1';
descriptor1.service = [new plugin.google.protobuf.ServiceDescriptorProto()];
const naming = new Naming([descriptor1]);
assert.strictEqual(naming.name, 'Service');
assert.strictEqual(naming.productName, 'Service');
assert.deepStrictEqual(naming.namespace, ['']);
assert.strictEqual(naming.version, 'v1beta1');
assert.strictEqual(naming.protoPackage, 'service.v1beta1');
});

it('parses name correctly 3', () => {
const descriptor1 = new plugin.google.protobuf.FileDescriptorProto();
descriptor1.package = 'company.service.v1beta1';
descriptor1.service = [new plugin.google.protobuf.ServiceDescriptorProto()];
const naming = new Naming([descriptor1]);
assert.strictEqual(naming.name, 'Service');
assert.strictEqual(naming.productName, 'Service');
assert.deepStrictEqual(naming.namespace, ['company']);
assert.strictEqual(naming.version, 'v1beta1');
assert.strictEqual(naming.protoPackage, 'company.service.v1beta1');
});

it('ignores files with no services when determining package name', () => {
const descriptor1 = new plugin.google.protobuf.FileDescriptorProto();
const descriptor2 = new plugin.google.protobuf.FileDescriptorProto();
Expand Down