codetags
v0.1.2
Published
A simple feature toggle utility
Downloads
83
Readme
codetags
A simple feature toggle utility
What is codetags
?
codetags
is a simple feature toggle utility for javascript/nodejs. Developers could use this library to prepare new features and switch the features by using environment variables.
How does it work?
Retrieving a codetags
instance
A default codetags
instance can be retrieved simply by a require
call:
const codetags = require('codetags');
We can create multiple codetags's instance
with newInstance
or getInstance
methods. Call to both will create a codetags instance, but the getInstance
creates a new instance only if it has not existed before.
const codetags = require('codetags');
const space1 = codetags.getInstance('main', {
namespace: 'maincode'
});
const space2 = codetags.newInstance('test', {
namespace: 'testcode'
});
// ...
const space3 = codetags.getInstance('main', {
namespace: 'maincode'
});
console.log(space3 === space1); // true
const space4 = codetags.newInstance('test', {
namespace: 'testcode'
});
console.log(space4 === space2); // false
Initializing default tags
Default tags can be initialized by register()
method:
codetags_instance.register(an_array_of_tag_descriptors);
For example:
codetags.register(['a-simple-tag']);
similar to:
codetags.register([
{
name: 'a-simple-tag',
enabled: true
}
]);
More complex example:
codetags.register([
'foo',
{
name: 'bar'
},
{
name: 'nil',
enabled: false
}
]);
Wrapping code in a tags filter expression
const codetags = require('codetags');
// ...
if (codetags.isActive('foo')) {
// do something
}
if (tryit.isActive(['foo', 'bar'])) {
// do other things
}
Enable/disable tags
Declare environment variables:
export CODETAGS_INCLUDED_TAGS=nil,foo
export CODETAGS_EXCLUDED_TAGS=bar
Start node program:
node index.js
Methods
.initialize(kwargs)
The kwargs
composes of following fields:
namespace
- a customized namespace.INCLUDED_TAGS
- a customized label for included tags environment variable name (default:INCLUDED_TAGS
).EXCLUDED_TAGS
- a customized label for excluded tags environment variable name (default:EXCLUDED_TAGS
).version
- the current package version.
This method returns the codetags
instance itself.
.register(descriptors)
Method register()
is used to define the default declaredTags
collection.
The argument descriptors
is an array of descriptor
objects which of each describing a string label together with the range of versions that will be applied.
const descriptor1 = {
name: 'tag-1',
plan: {
minBound: '0.1.3',
enabled: true
}
}
const descriptor2 = {
name: 'tag-2',
plan: {
maxBound: '0.2.7',
enabled: false
}
}
const descriptor3 = {
name: 'tag-3',
plan: {
minBound: '0.1.2',
maxBound: '0.2.8',
enabled: false
}
}
const descriptors = [ descriptor1, descriptor2, descriptor3 ];
codetags.register(descriptors);
This method returns the codetags
instance itself.
.isActive(tagexps)
Method isActive()
evaluates tags filter expressions (named tagexp
) based on three collections of tags (declaredTags
, includedTags
, excludedTags
) to determine whether it is accepted or denied. An expression of tags is composed by string labels, arrays, hashmaps and conditional operators ($all
, $any
, $not
).
tagexp
is a single string
Syntax:
const tagexp = 'tagexp-is-a-string';
if (codetags.isActive(tagexp)) {
// do something
}
Function call codetags.isActive(tagexp)
returns true
when:
excludedTags
does not containtagexp-is-a-string
;- at least one of
includedTags
anddeclaredTags
containstagexp-is-a-string
.
tagexp
is an array of sub-tagexps
Syntax:
const tagexp = [subtagexp_1, subtagexp_2, subtagexp_3];
if (codetags.isActive(tagexp)) {
// do something
}
Function call codetags.isActive(tagexp)
returns true
if all of sub-tagexp in the array must satisfy the function codetags.isActive
(i.e. codetags.isActive(subtagexp_i))
return true
for any i
from 1
to 3
).
tagexp
is a conditional expression
Syntax:
const tagexp = {
$all: [
{
$not: subtagexp_0,
$any: [ subtagexp_1, subtagexp_2, subtagexp_3 ]
},
{
$any: [ subtagexp_4, subtagexp_5 ]
}
]
};
if (codetags.isActive(tagexp)) {
// do something
}
Function call codetags.isActive(tagexp)
returns true
if the sub-tagexps are satisfied the following constraints:
codetags.isActive(subtagexp_0)
returnsfalse
;- one of
codetags.isActive(subtagexp_i)
returnstrue
(withi
from1
to3
); - one of
codetags.isActive(subtagexp_j)
returnstrue
(withj
is4
or5
);
arguments
is a sequence of tagexps
Syntax:
codetags.isActive(tagexp1, tagexp2, tagexp3);
The above function call will return true
if there is at least one of tagexp
arguments satisfies the function codetags.isActive
. It is equivalent to the following expression:
codetags.isActive(tagexp1) || codetags.isActive(tagexp2) || codetags.isActive(tagexp3)
.clearCache()
Method clearCache()
clears the cached values of tags filtering result as well as the cached values of environment variables. This method returns the codetags instance itself.
.reset()
Method reset()
invokes the method clearCache()
as well as clears the values of declaredTags
collection that has been defined by register()
method. This method also returns the codetags
instance itself.
.newInstance(name, opts)
Method newInstance()
creates a new instance in each time it is called and assigns name
to this instance. The name
value is associated with the latest instance. If you want to retrieve the already created instance, using getInstance
instead. The arguments can be:
name
: a string as name (using ingetInstance()
to retrieve the instance);opts
: an option object that is similar to which ininitialize()
;
This method returns the created instance.
.getInstance(name, opts)
Method getInstance()
returns the instance associated to name
or creates a new instance when it has not existed before. Its arguments are the same as the method newInstance()
.
Examples
Default codetags instance
Register feature tags:
// file: bootstrap.js
const codetags = require('codetags');
codetags.register([
{
name: 'replace-console-log-with-winston',
enabled: false
},
{
name: 'moving-from-mongodb-to-couchbase',
enabled: true
},
]);
Check the state of tags:
// file: index.js
require('./bootstrap.js');
const codetags = require('codetags');
// ...
if (codetags.isActive('replace-console-log-with-winston')) {
// be disabled by default
winston.log('debug', 'Hello world from winston');
} else {
console.log('Hello world from console.log');
}
Change state of tags with environment variables:
export CODETAGS_INCLUDED_TAGS=replace-console-log-with-winston
export CODETAGS_EXCLUDED_TAGS=moving-from-mongodb-to-couchbase
node index.js
Multiple instances
Create multiple codetags
instances:
// file: bootstrap.js
const codetags = require('codetags');
// features for trunk branch
const trunk = codetags.newInstance('trunk', {
namespace: 'my_mission'
});
trunk.register([
{
name: 'replace-console-log-with-winston',
enabled: false
},
{
name: 'moving-from-mongodb-to-couchbase',
enabled: true
},
]);
// features for trial branch
const trial = codetags.newInstance('trial', {
namespace: 'my_passion'
});
trial.register(['foo', 'bar']);
Make conditional flow:
// file: index.js
require('./bootstrap.js');
const codetags = require('codetags');
const trunk = codetags.getInstance('trunk');
const tryit = codetags.getInstance('trial');
// ...
if (trunk.isActive('replace-console-log-with-winston')) {
// be disabled by default
winston.log('debug', 'Hello world from winston');
} else {
console.log('Hello world from console.log');
}
// ...
if (tryit.isActive('foo')) {
// do something here
}
if (tryit.isActive(['foo', 'bar'])) {
// and here
}
if (tryit.isActive('foo', 'bar')) {
// and here
}
Change state of tags with environment variables:
export MY_MISSION_INCLUDED_TAGS=replace-console-log-with-winston
export MY_PASSION_EXCLUDED_TAGS=foo,bar
node index.js
License
MIT
See LICENSE to see the full text.