From 017b727c6427830207fc472a96a2d7f4d44952c3 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 11 Mar 2020 14:15:33 -0400 Subject: [PATCH] fix(@angular/cli): allow for private use language subtags Fixes: #17163 --- packages/angular/cli/lib/config/schema.json | 8 ++++---- .../build_angular/src/browser/schema.json | 2 +- .../build_angular/src/server/schema.json | 2 +- .../build_angular/src/utils/i18n-options.ts | 7 +++++-- .../experimental/workspace/workspace-schema.json | 6 +++--- .../e2e/tests/i18n/ivy-localize-locale-data.ts | 14 ++++++++++++++ 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/angular/cli/lib/config/schema.json b/packages/angular/cli/lib/config/schema.json index 239eb4d1be2e..2b2e387b5972 100644 --- a/packages/angular/cli/lib/config/schema.json +++ b/packages/angular/cli/lib/config/schema.json @@ -387,7 +387,7 @@ "description": "Specifies the source locale of the application.", "default": "en-US", "$comment": "IETF BCP 47 language tag (simplified)", - "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$" + "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$" }, { "type": "object", @@ -396,7 +396,7 @@ "code": { "type": "string", "description": "Specifies the locale code of the source locale", - "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$" + "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$" }, "baseHref": { "type": "string", @@ -411,7 +411,7 @@ "type": "object", "additionalProperties": false, "patternProperties": { - "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$": { + "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$": { "oneOf": [ { "type": "string", @@ -2066,7 +2066,7 @@ "minItems": 1, "items": { "type": "string", - "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$" + "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$" } } ] diff --git a/packages/angular_devkit/build_angular/src/browser/schema.json b/packages/angular_devkit/build_angular/src/browser/schema.json index 74fbcd5eb83c..4a63aea215c3 100644 --- a/packages/angular_devkit/build_angular/src/browser/schema.json +++ b/packages/angular_devkit/build_angular/src/browser/schema.json @@ -211,7 +211,7 @@ "minItems": 1, "items": { "type": "string", - "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$" + "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$" } } ] diff --git a/packages/angular_devkit/build_angular/src/server/schema.json b/packages/angular_devkit/build_angular/src/server/schema.json index 6b58555169fc..f3b4e57c4165 100644 --- a/packages/angular_devkit/build_angular/src/server/schema.json +++ b/packages/angular_devkit/build_angular/src/server/schema.json @@ -175,7 +175,7 @@ "minItems": 1, "items": { "type": "string", - "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$" + "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$" } } ] diff --git a/packages/angular_devkit/build_angular/src/utils/i18n-options.ts b/packages/angular_devkit/build_angular/src/utils/i18n-options.ts index e00faf950ed0..43e6511a93e0 100644 --- a/packages/angular_devkit/build_angular/src/utils/i18n-options.ts +++ b/packages/angular_devkit/build_angular/src/utils/i18n-options.ts @@ -338,10 +338,13 @@ function findLocaleDataBasePath(projectRoot: string): string | null { } function findLocaleDataPath(locale: string, basePath: string): string | null { - const localeDataPath = path.join(basePath, locale + '.js'); + // Remove private use subtags + const scrubbedLocale = locale.replace(/-x(-[a-zA-Z0-9]{1,8})+$/, ''); + + const localeDataPath = path.join(basePath, scrubbedLocale + '.js'); if (!fs.existsSync(localeDataPath)) { - if (locale === 'en-US') { + if (scrubbedLocale === 'en-US') { // fallback to known existing en-US locale data as of 9.0 return findLocaleDataPath('en-US-POSIX', basePath); } diff --git a/packages/angular_devkit/core/src/experimental/workspace/workspace-schema.json b/packages/angular_devkit/core/src/experimental/workspace/workspace-schema.json index 52c3385afe6a..98ddb4b6d3bd 100644 --- a/packages/angular_devkit/core/src/experimental/workspace/workspace-schema.json +++ b/packages/angular_devkit/core/src/experimental/workspace/workspace-schema.json @@ -136,7 +136,7 @@ "type": "string", "description": "Specifies the source locale of the application.", "default": "en-US", - "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$" + "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$" }, { "type": "object", @@ -145,7 +145,7 @@ "code": { "type": "string", "description": "Specifies the locale code of the source locale", - "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$" + "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$" }, "baseHref": { "type": "string", @@ -160,7 +160,7 @@ "type": "object", "additionalProperties": false, "patternProperties": { - "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?$": { + "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$": { "oneOf": [ { "type": "string", diff --git a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-locale-data.ts b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-locale-data.ts index adc2be973e83..4d0628f571b5 100644 --- a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-locale-data.ts +++ b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-locale-data.ts @@ -43,4 +43,18 @@ export default async function() { throw new Error('locale data not found warning shown'); } + // Update angular.json + await updateJsonFile('angular.json', workspaceJson => { + const appProject = workspaceJson.projects['test-project']; + // tslint:disable-next-line: no-any + const i18n: Record = appProject.i18n; + + i18n.sourceLocale = 'en-x-abc'; + appProject.architect['build'].options.localize = ['en-x-abc']; + }); + + const { stderr: err3 } = await ng('build'); + if (err3.includes(`Locale data for 'en-x-abc' cannot be found. No locale data will be included for this locale.`)) { + throw new Error('locale data not found warning shown'); + } }