Открыть меню
Открыть персональное меню
Вы не представились системе
Your IP address will be publicly visible if you make any edits.

Модуль:FeatureFlag: различия между версиями

Материал из wiki.iccup.org
Нет описания правки
 
(нет различий)

Текущая версия от 15:09, 31 августа 2024


FeatureFlag Module Documentation[править код]

The `FeatureFlag` module is used to manage feature flags, which are boolean values controlling whether certain code paths related to new features are enabled or not. This module provides functionality to read, set, and temporarily apply feature flags.

Usage[править код]

Feature flags can be used to enable or disable specific features or parts of code. They can be set permanently or temporarily for a specific scope. This is useful for enabling experimental features, rolling out new functionalities gradually, or toggling features for debugging purposes.

Example Usage[править код]

To get the value of a feature flag: -- Get the current value of a feature flag local isEnabled = FeatureFlag.get('chiseled_face')

To set the value of a feature flag: -- Set a feature flag to true FeatureFlag.set('thick_mustache', true)

To apply feature flags temporarily inside a specific function scope: -- Temporarily set feature flags FeatureFlag.with({rugged_grin = true}, function()

   -- Code executed with the feature flag set

end)

API[править код]

Программное имя: FeatureFlag


get (flag: string) → boolean

Retrieves the boolean value of a feature flag. Returns the default value if the flag has not been set.




set (flag: string, value: boolean?) → nil

Sets the value of a feature flag. If the value is nil, it resets the flag to its default value.




with (flags: {[string]: boolean}, f: function) → Result of the function execution or an error

Temporarily sets feature flags inside the provided function scope. After execution, flags are restored to their previous values.




getConfig (flag: string) → table containing the defaultValue

Retrieves the configuration for a specified feature flag, including its default value.




Посмотрите всю нашу документацию iCCup здесь.



Feature Flag Configuration[править код]

Feature flags are configured in `Module:FeatureFlag/Config`. Each flag should have an entry specifying its default value. When a flag is accessed for the first time, its value is read from this configuration.

Wikitext Integration[править код]

Feature flags are accessible in wikitext using the VariablesLua extension. Example usage in wikitext:


Notes[править код]

- Ensure that `Module:FeatureFlag/Config` contains all feature flags used in the code. - Feature flags should be used responsibly to control feature rollouts and testing scenarios.

See Also[править код]



---
-- @iCCup
-- wiki=commons
-- page=Module:FeatureFlag
--
-- Please see https://github.com/iCCup/Lua-Modules to contribute
--

local FeatureFlagConfig = mw.loadData('Module:FeatureFlag/Config')
local Logic = require('Module:Logic')
local Table = require('Module:Table')

--[[
Module for reading and setting feature flags. Feature flags are boolean values
that control whether certain code paths pertaining to new features are enabled.
To create a new feature flag, add an entry to Module:FeatureFlag/Config.

Usage:
Feature flags can be read and written to. If the value has not been set, then
the configured default value is used.

FeatureFlag.get('chiseled_face')
FeatureFlag.set('thick_mustache', true)

Feature flags can be applied temporarily inside a scope.

FeatureFlag.with({rugged_grin = true}, function()
	-- ...
end)

Feature flags are also available in wikicode, with the exception of the
configured default value which is only available in lua.

{{#var:feature_chiseled_face}}
{{#vardefine:feature_thick_mustache|1}}

]]
local FeatureFlag = {}

local cachedFlags = {}

---Retrieves the boolean value of a feature flag. If the flag has not been
---previously set, this returns the configured default value of the flag.
---@param flag string
---@return boolean
function FeatureFlag.get(flag)
	if cachedFlags[flag] == nil then
		cachedFlags[flag] = FeatureFlag._get(flag)
	end
	return cachedFlags[flag]
end

---@param flag string
---@return boolean
function FeatureFlag._get(flag)
	local config = FeatureFlag.getConfig(flag)
	return Logic.nilOr(
		Logic.readBoolOrNil(mw.ext.VariablesLua.var('feature_' .. flag)),
		config.defaultValue,
		false
	)
end

---Sets the value of a feature flag. If value is nil, then this resets the value to the configured default.
---@param flag string
---@param value boolean?
function FeatureFlag.set(flag, value)
	FeatureFlag.getConfig(flag)
	if value ~= nil then
		mw.ext.VariablesLua.vardefine('feature_' .. flag, value and '1' or '0')
	else
		mw.ext.VariablesLua.vardefine('feature_' .. flag, '')
	end
	cachedFlags[flag] = nil
end

---Runs a function inside a scope where the specified flags are set.
---@generic V
---@param flags? {[string]: boolean}
---@param f fun(): V
---@return V|Error
function FeatureFlag.with(flags, f)
	if Table.isEmpty(flags) then
		return f()
	end
	---@cast flags -nil

	-- Remember previous flags
	local oldFlags = Table.map(flags, function(flag, value)
		return flag, mw.ext.VariablesLua.var('feature_' .. flag)
	end)

	-- Set new flags
	for flag, value in pairs(flags) do
		FeatureFlag.set(flag, value)
	end

	return Logic.try(f)
		:finally(function()
			-- Restore previous flags
			for flag, oldValue in pairs(oldFlags) do
				mw.ext.VariablesLua.vardefine('feature_' .. flag, oldValue)
				cachedFlags[flag] = nil
			end
		end)
		:get()
end

---@param flag string
---@return {defaultValue: boolean}
function FeatureFlag.getConfig(flag)
	local config = FeatureFlagConfig[flag]
	if not config then
		error('Unrecognized feature flag \'' .. flag .. '\'', 2)
	end
	return config
end

return FeatureFlag