From 28b4a0f776e2510f821a7c9d912c3c348857a729 Mon Sep 17 00:00:00 2001 From: Fahad Heylaal Date: Sat, 9 Mar 2024 16:10:53 +0100 Subject: [PATCH 01/48] feat: allow printing datafile per environment (#275) --- docs/building-datafiles.md | 8 ++++- packages/core/src/builder/buildDatafile.ts | 34 +++++++++++++++++++- packages/core/src/builder/buildProject.ts | 17 +++++----- packages/core/src/tester/testFeature.ts | 37 +++------------------- 4 files changed, 53 insertions(+), 43 deletions(-) diff --git a/docs/building-datafiles.md b/docs/building-datafiles.md index 0633a5bb..2b7fec01 100644 --- a/docs/building-datafiles.md +++ b/docs/building-datafiles.md @@ -54,12 +54,18 @@ $ featurevisor build --revision 1.2.3 ## Printing -You can print the contents of a datafile for a single feature without writing anything to disk by passing these flags: +You can print the contents of a datafile for a single feature in/or an environment without writing anything to disk by passing these flags: ``` $ featurevisor build --feature=foo --environment=production --print --pretty ``` +Or if you with to print datafile containing all features for a specific environment: + +``` +$ featurevisor build --environment=production --print --pretty +``` + This is useful primarily for debugging and testing purposes. If you are an SDK developer in other languages besides JavaScript, you may want to use this handy command to get the generated datafile content in JSON format that you can use in your own [test runner](/docs/testing). diff --git a/packages/core/src/builder/buildDatafile.ts b/packages/core/src/builder/buildDatafile.ts index c7ef3d49..d64d4e64 100644 --- a/packages/core/src/builder/buildDatafile.ts +++ b/packages/core/src/builder/buildDatafile.ts @@ -19,13 +19,45 @@ import { VariableSchema, } from "@featurevisor/types"; -import { ProjectConfig } from "../config"; +import { ProjectConfig, SCHEMA_VERSION } from "../config"; import { Datasource } from "../datasource"; import { extractAttributeKeysFromConditions, extractSegmentKeysFromGroupSegments } from "../utils"; import { getTraffic } from "./traffic"; import { getFeatureRanges } from "./getFeatureRanges"; +export interface CustomDatafileOptions { + featureKey?: string; + environment: string; + projectConfig: ProjectConfig; + datasource: Datasource; + revision?: string; +} + +export async function getCustomDatafile(options: CustomDatafileOptions): Promise { + let featuresToInclude; + + if (options.featureKey) { + const requiredChain = await options.datasource.getRequiredFeaturesChain(options.featureKey); + featuresToInclude = Array.from(requiredChain); + } + + const existingState = await options.datasource.readState(options.environment); + const datafileContent = await buildDatafile( + options.projectConfig, + options.datasource, + { + schemaVersion: SCHEMA_VERSION, + revision: options.revision || "tester", + environment: options.environment, + features: featuresToInclude, + }, + existingState, + ); + + return datafileContent; +} + export interface BuildOptions { schemaVersion: string; revision: string; diff --git a/packages/core/src/builder/buildProject.ts b/packages/core/src/builder/buildProject.ts index bf7164d6..1b44638a 100644 --- a/packages/core/src/builder/buildProject.ts +++ b/packages/core/src/builder/buildProject.ts @@ -2,8 +2,7 @@ import * as path from "path"; import { SCHEMA_VERSION } from "../config"; -import { buildDatafile } from "./buildDatafile"; -import { getDatafileForFeature } from "../tester"; +import { buildDatafile, getCustomDatafile } from "./buildDatafile"; import { Dependencies } from "../dependencies"; export interface BuildCLIOptions { @@ -23,20 +22,20 @@ export async function buildProject(deps: Dependencies, cliOptions: BuildCLIOptio * This build process does not write to disk, and prints only to stdout. * * This is ideally for test runners in other languages, - * when they wish to get datafile for a single feature, + * when they wish to get datafile for a single feature and/or environment, * so they can run tests against their own SDKs in other languages. * * This way we centralize the datafile generation in one place, * while tests can be run anywhere else. */ - if (cliOptions.environment && cliOptions.feature && cliOptions.print) { - const datafileContent = await getDatafileForFeature( - cliOptions.feature, - cliOptions.environment, + if (cliOptions.environment && cliOptions.print) { + const datafileContent = await getCustomDatafile({ + featureKey: cliOptions.feature, + environment: cliOptions.environment, projectConfig, datasource, - cliOptions.revision, - ); + revision: cliOptions.revision, + }); if (cliOptions.pretty) { console.log(JSON.stringify(datafileContent, null, 2)); diff --git a/packages/core/src/tester/testFeature.ts b/packages/core/src/tester/testFeature.ts index 44c7456d..8c873b23 100644 --- a/packages/core/src/tester/testFeature.ts +++ b/packages/core/src/tester/testFeature.ts @@ -9,39 +9,12 @@ import { createInstance, MAX_BUCKETED_NUMBER } from "@featurevisor/sdk"; import { Datasource } from "../datasource"; import { ProjectConfig } from "../config"; -import { buildDatafile } from "../builder"; -import { SCHEMA_VERSION } from "../config"; +import { getCustomDatafile } from "../builder"; import { checkIfArraysAreEqual } from "./checkIfArraysAreEqual"; import { checkIfObjectsAreEqual } from "./checkIfObjectsAreEqual"; import { getFeatureAssertionsFromMatrix } from "./matrix"; -export async function getDatafileForFeature( - featureKey: string, - environment: string, - projectConfig: ProjectConfig, - datasource: Datasource, - revision: string = "testing", -): Promise { - const requiredChain = await datasource.getRequiredFeaturesChain(featureKey); - const featuresToInclude = Array.from(requiredChain); - - const existingState = await datasource.readState(environment); - const datafileContent = await buildDatafile( - projectConfig, - datasource, - { - schemaVersion: SCHEMA_VERSION, - revision, - environment: environment, - features: featuresToInclude, - }, - existingState, - ); - - return datafileContent; -} - export async function testFeature( datasource: Datasource, projectConfig: ProjectConfig, @@ -85,12 +58,12 @@ export async function testFeature( const datafileContent = typeof datafileContentByEnvironment[assertion.environment] !== "undefined" ? datafileContentByEnvironment[assertion.environment] - : await getDatafileForFeature( - test.feature, - assertion.environment, + : await getCustomDatafile({ + featureKey: test.feature, + environment: assertion.environment, projectConfig, datasource, - ); + }); if (options.showDatafile) { console.log(""); From 1cbcd14baff3d689a425571e72e4c8bc82888053 Mon Sep 17 00:00:00 2001 From: fahad19 Date: Sat, 9 Mar 2024 15:13:39 +0000 Subject: [PATCH 02/48] v1.9.0 --- CHANGELOG.md | 11 ++++++++++ examples/example-1/CHANGELOG.md | 8 +++++++ examples/example-1/package.json | 4 ++-- examples/example-json/CHANGELOG.md | 8 +++++++ examples/example-json/package.json | 4 ++-- examples/example-toml/CHANGELOG.md | 8 +++++++ examples/example-toml/package.json | 4 ++-- examples/example-yml-include/CHANGELOG.md | 8 +++++++ examples/example-yml-include/package.json | 4 ++-- examples/example-yml/CHANGELOG.md | 8 +++++++ examples/example-yml/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 26 +++++++++++------------ packages/cli/CHANGELOG.md | 8 +++++++ packages/cli/package.json | 4 ++-- packages/core/CHANGELOG.md | 11 ++++++++++ packages/core/package.json | 2 +- 17 files changed, 97 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c69338d2..f230c24e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) + + +### Features + +* allow printing datafile per environment ([#275](https://github.com/featurevisor/featurevisor/issues/275)) ([28b4a0f](https://github.com/featurevisor/featurevisor/commit/28b4a0f776e2510f821a7c9d912c3c348857a729)) + + + + + # [1.8.0](https://github.com/featurevisor/featurevisor/compare/v1.7.3...v1.8.0) (2024-02-26) diff --git a/examples/example-1/CHANGELOG.md b/examples/example-1/CHANGELOG.md index f4145eb3..de67ad03 100644 --- a/examples/example-1/CHANGELOG.md +++ b/examples/example-1/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) + +**Note:** Version bump only for package @featurevisor/example-1 + + + + + # [1.8.0](https://github.com/featurevisor/featurevisor/compare/v1.7.3...v1.8.0) (2024-02-26) **Note:** Version bump only for package @featurevisor/example-1 diff --git a/examples/example-1/package.json b/examples/example-1/package.json index e2fdee0f..7cff33dd 100644 --- a/examples/example-1/package.json +++ b/examples/example-1/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-1", "private": true, - "version": "1.8.0", + "version": "1.9.0", "description": "For testing only", "scripts": { "lint": "featurevisor lint", @@ -14,6 +14,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.8.0" + "@featurevisor/cli": "^1.9.0" } } diff --git a/examples/example-json/CHANGELOG.md b/examples/example-json/CHANGELOG.md index 84f786ac..f853d33a 100644 --- a/examples/example-json/CHANGELOG.md +++ b/examples/example-json/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) + +**Note:** Version bump only for package @featurevisor/example-json + + + + + # [1.8.0](https://github.com/featurevisor/featurevisor/compare/v1.7.3...v1.8.0) (2024-02-26) **Note:** Version bump only for package @featurevisor/example-json diff --git a/examples/example-json/package.json b/examples/example-json/package.json index e8c03d86..b6473b7f 100644 --- a/examples/example-json/package.json +++ b/examples/example-json/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-json", "private": true, - "version": "1.8.0", + "version": "1.9.0", "description": "Featurevisor project with JSON definitions", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.8.0" + "@featurevisor/cli": "^1.9.0" } } diff --git a/examples/example-toml/CHANGELOG.md b/examples/example-toml/CHANGELOG.md index 02e0c191..b03e783a 100644 --- a/examples/example-toml/CHANGELOG.md +++ b/examples/example-toml/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) + +**Note:** Version bump only for package @featurevisor/example-toml + + + + + # [1.8.0](https://github.com/featurevisor/featurevisor/compare/v1.7.3...v1.8.0) (2024-02-26) **Note:** Version bump only for package @featurevisor/example-toml diff --git a/examples/example-toml/package.json b/examples/example-toml/package.json index cbc20078..c9b4144d 100644 --- a/examples/example-toml/package.json +++ b/examples/example-toml/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-toml", "private": true, - "version": "1.8.0", + "version": "1.9.0", "description": "Featurevisor project with TOML definitions", "scripts": { "lint": "featurevisor lint", @@ -13,7 +13,7 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.8.0", + "@featurevisor/cli": "^1.9.0", "toml": "^3.0.0" } } diff --git a/examples/example-yml-include/CHANGELOG.md b/examples/example-yml-include/CHANGELOG.md index 91e8bcdd..33f23953 100644 --- a/examples/example-yml-include/CHANGELOG.md +++ b/examples/example-yml-include/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) + +**Note:** Version bump only for package @featurevisor/example-yml-include + + + + + # [1.8.0](https://github.com/featurevisor/featurevisor/compare/v1.7.3...v1.8.0) (2024-02-26) **Note:** Version bump only for package @featurevisor/example-yml-include diff --git a/examples/example-yml-include/package.json b/examples/example-yml-include/package.json index 99d4978c..5afc8862 100644 --- a/examples/example-yml-include/package.json +++ b/examples/example-yml-include/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-yml-include", "private": true, - "version": "1.8.0", + "version": "1.9.0", "description": "Featurevisor project with YAML definitions and custom includes", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.8.0" + "@featurevisor/cli": "^1.9.0" } } diff --git a/examples/example-yml/CHANGELOG.md b/examples/example-yml/CHANGELOG.md index d3daabd1..1911ee52 100644 --- a/examples/example-yml/CHANGELOG.md +++ b/examples/example-yml/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) + +**Note:** Version bump only for package @featurevisor/example-yml + + + + + # [1.8.0](https://github.com/featurevisor/featurevisor/compare/v1.7.3...v1.8.0) (2024-02-26) **Note:** Version bump only for package @featurevisor/example-yml diff --git a/examples/example-yml/package.json b/examples/example-yml/package.json index 8c0d9171..7aeebda1 100644 --- a/examples/example-yml/package.json +++ b/examples/example-yml/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-yml", "private": true, - "version": "1.8.0", + "version": "1.9.0", "description": "Featurevisor project with YAML definitions", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.8.0" + "@featurevisor/cli": "^1.9.0" } } diff --git a/lerna.json b/lerna.json index a5746a11..61edca3e 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "1.8.0" + "version": "1.9.0" } diff --git a/package-lock.json b/package-lock.json index 8e6b5edf..1140becb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,38 +34,38 @@ }, "examples/example-1": { "name": "@featurevisor/example-1", - "version": "1.8.0", + "version": "1.9.0", "dependencies": { - "@featurevisor/cli": "^1.8.0" + "@featurevisor/cli": "^1.9.0" } }, "examples/example-json": { "name": "@featurevisor/example-json", - "version": "1.8.0", + "version": "1.9.0", "dependencies": { - "@featurevisor/cli": "^1.8.0" + "@featurevisor/cli": "^1.9.0" } }, "examples/example-toml": { "name": "@featurevisor/example-toml", - "version": "1.8.0", + "version": "1.9.0", "dependencies": { - "@featurevisor/cli": "^1.8.0", + "@featurevisor/cli": "^1.9.0", "toml": "^3.0.0" } }, "examples/example-yml": { "name": "@featurevisor/example-yml", - "version": "1.8.0", + "version": "1.9.0", "dependencies": { - "@featurevisor/cli": "^1.8.0" + "@featurevisor/cli": "^1.9.0" } }, "examples/example-yml-include": { "name": "@featurevisor/example-yml-include", - "version": "1.8.0", + "version": "1.9.0", "dependencies": { - "@featurevisor/cli": "^1.8.0" + "@featurevisor/cli": "^1.9.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -18779,10 +18779,10 @@ }, "packages/cli": { "name": "@featurevisor/cli", - "version": "1.8.0", + "version": "1.9.0", "license": "MIT", "dependencies": { - "@featurevisor/core": "^1.8.0", + "@featurevisor/core": "^1.9.0", "yargs": "^17.6.2" }, "bin": { @@ -18829,7 +18829,7 @@ }, "packages/core": { "name": "@featurevisor/core", - "version": "1.8.0", + "version": "1.9.0", "license": "MIT", "dependencies": { "@featurevisor/sdk": "^1.3.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index d324bd1d..e6726dbe 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) + +**Note:** Version bump only for package @featurevisor/cli + + + + + # [1.8.0](https://github.com/featurevisor/featurevisor/compare/v1.7.3...v1.8.0) (2024-02-26) diff --git a/packages/cli/package.json b/packages/cli/package.json index 7cce9e78..a9d8a983 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@featurevisor/cli", - "version": "1.8.0", + "version": "1.9.0", "description": "CLI package of Featurevisor", "main": "bin.js", "types": "lib/index.d.ts", @@ -47,7 +47,7 @@ }, "license": "MIT", "dependencies": { - "@featurevisor/core": "^1.8.0", + "@featurevisor/core": "^1.9.0", "yargs": "^17.6.2" }, "devDependencies": { diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 0d931bda..8c9ab45c 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) + + +### Features + +* allow printing datafile per environment ([#275](https://github.com/featurevisor/featurevisor/issues/275)) ([28b4a0f](https://github.com/featurevisor/featurevisor/commit/28b4a0f776e2510f821a7c9d912c3c348857a729)) + + + + + # [1.8.0](https://github.com/featurevisor/featurevisor/compare/v1.7.3...v1.8.0) (2024-02-26) diff --git a/packages/core/package.json b/packages/core/package.json index 249ea9cb..f0a30377 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@featurevisor/core", - "version": "1.8.0", + "version": "1.9.0", "description": "Core package of Featurevisor for Node.js usage", "main": "lib/index.js", "types": "lib/index.d.ts", From cefab8f8c0eb091c10bee213039920d55fa3957a Mon Sep 17 00:00:00 2001 From: Fahad Heylaal Date: Sun, 10 Mar 2024 18:53:27 +0100 Subject: [PATCH 03/48] feat: allow showing only failed specs in test runner (#276) --- docs/testing.md | 8 ++++++++ packages/cli/src/index.ts | 1 + packages/core/src/tester/testProject.ts | 16 ++++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/testing.md b/docs/testing.md index c0643a30..1c061a13 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -204,6 +204,14 @@ $ featurevisor test --showDatafile Printing datafile content for each and every tested feature can be very verbose, so we recommend using this option with `--keyPattern` to filter tests. +### `onlyFailures` + +If you are interested to see only the test specs that fail: + +``` +$ featurevisor test --onlyFailures +``` + ### `fast` By default, Featurevisor's test runner would generate a datafile for your feature against the desired environment for each assertion. diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index b58c75c5..830c0fb5 100755 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -149,6 +149,7 @@ async function main() { verbose: options.verbose || false, showDatafile: options.showDatafile || false, fast: options.fast || false, + onlyFailures: options.onlyFailures || false, }; const hasError = await testProject(deps, testOptions); diff --git a/packages/core/src/tester/testProject.ts b/packages/core/src/tester/testProject.ts index 479a563f..9bafdf5b 100644 --- a/packages/core/src/tester/testProject.ts +++ b/packages/core/src/tester/testProject.ts @@ -17,6 +17,7 @@ export interface TestProjectOptions { assertionPattern?: string; verbose?: boolean; showDatafile?: boolean; + onlyFailures?: boolean; fast?: boolean; } @@ -88,7 +89,15 @@ export async function executeTest( ); } - printTestResult(testResult, testFilePath, rootDirectoryPath); + if (!options.onlyFailures) { + // show all + printTestResult(testResult, testFilePath, rootDirectoryPath); + } else { + // show failed only + if (!testResult.passed) { + printTestResult(testResult, testFilePath, rootDirectoryPath); + } + } if (!testResult.passed) { executionResult.passed = false; @@ -185,7 +194,10 @@ export async function testProject( const diffInMs = Date.now() - startTime; - console.log("\n---\n"); + if (options.onlyFailures !== true || hasError) { + console.log("\n---"); + } + console.log(""); const testSpecsMessage = `Test specs: ${passedTestsCount} passed, ${failedTestsCount} failed`; const testAssertionsMessage = `Assertions: ${passedAssertionsCount} passed, ${failedAssertionsCount} failed`; From d64bb9d1e56a7e1f776d66a70284f894128a7cfe Mon Sep 17 00:00:00 2001 From: fahad19 Date: Sun, 10 Mar 2024 17:56:11 +0000 Subject: [PATCH 04/48] v1.10.0 --- CHANGELOG.md | 11 ++++++++++ examples/example-1/CHANGELOG.md | 8 +++++++ examples/example-1/package.json | 4 ++-- examples/example-json/CHANGELOG.md | 8 +++++++ examples/example-json/package.json | 4 ++-- examples/example-toml/CHANGELOG.md | 8 +++++++ examples/example-toml/package.json | 4 ++-- examples/example-yml-include/CHANGELOG.md | 8 +++++++ examples/example-yml-include/package.json | 4 ++-- examples/example-yml/CHANGELOG.md | 8 +++++++ examples/example-yml/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 26 +++++++++++------------ packages/cli/CHANGELOG.md | 11 ++++++++++ packages/cli/package.json | 4 ++-- packages/core/CHANGELOG.md | 11 ++++++++++ packages/core/package.json | 2 +- 17 files changed, 100 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f230c24e..19c101ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) + + +### Features + +* allow showing only failed specs in test runner ([#276](https://github.com/featurevisor/featurevisor/issues/276)) ([cefab8f](https://github.com/featurevisor/featurevisor/commit/cefab8f8c0eb091c10bee213039920d55fa3957a)) + + + + + # [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) diff --git a/examples/example-1/CHANGELOG.md b/examples/example-1/CHANGELOG.md index de67ad03..ddfd3fc0 100644 --- a/examples/example-1/CHANGELOG.md +++ b/examples/example-1/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-1 + + + + + # [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) **Note:** Version bump only for package @featurevisor/example-1 diff --git a/examples/example-1/package.json b/examples/example-1/package.json index 7cff33dd..2124364d 100644 --- a/examples/example-1/package.json +++ b/examples/example-1/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-1", "private": true, - "version": "1.9.0", + "version": "1.10.0", "description": "For testing only", "scripts": { "lint": "featurevisor lint", @@ -14,6 +14,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.9.0" + "@featurevisor/cli": "^1.10.0" } } diff --git a/examples/example-json/CHANGELOG.md b/examples/example-json/CHANGELOG.md index f853d33a..58296cd8 100644 --- a/examples/example-json/CHANGELOG.md +++ b/examples/example-json/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-json + + + + + # [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) **Note:** Version bump only for package @featurevisor/example-json diff --git a/examples/example-json/package.json b/examples/example-json/package.json index b6473b7f..e49232b6 100644 --- a/examples/example-json/package.json +++ b/examples/example-json/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-json", "private": true, - "version": "1.9.0", + "version": "1.10.0", "description": "Featurevisor project with JSON definitions", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.9.0" + "@featurevisor/cli": "^1.10.0" } } diff --git a/examples/example-toml/CHANGELOG.md b/examples/example-toml/CHANGELOG.md index b03e783a..f0d67426 100644 --- a/examples/example-toml/CHANGELOG.md +++ b/examples/example-toml/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-toml + + + + + # [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) **Note:** Version bump only for package @featurevisor/example-toml diff --git a/examples/example-toml/package.json b/examples/example-toml/package.json index c9b4144d..baf6e1fe 100644 --- a/examples/example-toml/package.json +++ b/examples/example-toml/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-toml", "private": true, - "version": "1.9.0", + "version": "1.10.0", "description": "Featurevisor project with TOML definitions", "scripts": { "lint": "featurevisor lint", @@ -13,7 +13,7 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.9.0", + "@featurevisor/cli": "^1.10.0", "toml": "^3.0.0" } } diff --git a/examples/example-yml-include/CHANGELOG.md b/examples/example-yml-include/CHANGELOG.md index 33f23953..529e5de3 100644 --- a/examples/example-yml-include/CHANGELOG.md +++ b/examples/example-yml-include/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-yml-include + + + + + # [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) **Note:** Version bump only for package @featurevisor/example-yml-include diff --git a/examples/example-yml-include/package.json b/examples/example-yml-include/package.json index 5afc8862..87ef0ae0 100644 --- a/examples/example-yml-include/package.json +++ b/examples/example-yml-include/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-yml-include", "private": true, - "version": "1.9.0", + "version": "1.10.0", "description": "Featurevisor project with YAML definitions and custom includes", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.9.0" + "@featurevisor/cli": "^1.10.0" } } diff --git a/examples/example-yml/CHANGELOG.md b/examples/example-yml/CHANGELOG.md index 1911ee52..bc74df7e 100644 --- a/examples/example-yml/CHANGELOG.md +++ b/examples/example-yml/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-yml + + + + + # [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) **Note:** Version bump only for package @featurevisor/example-yml diff --git a/examples/example-yml/package.json b/examples/example-yml/package.json index 7aeebda1..c3149a1f 100644 --- a/examples/example-yml/package.json +++ b/examples/example-yml/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-yml", "private": true, - "version": "1.9.0", + "version": "1.10.0", "description": "Featurevisor project with YAML definitions", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.9.0" + "@featurevisor/cli": "^1.10.0" } } diff --git a/lerna.json b/lerna.json index 61edca3e..211e22bb 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "1.9.0" + "version": "1.10.0" } diff --git a/package-lock.json b/package-lock.json index 1140becb..d6b499c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,38 +34,38 @@ }, "examples/example-1": { "name": "@featurevisor/example-1", - "version": "1.9.0", + "version": "1.10.0", "dependencies": { - "@featurevisor/cli": "^1.9.0" + "@featurevisor/cli": "^1.10.0" } }, "examples/example-json": { "name": "@featurevisor/example-json", - "version": "1.9.0", + "version": "1.10.0", "dependencies": { - "@featurevisor/cli": "^1.9.0" + "@featurevisor/cli": "^1.10.0" } }, "examples/example-toml": { "name": "@featurevisor/example-toml", - "version": "1.9.0", + "version": "1.10.0", "dependencies": { - "@featurevisor/cli": "^1.9.0", + "@featurevisor/cli": "^1.10.0", "toml": "^3.0.0" } }, "examples/example-yml": { "name": "@featurevisor/example-yml", - "version": "1.9.0", + "version": "1.10.0", "dependencies": { - "@featurevisor/cli": "^1.9.0" + "@featurevisor/cli": "^1.10.0" } }, "examples/example-yml-include": { "name": "@featurevisor/example-yml-include", - "version": "1.9.0", + "version": "1.10.0", "dependencies": { - "@featurevisor/cli": "^1.9.0" + "@featurevisor/cli": "^1.10.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -18779,10 +18779,10 @@ }, "packages/cli": { "name": "@featurevisor/cli", - "version": "1.9.0", + "version": "1.10.0", "license": "MIT", "dependencies": { - "@featurevisor/core": "^1.9.0", + "@featurevisor/core": "^1.10.0", "yargs": "^17.6.2" }, "bin": { @@ -18829,7 +18829,7 @@ }, "packages/core": { "name": "@featurevisor/core", - "version": "1.9.0", + "version": "1.10.0", "license": "MIT", "dependencies": { "@featurevisor/sdk": "^1.3.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index e6726dbe..d70ce192 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) + + +### Features + +* allow showing only failed specs in test runner ([#276](https://github.com/featurevisor/featurevisor/issues/276)) ([cefab8f](https://github.com/featurevisor/featurevisor/commit/cefab8f8c0eb091c10bee213039920d55fa3957a)) + + + + + # [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) **Note:** Version bump only for package @featurevisor/cli diff --git a/packages/cli/package.json b/packages/cli/package.json index a9d8a983..957b161f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@featurevisor/cli", - "version": "1.9.0", + "version": "1.10.0", "description": "CLI package of Featurevisor", "main": "bin.js", "types": "lib/index.d.ts", @@ -47,7 +47,7 @@ }, "license": "MIT", "dependencies": { - "@featurevisor/core": "^1.9.0", + "@featurevisor/core": "^1.10.0", "yargs": "^17.6.2" }, "devDependencies": { diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 8c9ab45c..3815780c 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) + + +### Features + +* allow showing only failed specs in test runner ([#276](https://github.com/featurevisor/featurevisor/issues/276)) ([cefab8f](https://github.com/featurevisor/featurevisor/commit/cefab8f8c0eb091c10bee213039920d55fa3957a)) + + + + + # [1.9.0](https://github.com/featurevisor/featurevisor/compare/v1.8.0...v1.9.0) (2024-03-09) diff --git a/packages/core/package.json b/packages/core/package.json index f0a30377..4fed1a42 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@featurevisor/core", - "version": "1.9.0", + "version": "1.10.0", "description": "Core package of Featurevisor for Node.js usage", "main": "lib/index.js", "types": "lib/index.d.ts", From 1e46d7992a632ce956e8821dbaae9677bef59a43 Mon Sep 17 00:00:00 2001 From: Fahad Heylaal Date: Sun, 10 Mar 2024 19:16:00 +0100 Subject: [PATCH 05/48] fix: init command (#277) --- packages/cli/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 830c0fb5..c56395b3 100755 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -44,8 +44,9 @@ function requireAndGetProjectConfig(rootDirectoryPath) { return getProjectConfig(rootDirectoryPath); } +const rootDirectoryPath = process.cwd(); + async function getDependencies(options): Promise { - const rootDirectoryPath = process.cwd(); const projectConfig = requireAndGetProjectConfig(rootDirectoryPath); const datasource = new Datasource(projectConfig, rootDirectoryPath); @@ -67,8 +68,7 @@ async function main() { .command({ command: "init", handler: async function (options) { - const deps = await getDependencies(options); - const hasError = await initProject(deps.rootDirectoryPath, options.example); + const hasError = await initProject(rootDirectoryPath, options.example); if (hasError) { process.exit(1); From bd13be0f41f544340ee68f92d5c9661e3399f3f3 Mon Sep 17 00:00:00 2001 From: fahad19 Date: Sun, 10 Mar 2024 18:18:35 +0000 Subject: [PATCH 06/48] v1.10.1 --- CHANGELOG.md | 11 +++++++++++ examples/example-1/CHANGELOG.md | 8 ++++++++ examples/example-1/package.json | 4 ++-- examples/example-json/CHANGELOG.md | 8 ++++++++ examples/example-json/package.json | 4 ++-- examples/example-toml/CHANGELOG.md | 8 ++++++++ examples/example-toml/package.json | 4 ++-- examples/example-yml-include/CHANGELOG.md | 8 ++++++++ examples/example-yml-include/package.json | 4 ++-- examples/example-yml/CHANGELOG.md | 8 ++++++++ examples/example-yml/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 22 +++++++++++----------- packages/cli/CHANGELOG.md | 11 +++++++++++ packages/cli/package.json | 2 +- 15 files changed, 85 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19c101ea..cd787c00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) + + +### Bug Fixes + +* init command ([#277](https://github.com/featurevisor/featurevisor/issues/277)) ([1e46d79](https://github.com/featurevisor/featurevisor/commit/1e46d7992a632ce956e8821dbaae9677bef59a43)) + + + + + # [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) diff --git a/examples/example-1/CHANGELOG.md b/examples/example-1/CHANGELOG.md index ddfd3fc0..c66df284 100644 --- a/examples/example-1/CHANGELOG.md +++ b/examples/example-1/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-1 + + + + + # [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-1 diff --git a/examples/example-1/package.json b/examples/example-1/package.json index 2124364d..19912369 100644 --- a/examples/example-1/package.json +++ b/examples/example-1/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-1", "private": true, - "version": "1.10.0", + "version": "1.10.1", "description": "For testing only", "scripts": { "lint": "featurevisor lint", @@ -14,6 +14,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.0" + "@featurevisor/cli": "^1.10.1" } } diff --git a/examples/example-json/CHANGELOG.md b/examples/example-json/CHANGELOG.md index 58296cd8..63b88f91 100644 --- a/examples/example-json/CHANGELOG.md +++ b/examples/example-json/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-json + + + + + # [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-json diff --git a/examples/example-json/package.json b/examples/example-json/package.json index e49232b6..196608aa 100644 --- a/examples/example-json/package.json +++ b/examples/example-json/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-json", "private": true, - "version": "1.10.0", + "version": "1.10.1", "description": "Featurevisor project with JSON definitions", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.0" + "@featurevisor/cli": "^1.10.1" } } diff --git a/examples/example-toml/CHANGELOG.md b/examples/example-toml/CHANGELOG.md index f0d67426..b99e0ea8 100644 --- a/examples/example-toml/CHANGELOG.md +++ b/examples/example-toml/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-toml + + + + + # [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-toml diff --git a/examples/example-toml/package.json b/examples/example-toml/package.json index baf6e1fe..d2b11624 100644 --- a/examples/example-toml/package.json +++ b/examples/example-toml/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-toml", "private": true, - "version": "1.10.0", + "version": "1.10.1", "description": "Featurevisor project with TOML definitions", "scripts": { "lint": "featurevisor lint", @@ -13,7 +13,7 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.0", + "@featurevisor/cli": "^1.10.1", "toml": "^3.0.0" } } diff --git a/examples/example-yml-include/CHANGELOG.md b/examples/example-yml-include/CHANGELOG.md index 529e5de3..0b097605 100644 --- a/examples/example-yml-include/CHANGELOG.md +++ b/examples/example-yml-include/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-yml-include + + + + + # [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-yml-include diff --git a/examples/example-yml-include/package.json b/examples/example-yml-include/package.json index 87ef0ae0..aba640b4 100644 --- a/examples/example-yml-include/package.json +++ b/examples/example-yml-include/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-yml-include", "private": true, - "version": "1.10.0", + "version": "1.10.1", "description": "Featurevisor project with YAML definitions and custom includes", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.0" + "@featurevisor/cli": "^1.10.1" } } diff --git a/examples/example-yml/CHANGELOG.md b/examples/example-yml/CHANGELOG.md index bc74df7e..306b9907 100644 --- a/examples/example-yml/CHANGELOG.md +++ b/examples/example-yml/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-yml + + + + + # [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-yml diff --git a/examples/example-yml/package.json b/examples/example-yml/package.json index c3149a1f..133b9fc9 100644 --- a/examples/example-yml/package.json +++ b/examples/example-yml/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-yml", "private": true, - "version": "1.10.0", + "version": "1.10.1", "description": "Featurevisor project with YAML definitions", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.0" + "@featurevisor/cli": "^1.10.1" } } diff --git a/lerna.json b/lerna.json index 211e22bb..21526b64 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "1.10.0" + "version": "1.10.1" } diff --git a/package-lock.json b/package-lock.json index d6b499c9..e4ca5104 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,38 +34,38 @@ }, "examples/example-1": { "name": "@featurevisor/example-1", - "version": "1.10.0", + "version": "1.10.1", "dependencies": { - "@featurevisor/cli": "^1.10.0" + "@featurevisor/cli": "^1.10.1" } }, "examples/example-json": { "name": "@featurevisor/example-json", - "version": "1.10.0", + "version": "1.10.1", "dependencies": { - "@featurevisor/cli": "^1.10.0" + "@featurevisor/cli": "^1.10.1" } }, "examples/example-toml": { "name": "@featurevisor/example-toml", - "version": "1.10.0", + "version": "1.10.1", "dependencies": { - "@featurevisor/cli": "^1.10.0", + "@featurevisor/cli": "^1.10.1", "toml": "^3.0.0" } }, "examples/example-yml": { "name": "@featurevisor/example-yml", - "version": "1.10.0", + "version": "1.10.1", "dependencies": { - "@featurevisor/cli": "^1.10.0" + "@featurevisor/cli": "^1.10.1" } }, "examples/example-yml-include": { "name": "@featurevisor/example-yml-include", - "version": "1.10.0", + "version": "1.10.1", "dependencies": { - "@featurevisor/cli": "^1.10.0" + "@featurevisor/cli": "^1.10.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -18779,7 +18779,7 @@ }, "packages/cli": { "name": "@featurevisor/cli", - "version": "1.10.0", + "version": "1.10.1", "license": "MIT", "dependencies": { "@featurevisor/core": "^1.10.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index d70ce192..a16ff64e 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) + + +### Bug Fixes + +* init command ([#277](https://github.com/featurevisor/featurevisor/issues/277)) ([1e46d79](https://github.com/featurevisor/featurevisor/commit/1e46d7992a632ce956e8821dbaae9677bef59a43)) + + + + + # [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) diff --git a/packages/cli/package.json b/packages/cli/package.json index 957b161f..95ff170d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@featurevisor/cli", - "version": "1.10.0", + "version": "1.10.1", "description": "CLI package of Featurevisor", "main": "bin.js", "types": "lib/index.d.ts", From 6a175d1be01c1ab78661bbd93d535de69af47135 Mon Sep 17 00:00:00 2001 From: Fahad Heylaal Date: Sun, 10 Mar 2024 19:42:03 +0100 Subject: [PATCH 07/48] feat: revisioning info moved to its own file (#274) --- README.md | 14 ++--- docs/building-datafiles.md | 8 +-- docs/cli.md | 42 +++++++------- docs/code-generation.md | 2 +- docs/deployment.md | 22 +++---- docs/integrations/cloudflare-pages.md | 47 +++++++-------- docs/integrations/github-actions.md | 57 +++++++++++-------- docs/linting.md | 6 +- docs/quick-start.md | 28 +++------ docs/site.md | 4 +- docs/state-files.md | 2 +- docs/testing.md | 14 ++--- docs/use-cases/microfrontends.md | 2 +- packages/cli/README.md | 24 ++++---- packages/core/src/builder/buildProject.ts | 18 ++++-- packages/core/src/builder/revision.spec.ts | 22 +++++++ packages/core/src/builder/revision.ts | 22 +++++++ packages/core/src/datasource/adapter.ts | 4 ++ packages/core/src/datasource/datasource.ts | 11 ++++ .../core/src/datasource/filesystemAdapter.ts | 39 +++++++++++++ 20 files changed, 237 insertions(+), 151 deletions(-) create mode 100644 packages/core/src/builder/revision.spec.ts create mode 100644 packages/core/src/builder/revision.ts diff --git a/README.md b/README.md index 071fe937..245ac781 100644 --- a/README.md +++ b/README.md @@ -102,17 +102,13 @@ The whole process can be broken down into 3 steps: ## Step 1: Create a Featurevisor project -Install Featurevisor CLI globally (or use `npx @featurevisor/cli`): - -``` -$ npm install -g @featurevisor/cli -``` - -Initialize a new Featurevisor project: +Use `npx` to scaffold a new Featurevisor project: ``` $ mkdir my-featurevisor-project && cd my-featurevisor-project -$ featurevisor init + +$ npx @featurevisor/cli init +$ npm install ``` You can now create and manage your feature flags, experiments, and remote config in this directory expressed as YAMLs. @@ -128,7 +124,7 @@ See the building block guides here: Once the project is ready, you can build your datafiles (JSON files containing configuration of your feature flags): ``` -$ featurevisor build +$ npx featurevisor build ``` You will find the output in `dist` directory, that you can upload to your CDN. diff --git a/docs/building-datafiles.md b/docs/building-datafiles.md index 2b7fec01..623cbb93 100644 --- a/docs/building-datafiles.md +++ b/docs/building-datafiles.md @@ -10,7 +10,7 @@ Datafiles are JSON files that are created against combinations of tags and envir Use Featurevisor CLI to build your datafiles: ``` -$ featurevisor build +$ npx featurevisor build ``` ## Output @@ -49,7 +49,7 @@ By default, Featurevisor will use the `version` as exists in `package.json` of t You can optionally customize the `revision` value in datafiles by passing a `--revision` flag when building: ``` -$ featurevisor build --revision 1.2.3 +$ npx featurevisor build --revision 1.2.3 ``` ## Printing @@ -57,13 +57,13 @@ $ featurevisor build --revision 1.2.3 You can print the contents of a datafile for a single feature in/or an environment without writing anything to disk by passing these flags: ``` -$ featurevisor build --feature=foo --environment=production --print --pretty +$ npx featurevisor build --feature=foo --environment=production --print --pretty ``` Or if you with to print datafile containing all features for a specific environment: ``` -$ featurevisor build --environment=production --print --pretty +$ npx featurevisor build --environment=production --print --pretty ``` This is useful primarily for debugging and testing purposes. diff --git a/docs/cli.md b/docs/cli.md index 0b7474d5..d7ab4eb4 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -8,33 +8,29 @@ Beyond just initializing a project and building datafiles, Featurevisor CLI can ## Installation -Install with `npm`: +Use `npx` to initialize a project first: ``` -$ npm install -g @featurevisor/cli +$ mkdir my-featurevisor-project && cd my-featurevisor-project +$ npx @featurevisor/cli init ``` -Or use `npx` to run the CLI without installing it: +If you wish to initialize a specific example as available in the [monorepo](https://github.com/featurevisor/featurevisor/tree/main/examples): ``` -$ npx @featurevisor/cli +$ npx @featurevisor/cli init --example ``` -Rest of the documentation assumes that you have installed the CLI globally. - -## Initializing a project - -Scaffold a new project in your working directory: +After you have installed the dependencies in the project: ``` -$ mkdir my-project && cd my-project -$ featurevisor init -``` +$ npm install +`` -If you wish to initialize a specific example as available in the [monorepo](https://github.com/featurevisor/featurevisor/tree/main/examples): +You can access the Featurevisor CLI from inside the project via: ``` -$ featurevisor init --example +$ npx featurevisor ``` Learn more in [Quick start](/docs/quick-start). @@ -44,7 +40,7 @@ Learn more in [Quick start](/docs/quick-start). Check if the YAML files have any syntax or structural errors: ``` -$ featurevisor lint +$ npx featurevisor lint ``` Lear more in [Linting](/docs/linting). @@ -54,7 +50,7 @@ Lear more in [Linting](/docs/linting). Generate JSON files on a per environment and tag combination as exists in project [configuration](/docs/configuration): ``` -$ featurevisor build +$ npx featurevisor build ``` Learn more in [Building datafiles](/docs/building-datafiles). @@ -64,7 +60,7 @@ Learn more in [Building datafiles](/docs/building-datafiles). Test your features and segments: ``` -$ featurevisor test +$ npx featurevisor test ``` Learn more in [Testing](/docs/testing). @@ -76,7 +72,7 @@ Building datafiles also generates [state files](/docs/state-files). To restore them to last known state in Git, run: ``` -$ featurevisor restore +$ npx featurevisor restore ``` ## Generate static site @@ -84,19 +80,19 @@ $ featurevisor restore Build the site: ``` -$ featurevisor site export +$ npx featurevisor site export ``` Serve the built site (defaults to port 3000): ``` -$ featurevisor site serve +$ npx featurevisor site serve ``` Serve it in a specific port: ``` -$ featurevisor site serve -p 3000 +$ npx featurevisor site serve -p 3000 ``` Learn more in [Status site](/docs/status-site). @@ -107,7 +103,7 @@ Learn more in [Status site](/docs/status-site). Generate TypeScript code from your YAMLs: ``` -$ featurevisor generate-code --language typescript --out-dir ./src +$ npx featurevisor generate-code --language typescript --out-dir ./src ``` See output in `./src` directory. @@ -121,5 +117,5 @@ It is possible to end up with multiple segments having same conditions in larger We can find these duplicates early on by running: ``` -$ featurevisor find-duplicate-segments +$ npx featurevisor find-duplicate-segments ``` diff --git a/docs/code-generation.md b/docs/code-generation.md index cffa8002..8391989d 100644 --- a/docs/code-generation.md +++ b/docs/code-generation.md @@ -27,7 +27,7 @@ Support for other languages is planned in future, as Featurevisor SDK becomes av From the root of your Featurevisor project directory, use the [CLI](/docs/cli) for generating code in a specified directory: ``` -$ featurevisor generate-code --language typescript --out-dir ./src +$ npx featurevisor generate-code --language typescript --out-dir ./src ``` The generated files can be found in `./src` directory. diff --git a/docs/deployment.md b/docs/deployment.md index 92ceab15..f7074c63 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -11,36 +11,36 @@ We recommend that you set up a CI/CD pipeline to automate the build and deployme When a new Pull Request (branch) is merged, the CI/CD pipeline should: -### Lint your files +### Linting Lint all the attributes, segments, and feature definitions: ``` -$ fearurevisor lint +$ npx featurevisor lint ``` -### Version your project +### Testing + +Test all the features and segments: ``` -$ npm version patch +$ npx featurevisor test ``` -The new `version` value as available in `package.json` file will be used when building datafiles. - ### Build the datafiles ``` -$ featurevisor build +$ npx featurevisor build ``` ### Commit the state files ``` -$ git add . -$ git commit -m "State files" +$ git add .featurevisor/* +$ git commit -m "[skip ci] Revision $(cat .featurevisor/REVISION)" ``` -Only the state files should be committed as available under `.featurevisor` directory. The generated datafiles in `dist` directory are ignored. +Only the [state files](/docs/state-files) should be committed as available under `.featurevisor` directory. The generated datafiles in `dist` directory are ignored from Git. ### Upload to your CDN @@ -53,7 +53,7 @@ You can use the `dist` directory as the root directory for your CDN. We want to make sure the next Pull Request merge will be on top of the latest version and state files. ``` -$ git push origin main --tags +$ git push origin main ``` If any of the steps above fail, the CI/CD pipeline should stop and notify the team. diff --git a/docs/integrations/cloudflare-pages.md b/docs/integrations/cloudflare-pages.md index 864430c9..3e53adea 100644 --- a/docs/integrations/cloudflare-pages.md +++ b/docs/integrations/cloudflare-pages.md @@ -14,15 +14,11 @@ This guide assumes you have created a new Featurevisor project using the CLI: ``` $ mkdir my-featurevisor-project && cd my-featurevisor-project + $ npx @featurevisor/cli init +$ npm install ``` -The initialized project will already contain the npm scripts for linting, building, and testing your project: - -- `lint`: `featurevisor lint` -- `build`: `featurevisor build` -- `test`: `featurevisor test` - ## Cloudflare Pages We are going to be uploading to and serving our datafiles from [Cloudflare Pages](https://pages.cloudflare.com/). @@ -78,13 +74,13 @@ jobs: run: npm ci - name: Lint - run: npm run lint - - - name: Build - run: npm run build + run: npx featurevisor lint - name: Test specs - run: npm test + run: npx featurevisor test + + - name: Build + run: npx featurevisor build ``` ### Publish @@ -117,21 +113,13 @@ jobs: run: npm ci - name: Lint - run: npm run lint - - - name: Git configs - run: | - git config user.name "${{ github.actor }}" - git config user.email "${{ github.actor }}@users.noreply.github.com" + run: npx featurevisor lint - - name: Version - run: npm version patch + - name: Test specs + run: npx featurevisor test - name: Build - run: npm run build - - - name: Test specs - run: npm test + run: npx featurevisor build - name: Upload to Cloudflare Pages run: | @@ -141,10 +129,15 @@ jobs: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + - name: Git configs + run: | + git config user.name "${{ github.actor }}" + git config user.email "${{ github.actor }}@users.noreply.github.com" + - name: Push back to origin run: | git add .featurevisor/* - git commit --amend --no-edit + git commit -m "[skip ci] Revision $(cat .featurevisor/REVISION)" git push ``` @@ -154,8 +147,12 @@ Once uploaded, the your datafiles will be accessible as: `https:// You may want to take it a step further by setting up custom domains (or subdomains) for your Cloudflare Pages project. Otherwise, you are good to go. -Learn how too consume datafiles from URLs directly using [SDKs](/docs/sdks). +Learn how to consume datafiles from URLs directly using [SDKs](/docs/sdks). ## Full example You can find a fully functional repository based on this guide here: [https://github.com/featurevisor/featurevisor-example-cloudflare](https://github.com/featurevisor/featurevisor-example-cloudflare). + +## Sequential builds + +In case you are worried about simultaneous builds triggered by multiple Pull Requests merged in quick succession, you can learn about mitigating any unintended issues [here](/docs/integrations/github-actions/#sequential-builds). diff --git a/docs/integrations/github-actions.md b/docs/integrations/github-actions.md index e1ae40bc..c2db331c 100644 --- a/docs/integrations/github-actions.md +++ b/docs/integrations/github-actions.md @@ -14,15 +14,11 @@ This guide assumes you have created a new Featurevisor project using the CLI: ``` $ mkdir my-featurevisor-project && cd my-featurevisor-project + $ npx @featurevisor/cli init +$ npm install ``` -The initialized project will already contain the npm scripts for linting, building, and testing your project: - -- `lint`: `featurevisor lint` -- `build`: `featurevisor build` -- `test`: `featurevisor test` - ## Repository settings Make sure you have `Read and write permissions` enabled in your GitHub repository's `Settings > Actions > General > Workflow permissions` section. @@ -63,13 +59,13 @@ jobs: run: npm ci - name: Lint - run: npm run lint - - - name: Build - run: npm run build + run: npx featurevisor lint - name: Test specs - run: npm test + run: npx featurevisor test + + - name: Build + run: npx featurevisor build ``` ### Publish @@ -102,33 +98,46 @@ jobs: run: npm ci - name: Lint - run: npm run lint + run: npx featurevisor lint - - name: Git configs - run: | - git config user.name "${{ github.actor }}" - git config user.email "${{ github.actor }}@users.noreply.github.com" - - - name: Version - run: npm version patch + - name: Test specs + run: npx featurevisor test - name: Build - run: npm run build - - - name: Test specs - run: npm test + run: npx featurevisor build - name: Upload datafiles run: echo "Uploading..." # Update it accordingly based on your CDN set up + - name: Git configs + run: | + git config user.name "${{ github.actor }}" + git config user.email "${{ github.actor }}@users.noreply.github.com" + - name: Push back to origin run: | git add .featurevisor/* - git commit --amend --no-edit + git commit -m "[skip ci] Revision $(cat .featurevisor/REVISION)" git push ``` After generating new datafiles and uploading them, the workflow will also take care of pushing the Featurevisor [state files](/docs/state-files) back to the repository, so that future builds will be built on top of latest state. If you want an example of an actual uploading step, see [Cloudflare Pages](/docs/integrations/cloudflare-pages/) integration guide. + +## Sequential builds + +It is possible you might want to run the publish workflow sequentially for every merged Pull Requests, in case multiple Pull Requests are merged in quick succession. + +### Queue + +You can consider using [softprops/turnstyle](https://github.com/softprops/turnstyle) GitHub Action to run publish workflow of all your merged Pull Requests sequentially. + +### Branch protection rules + +Next to it, you can also make it stricter by requiring all Pull Request authors to have their branches up to date from latest main branch before merging: + +- [Managing suggestions to update pull request branches](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-suggestions-to-update-pull-request-branches) +- [Create branch protection rule](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule#creating-a-branch-protection-rule) (see #7) + - Require branches to be up to date before merging diff --git a/docs/linting.md b/docs/linting.md index 9ee85129..8a690376 100644 --- a/docs/linting.md +++ b/docs/linting.md @@ -10,7 +10,7 @@ Featurevisor provides a CLI command to lint your definition files, making sure t Run: ``` -$ featurevisor lint +$ npx featurevisor lint ``` And it will show you the errors in your definition files, if any. @@ -24,7 +24,7 @@ If any errors are found, it will terminate with a non-zero exit code. You can also filter keys using regex patterns: ``` -$ featurevisor lint --keyPattern="myKeyHere" +$ npx featurevisor lint --keyPattern="myKeyHere" ``` ### `entityType` @@ -32,7 +32,7 @@ $ featurevisor lint --keyPattern="myKeyHere" If you want to filter it down further by entity type: ``` -$ featurevisor lint --keyPattern="myKeyHere" --entityType="feature" +$ npx featurevisor lint --keyPattern="myKeyHere" --entityType="feature" ``` Possible values for `--entityType`: diff --git a/docs/quick-start.md b/docs/quick-start.md index 4367193f..f65e591a 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -8,20 +8,6 @@ ogImage: /img/og/docs-quick-start.png - [Node.js](https://nodejs.org/en/) >= 16.0.0 -## Installation - -Easiest way to get started is by using the Featurevisor CLI. - -``` -$ npm install -g @featurevisor/cli -``` - -If you want to avoid global installation, you can use `npx` instead: - -``` -$ npx @featurevisor/cli -``` - ## Initialize your project This is meant to be a completely separate repository from your application code. @@ -31,21 +17,21 @@ The idea is to be able to decouple your application deployments from releasing y Run the following command to initialize your project: ``` -$ mkdir my-project && cd my-project -$ featurevisor init +$ mkdir my-featurevisor-project && cd my-featurevisor-project +$ npx @featurevisor/cli init ``` If you want to initialize a specific example: ``` -$ featurevisor init --example +$ npx @featurevisor/cli init --example ``` You can find all available examples [here](/docs/examples). -## Dependencies +## Installation -We start by installing all the necessary local dependencies: +Once your project has been initialized, install all the dependencies: ``` $ npm install @@ -153,7 +139,7 @@ environments: We can lint the content of all our files to make sure they are all valid: ``` -$ featurevisor lint +$ npx featurevisor lint ``` Learn more in [Linting](/docs/linting). @@ -165,7 +151,7 @@ Datafiles are JSON files that we expect our client-side applications to consume Now that we have all the configuration in place, we can build the project: ``` -$ featurevisor build +$ npx featurevisor build ``` This will generate datafiles in the `dist` directory for each of your tags against each environment as defined in your `featurevisor.config.js` file. diff --git a/docs/site.md b/docs/site.md index b9c77251..b75ea622 100644 --- a/docs/site.md +++ b/docs/site.md @@ -24,7 +24,7 @@ The git repo also needs to have an `origin` remote set up, in order for the edit Use Featurevisor CLI: ``` -$ featurevisor site export +$ npx featurevisor site export ``` The generated static site will be available in the `out` directory. @@ -34,7 +34,7 @@ The generated static site will be available in the `out` directory. Run: ``` -$ featurevisor site serve +$ npx featurevisor site serve ``` ## Screenshots diff --git a/docs/state-files.md b/docs/state-files.md index 7a5f0570..f9ac9406 100644 --- a/docs/state-files.md +++ b/docs/state-files.md @@ -22,7 +22,7 @@ We will learn more about it in [Deployment](/docs/deployment). If you have already built your datafiles, you can restore the state files to the last known state in Git by running: ``` -$ featurevisor restore +$ npx featurevisor restore ``` This will only work if the state files already exist in the Git repository. diff --git a/docs/testing.md b/docs/testing.md index 1c061a13..0d8db677 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -163,7 +163,7 @@ This helps us cover more scenarios by having to write less code in our specs. Use the Featurevisor CLI to run your tests: ``` -$ featurevisor test +$ npx featurevisor test ``` If any of your assertions fail in any test specs, it will terminate with a non-zero exit code. @@ -175,7 +175,7 @@ If any of your assertions fail in any test specs, it will terminate with a non-z You can also filter tests by feature or segment keys using regex patterns: ``` -$ featurevisor test --keyPattern="myKeyHere" +$ npx featurevisor test --keyPattern="myKeyHere" ``` ### `assertionPattern` @@ -183,7 +183,7 @@ $ featurevisor test --keyPattern="myKeyHere" If you are writing assertion descriptions, then you can filter them further using regex patterns: ``` -$ featurevisor test --keyPattern="myKeyHere" --assertionPattern="text..." +$ npx featurevisor test --keyPattern="myKeyHere" --assertionPattern="text..." ``` ### `verbose` @@ -191,7 +191,7 @@ $ featurevisor test --keyPattern="myKeyHere" --assertionPattern="text..." For debugging purposes, you can enable verbose mode to see more details of your assertion evaluations ``` -$ featurevisor test --verbose +$ npx featurevisor test --verbose ``` ### `showDatafile` @@ -199,7 +199,7 @@ $ featurevisor test --verbose For more advanced debugging, you can print the datafile content used by test runner: ``` -$ featurevisor test --showDatafile +$ npx featurevisor test --showDatafile ``` Printing datafile content for each and every tested feature can be very verbose, so we recommend using this option with `--keyPattern` to filter tests. @@ -209,7 +209,7 @@ Printing datafile content for each and every tested feature can be very verbose, If you are interested to see only the test specs that fail: ``` -$ featurevisor test --onlyFailures +$ npx featurevisor test --onlyFailures ``` ### `fast` @@ -219,7 +219,7 @@ By default, Featurevisor's test runner would generate a datafile for your featur If you have a lot of tests, this can be time-consuming. You can use the `--fast` option to generate datafiles for each environment early packing all the features in the project together, and then run the assertions: ``` -$ featurevisor test --fast +$ npx featurevisor test --fast ``` **Note**: This approach is memory intensive and therefore not the default behaviour yet. diff --git a/docs/use-cases/microfrontends.md b/docs/use-cases/microfrontends.md index f7f5dbc7..d5d1fe05 100644 --- a/docs/use-cases/microfrontends.md +++ b/docs/use-cases/microfrontends.md @@ -102,7 +102,7 @@ module.exports = { Once this configuration is in place, we can [build](/docs/building-datafiles) our datafiles: ``` -$ featurevisor build +$ npx featurevisor build ``` And it will output the following datafiles in the `dist` directory: diff --git a/packages/cli/README.md b/packages/cli/README.md index 80c3792b..75fe1679 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -7,13 +7,7 @@ Visit [https://featurevisor.com/docs/cli](https://featurevisor.com/docs/cli) for ## Installation ``` -$ npm install -g @featurevisor/cli -``` - -Or via `npx`: - -``` -$ npx featurevisor +$ npm install --save-dev @featurevisor/cli ``` ## Usage @@ -23,13 +17,15 @@ $ npx featurevisor Initialize your project. ``` -$ featurevisor init +$ mkdir my-featurevisor-project && cd my-featurevisor-project +$ npx @featurevisor/cli init +$ npm install ``` If you want to initialize your project with a specific example: ``` -$ featurevisor init --example +$ npx @featurevisor/cli init --example ``` Examples found [here](../../examples). @@ -39,7 +35,7 @@ Examples found [here](../../examples). Check if your YAMLs are valid. ``` -$ featurevisor lint +$ npx featurevisor lint ``` @@ -48,7 +44,7 @@ $ featurevisor lint Build your datafiles. ``` -$ featurevisor build +$ npx featurevisor build ``` ### `test` @@ -56,7 +52,7 @@ $ featurevisor build Test your generated datafiles using the SDK, against specs written in YAMLs. ``` -$ featurevisor test +$ npx featurevisor test ``` See test specs in YAMLs [here](../../examples/example-1/tests) for inspiration. @@ -66,8 +62,8 @@ See test specs in YAMLs [here](../../examples/example-1/tests) for inspiration. Start a local server to view your project's site. ``` -$ featurevisor site export -$ featurevisor site serve +$ npx featurevisor site export +$ npx featurevisor site serve ``` ## License diff --git a/packages/core/src/builder/buildProject.ts b/packages/core/src/builder/buildProject.ts index 1b44638a..34fd9df3 100644 --- a/packages/core/src/builder/buildProject.ts +++ b/packages/core/src/builder/buildProject.ts @@ -1,7 +1,6 @@ -import * as path from "path"; - import { SCHEMA_VERSION } from "../config"; +import { getNextRevision } from "./revision"; import { buildDatafile, getCustomDatafile } from "./buildDatafile"; import { Dependencies } from "../dependencies"; @@ -16,7 +15,7 @@ export interface BuildCLIOptions { } export async function buildProject(deps: Dependencies, cliOptions: BuildCLIOptions = {}) { - const { rootDirectoryPath, projectConfig, datasource } = deps; + const { projectConfig, datasource } = deps; /** * This build process does not write to disk, and prints only to stdout. @@ -52,7 +51,11 @@ export async function buildProject(deps: Dependencies, cliOptions: BuildCLIOptio const tags = projectConfig.tags; const environments = projectConfig.environments; - const pkg = require(path.join(rootDirectoryPath, "package.json")); + const currentRevision = await datasource.readRevision(); + console.log("\nCurrent revision:", currentRevision); + + const nextRevision = + (cliOptions.revision && cliOptions.revision.toString()) || getNextRevision(currentRevision); for (const environment of environments) { console.log(`\nBuilding datafiles for environment: ${environment}`); @@ -67,7 +70,7 @@ export async function buildProject(deps: Dependencies, cliOptions: BuildCLIOptio datasource, { schemaVersion: SCHEMA_VERSION, - revision: cliOptions.revision || pkg.version, + revision: nextRevision, environment: environment, tag: tag, }, @@ -83,5 +86,10 @@ export async function buildProject(deps: Dependencies, cliOptions: BuildCLIOptio // write state for environment await datasource.writeState(environment, existingState); + + // write revision + await datasource.writeRevision(nextRevision); } + + console.log("\nLatest revision:", nextRevision); } diff --git a/packages/core/src/builder/revision.spec.ts b/packages/core/src/builder/revision.spec.ts new file mode 100644 index 00000000..f573409b --- /dev/null +++ b/packages/core/src/builder/revision.spec.ts @@ -0,0 +1,22 @@ +import { getNextRevision } from "./revision"; + +describe("core: Revision", function () { + it("should be a function", function () { + expect(typeof getNextRevision).toEqual("function"); + }); + + it("should return next version number", function () { + // string-string + expect(getNextRevision("")).toEqual("1"); + expect(getNextRevision("random text")).toEqual("1"); + + // string-numeric + expect(getNextRevision("1")).toEqual("2"); + expect(getNextRevision("2024")).toEqual("2025"); + + // string-semver + expect(getNextRevision("1.0.0")).toEqual("1"); + expect(getNextRevision("0.0.0")).toEqual("1"); + expect(getNextRevision("0.0.1523")).toEqual("1524"); + }); +}); diff --git a/packages/core/src/builder/revision.ts b/packages/core/src/builder/revision.ts new file mode 100644 index 00000000..b96a09e8 --- /dev/null +++ b/packages/core/src/builder/revision.ts @@ -0,0 +1,22 @@ +export function getNextRevision(currentRevision: string) { + // If the string is empty or can't be parsed with parseInt(), return "1". + if (!currentRevision || isNaN(parseInt(currentRevision, 10))) { + return "1"; + } + + // If the string is like an integer, increment it by 1 and return the value. + if (currentRevision.indexOf(".") === -1) { + return (parseInt(currentRevision, 10) + 1).toString(); + } + + // If the string is a semver, parse the patch version out of it, increment it by one and return it. + const parts = currentRevision.split("."); + const lastPart = parseInt(parts[parts.length - 1], 10); + + if (!isNaN(lastPart)) { + return (lastPart + 1).toString(); + } + + // If the string can't be parsed as a semver, return "1". + return "1"; +} diff --git a/packages/core/src/datasource/adapter.ts b/packages/core/src/datasource/adapter.ts index a1b4ed28..970006db 100644 --- a/packages/core/src/datasource/adapter.ts +++ b/packages/core/src/datasource/adapter.ts @@ -29,6 +29,10 @@ export abstract class Adapter { abstract readDatafile(options: DatafileOptions): Promise; abstract writeDatafile(datafileContent: DatafileContent, options: DatafileOptions): Promise; + // revision + abstract readRevision(): Promise; + abstract writeRevision(revision: string): Promise; + // history abstract listHistoryEntries(entityType?: EntityType, entityKey?: string): Promise; abstract readCommit( diff --git a/packages/core/src/datasource/datasource.ts b/packages/core/src/datasource/datasource.ts index 182c4b8f..584df3d4 100644 --- a/packages/core/src/datasource/datasource.ts +++ b/packages/core/src/datasource/datasource.ts @@ -40,6 +40,17 @@ export class Datasource { return this.adapter.writeState(environment, existingState); } + /** + * Revision + */ + readRevision() { + return this.adapter.readRevision(); + } + + writeRevision(revision: string) { + return this.adapter.writeRevision(revision); + } + /** * Datafile */ diff --git a/packages/core/src/datasource/filesystemAdapter.ts b/packages/core/src/datasource/filesystemAdapter.ts index a72f9a03..816d33a2 100644 --- a/packages/core/src/datasource/filesystemAdapter.ts +++ b/packages/core/src/datasource/filesystemAdapter.ts @@ -28,6 +28,10 @@ export function getExistingStateFilePath( return path.join(projectConfig.stateDirectoryPath, `existing-state-${environment}.json`); } +export function getRevisionFilePath(projectConfig: ProjectConfig): string { + return path.join(projectConfig.stateDirectoryPath, `REVISION`); +} + export class FilesystemAdapter extends Adapter { private parser: CustomParser; @@ -136,6 +140,41 @@ export class FilesystemAdapter extends Adapter { fs.writeFileSync(filePath, JSON.stringify(existingState, null, 2)); } + /** + * Revision + */ + async readRevision(): Promise { + const filePath = getRevisionFilePath(this.config); + + if (fs.existsSync(filePath)) { + return fs.readFileSync(filePath, "utf8"); + } + + // maintain backwards compatibility + try { + const pkg = require(path.join(this.rootDirectoryPath as string, "package.json")); + const pkgVersion = pkg.version; + + if (pkgVersion) { + return pkgVersion; + } + + return "0"; + } catch (e) { + return "0"; + } + } + + async writeRevision(revision: string): Promise { + const filePath = getRevisionFilePath(this.config); + + if (!fs.existsSync(this.config.stateDirectoryPath)) { + mkdirp.sync(this.config.stateDirectoryPath); + } + + fs.writeFileSync(filePath, revision); + } + /** * Datafile */ From 92ff9153a53a9a2182c3dc3994dbdca9f76e3dc5 Mon Sep 17 00:00:00 2001 From: fahad19 Date: Sun, 10 Mar 2024 18:44:44 +0000 Subject: [PATCH 08/48] v1.11.0 --- CHANGELOG.md | 11 ++++++++++ examples/example-1/CHANGELOG.md | 8 +++++++ examples/example-1/package.json | 4 ++-- examples/example-json/CHANGELOG.md | 8 +++++++ examples/example-json/package.json | 4 ++-- examples/example-toml/CHANGELOG.md | 8 +++++++ examples/example-toml/package.json | 4 ++-- examples/example-yml-include/CHANGELOG.md | 8 +++++++ examples/example-yml-include/package.json | 4 ++-- examples/example-yml/CHANGELOG.md | 8 +++++++ examples/example-yml/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 26 +++++++++++------------ packages/cli/CHANGELOG.md | 11 ++++++++++ packages/cli/package.json | 4 ++-- packages/core/CHANGELOG.md | 11 ++++++++++ packages/core/package.json | 2 +- 17 files changed, 100 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd787c00..bcf19141 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.11.0](https://github.com/featurevisor/featurevisor/compare/v1.10.1...v1.11.0) (2024-03-10) + + +### Features + +* revisioning info moved to its own file ([#274](https://github.com/featurevisor/featurevisor/issues/274)) ([6a175d1](https://github.com/featurevisor/featurevisor/commit/6a175d1be01c1ab78661bbd93d535de69af47135)) + + + + + ## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) diff --git a/examples/example-1/CHANGELOG.md b/examples/example-1/CHANGELOG.md index c66df284..fb8dbddb 100644 --- a/examples/example-1/CHANGELOG.md +++ b/examples/example-1/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.11.0](https://github.com/featurevisor/featurevisor/compare/v1.10.1...v1.11.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-1 + + + + + ## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-1 diff --git a/examples/example-1/package.json b/examples/example-1/package.json index 19912369..81d78488 100644 --- a/examples/example-1/package.json +++ b/examples/example-1/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-1", "private": true, - "version": "1.10.1", + "version": "1.11.0", "description": "For testing only", "scripts": { "lint": "featurevisor lint", @@ -14,6 +14,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.1" + "@featurevisor/cli": "^1.11.0" } } diff --git a/examples/example-json/CHANGELOG.md b/examples/example-json/CHANGELOG.md index 63b88f91..99363c3e 100644 --- a/examples/example-json/CHANGELOG.md +++ b/examples/example-json/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.11.0](https://github.com/featurevisor/featurevisor/compare/v1.10.1...v1.11.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-json + + + + + ## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-json diff --git a/examples/example-json/package.json b/examples/example-json/package.json index 196608aa..d221caaf 100644 --- a/examples/example-json/package.json +++ b/examples/example-json/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-json", "private": true, - "version": "1.10.1", + "version": "1.11.0", "description": "Featurevisor project with JSON definitions", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.1" + "@featurevisor/cli": "^1.11.0" } } diff --git a/examples/example-toml/CHANGELOG.md b/examples/example-toml/CHANGELOG.md index b99e0ea8..fa6f3753 100644 --- a/examples/example-toml/CHANGELOG.md +++ b/examples/example-toml/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.11.0](https://github.com/featurevisor/featurevisor/compare/v1.10.1...v1.11.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-toml + + + + + ## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-toml diff --git a/examples/example-toml/package.json b/examples/example-toml/package.json index d2b11624..b98f5c7f 100644 --- a/examples/example-toml/package.json +++ b/examples/example-toml/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-toml", "private": true, - "version": "1.10.1", + "version": "1.11.0", "description": "Featurevisor project with TOML definitions", "scripts": { "lint": "featurevisor lint", @@ -13,7 +13,7 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.1", + "@featurevisor/cli": "^1.11.0", "toml": "^3.0.0" } } diff --git a/examples/example-yml-include/CHANGELOG.md b/examples/example-yml-include/CHANGELOG.md index 0b097605..f547dc1c 100644 --- a/examples/example-yml-include/CHANGELOG.md +++ b/examples/example-yml-include/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.11.0](https://github.com/featurevisor/featurevisor/compare/v1.10.1...v1.11.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-yml-include + + + + + ## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-yml-include diff --git a/examples/example-yml-include/package.json b/examples/example-yml-include/package.json index aba640b4..cebb6c4b 100644 --- a/examples/example-yml-include/package.json +++ b/examples/example-yml-include/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-yml-include", "private": true, - "version": "1.10.1", + "version": "1.11.0", "description": "Featurevisor project with YAML definitions and custom includes", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.1" + "@featurevisor/cli": "^1.11.0" } } diff --git a/examples/example-yml/CHANGELOG.md b/examples/example-yml/CHANGELOG.md index 306b9907..7d32874f 100644 --- a/examples/example-yml/CHANGELOG.md +++ b/examples/example-yml/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.11.0](https://github.com/featurevisor/featurevisor/compare/v1.10.1...v1.11.0) (2024-03-10) + +**Note:** Version bump only for package @featurevisor/example-yml + + + + + ## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) **Note:** Version bump only for package @featurevisor/example-yml diff --git a/examples/example-yml/package.json b/examples/example-yml/package.json index 133b9fc9..c7fa4d97 100644 --- a/examples/example-yml/package.json +++ b/examples/example-yml/package.json @@ -1,7 +1,7 @@ { "name": "@featurevisor/example-yml", "private": true, - "version": "1.10.1", + "version": "1.11.0", "description": "Featurevisor project with YAML definitions", "scripts": { "lint": "featurevisor lint", @@ -13,6 +13,6 @@ "find-duplicate-segments": "featurevisor find-duplicate-segments" }, "dependencies": { - "@featurevisor/cli": "^1.10.1" + "@featurevisor/cli": "^1.11.0" } } diff --git a/lerna.json b/lerna.json index 21526b64..ff802f0d 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "1.10.1" + "version": "1.11.0" } diff --git a/package-lock.json b/package-lock.json index e4ca5104..0cceb446 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,38 +34,38 @@ }, "examples/example-1": { "name": "@featurevisor/example-1", - "version": "1.10.1", + "version": "1.11.0", "dependencies": { - "@featurevisor/cli": "^1.10.1" + "@featurevisor/cli": "^1.11.0" } }, "examples/example-json": { "name": "@featurevisor/example-json", - "version": "1.10.1", + "version": "1.11.0", "dependencies": { - "@featurevisor/cli": "^1.10.1" + "@featurevisor/cli": "^1.11.0" } }, "examples/example-toml": { "name": "@featurevisor/example-toml", - "version": "1.10.1", + "version": "1.11.0", "dependencies": { - "@featurevisor/cli": "^1.10.1", + "@featurevisor/cli": "^1.11.0", "toml": "^3.0.0" } }, "examples/example-yml": { "name": "@featurevisor/example-yml", - "version": "1.10.1", + "version": "1.11.0", "dependencies": { - "@featurevisor/cli": "^1.10.1" + "@featurevisor/cli": "^1.11.0" } }, "examples/example-yml-include": { "name": "@featurevisor/example-yml-include", - "version": "1.10.1", + "version": "1.11.0", "dependencies": { - "@featurevisor/cli": "^1.10.1" + "@featurevisor/cli": "^1.11.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -18779,10 +18779,10 @@ }, "packages/cli": { "name": "@featurevisor/cli", - "version": "1.10.1", + "version": "1.11.0", "license": "MIT", "dependencies": { - "@featurevisor/core": "^1.10.0", + "@featurevisor/core": "^1.11.0", "yargs": "^17.6.2" }, "bin": { @@ -18829,7 +18829,7 @@ }, "packages/core": { "name": "@featurevisor/core", - "version": "1.10.0", + "version": "1.11.0", "license": "MIT", "dependencies": { "@featurevisor/sdk": "^1.3.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a16ff64e..fcdcafe5 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.11.0](https://github.com/featurevisor/featurevisor/compare/v1.10.1...v1.11.0) (2024-03-10) + + +### Features + +* revisioning info moved to its own file ([#274](https://github.com/featurevisor/featurevisor/issues/274)) ([6a175d1](https://github.com/featurevisor/featurevisor/commit/6a175d1be01c1ab78661bbd93d535de69af47135)) + + + + + ## [1.10.1](https://github.com/featurevisor/featurevisor/compare/v1.10.0...v1.10.1) (2024-03-10) diff --git a/packages/cli/package.json b/packages/cli/package.json index 95ff170d..de4d6d64 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@featurevisor/cli", - "version": "1.10.1", + "version": "1.11.0", "description": "CLI package of Featurevisor", "main": "bin.js", "types": "lib/index.d.ts", @@ -47,7 +47,7 @@ }, "license": "MIT", "dependencies": { - "@featurevisor/core": "^1.10.0", + "@featurevisor/core": "^1.11.0", "yargs": "^17.6.2" }, "devDependencies": { diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 3815780c..2d26a40e 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.11.0](https://github.com/featurevisor/featurevisor/compare/v1.10.1...v1.11.0) (2024-03-10) + + +### Features + +* revisioning info moved to its own file ([#274](https://github.com/featurevisor/featurevisor/issues/274)) ([6a175d1](https://github.com/featurevisor/featurevisor/commit/6a175d1be01c1ab78661bbd93d535de69af47135)) + + + + + # [1.10.0](https://github.com/featurevisor/featurevisor/compare/v1.9.0...v1.10.0) (2024-03-10) diff --git a/packages/core/package.json b/packages/core/package.json index 4fed1a42..8f5b14e2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@featurevisor/core", - "version": "1.10.0", + "version": "1.11.0", "description": "Core package of Featurevisor for Node.js usage", "main": "lib/index.js", "types": "lib/index.d.ts", From a9f5c157e30487f14aea7e217884881044176a2c Mon Sep 17 00:00:00 2001 From: Fahad Heylaal Date: Sun, 10 Mar 2024 20:07:28 +0100 Subject: [PATCH 09/48] docs: fix code block --- docs/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli.md b/docs/cli.md index d7ab4eb4..268ce5a8 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -25,7 +25,7 @@ After you have installed the dependencies in the project: ``` $ npm install -`` +``` You can access the Featurevisor CLI from inside the project via: From d5847de089dae8096c42865a42dd08110ef5e76d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Che=C5=82kowski?= Date: Sun, 10 Mar 2024 20:16:44 +0100 Subject: [PATCH 10/48] docs: add Roku SDK documentation (#272) --- docs/sdks/index.md | 3 +- docs/sdks/roku.md | 509 ++++++++++++++++++++++++++++++++++++ docs/sidebarNavigation.json | 3 +- 3 files changed, 513 insertions(+), 2 deletions(-) create mode 100644 docs/sdks/roku.md diff --git a/docs/sdks/index.md b/docs/sdks/index.md index a3565faf..f7db36d3 100644 --- a/docs/sdks/index.md +++ b/docs/sdks/index.md @@ -5,11 +5,12 @@ description: Learn how to use Featurevisor SDKs SDKs are meant to be used in your own applications, where you want to evaluate features in the application runtime. {% .lead %} -JavaScript environments are supported first: +Supported environments: - [JavaScript](/docs/sdks/javascript) - [Node.js](/docs/sdks/nodejs) - [Browser](/docs/sdks/browser) +- [Roku](/docs/sdks/roku) With other languages to follow very soon: diff --git a/docs/sdks/roku.md b/docs/sdks/roku.md new file mode 100644 index 00000000..4d38115c --- /dev/null +++ b/docs/sdks/roku.md @@ -0,0 +1,509 @@ +--- +title: Roku SDK +description: Learn how to use Featurevisor Roku SDK +ogImage: /img/og/docs-sdks-roku.png +--- + +BrightScript SDK for Roku is meant to be used with [kopytko-framework](https://github.com/getndazn/kopytko-framework). {% .lead %} + +However, if you don't use it, you can simply copy all SDK files and their dependencies to your project (a version will be prepared in the future if anyone is interested). + +## Installation + +Install with npm: + +```bash +npm i -P @featurevisor/roku +``` + +## Introduction + +The BrightScript implementation is a bit different than the JS one, as in BrightScript to be able to keep our instance separated and keep it globally, the SDK would need to be a SceneGraph Node. But to provide a bit similar API to the JS SDK we have introduced 2 main entities. One is the `FeaturevisorInstance` node, and the other is the function `FeaturevisorSDK` (that returns an object with methods mirroring JS SDK functions). The `FeaturevisorSDK` operates on the `FeaturevisorInstance` that is created by it or passed to it. + +**That's why all functions presented in this documentation are `FeaturevisorSDK` methods (or exactly, of the object returned by `FeaturevisorSDK()`)** + +There are a couple of methods to handle Featurevisor in your Roku App, for example: + +- create a new SceneGraph Node that will save in its context the FeaturevisorSDK() and create your abstraction based on FeaturevisorSDK. Later save this whole node globally +- create with FeaturevisorSDK an instance that you will save globally and later pass each time to `FeaturevisorSDK().createInstance({}, existingInstance)` before using its methods. + +For this documentation, we assume there will be a new node created for the integration (first variant). +We will call it `MyFeaturevisorInstance` and all code will be invoked inside this node (in the `MyFeaturevisorInstance.brs` for the below example). +The value returned by `FeaturevisorSDK()` will be called `f`, or if needed saved in the context - `m.f`. + +XML definition: + +```xml + + + + + + + +