<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.iccup.org/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AFeatureFlag</id>
	<title>Модуль:FeatureFlag - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.iccup.org/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AFeatureFlag"/>
	<link rel="alternate" type="text/html" href="https://wiki.iccup.org/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:FeatureFlag&amp;action=history"/>
	<updated>2026-05-31T08:31:06Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://wiki.iccup.org/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:FeatureFlag&amp;diff=128&amp;oldid=prev</id>
		<title>DarkMuse в 15:09, 31 августа 2024</title>
		<link rel="alternate" type="text/html" href="https://wiki.iccup.org/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:FeatureFlag&amp;diff=128&amp;oldid=prev"/>
		<updated>2024-08-31T15:09:52Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;---&lt;br /&gt;
-- @iCCup&lt;br /&gt;
-- wiki=commons&lt;br /&gt;
-- page=Module:FeatureFlag&lt;br /&gt;
--&lt;br /&gt;
-- Please see https://github.com/iCCup/Lua-Modules to contribute&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
local FeatureFlagConfig = mw.loadData(&amp;#039;Module:FeatureFlag/Config&amp;#039;)&lt;br /&gt;
local Logic = require(&amp;#039;Module:Logic&amp;#039;)&lt;br /&gt;
local Table = require(&amp;#039;Module:Table&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Module for reading and setting feature flags. Feature flags are boolean values&lt;br /&gt;
that control whether certain code paths pertaining to new features are enabled.&lt;br /&gt;
To create a new feature flag, add an entry to Module:FeatureFlag/Config.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
Feature flags can be read and written to. If the value has not been set, then&lt;br /&gt;
the configured default value is used.&lt;br /&gt;
&lt;br /&gt;
FeatureFlag.get(&amp;#039;chiseled_face&amp;#039;)&lt;br /&gt;
FeatureFlag.set(&amp;#039;thick_mustache&amp;#039;, true)&lt;br /&gt;
&lt;br /&gt;
Feature flags can be applied temporarily inside a scope.&lt;br /&gt;
&lt;br /&gt;
FeatureFlag.with({rugged_grin = true}, function()&lt;br /&gt;
	-- ...&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
Feature flags are also available in wikicode, with the exception of the&lt;br /&gt;
configured default value which is only available in lua.&lt;br /&gt;
&lt;br /&gt;
{{#var:feature_chiseled_face}}&lt;br /&gt;
{{#vardefine:feature_thick_mustache|1}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
local FeatureFlag = {}&lt;br /&gt;
&lt;br /&gt;
local cachedFlags = {}&lt;br /&gt;
&lt;br /&gt;
---Retrieves the boolean value of a feature flag. If the flag has not been&lt;br /&gt;
---previously set, this returns the configured default value of the flag.&lt;br /&gt;
---@param flag string&lt;br /&gt;
---@return boolean&lt;br /&gt;
function FeatureFlag.get(flag)&lt;br /&gt;
	if cachedFlags[flag] == nil then&lt;br /&gt;
		cachedFlags[flag] = FeatureFlag._get(flag)&lt;br /&gt;
	end&lt;br /&gt;
	return cachedFlags[flag]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---@param flag string&lt;br /&gt;
---@return boolean&lt;br /&gt;
function FeatureFlag._get(flag)&lt;br /&gt;
	local config = FeatureFlag.getConfig(flag)&lt;br /&gt;
	return Logic.nilOr(&lt;br /&gt;
		Logic.readBoolOrNil(mw.ext.VariablesLua.var(&amp;#039;feature_&amp;#039; .. flag)),&lt;br /&gt;
		config.defaultValue,&lt;br /&gt;
		false&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Sets the value of a feature flag. If value is nil, then this resets the value to the configured default.&lt;br /&gt;
---@param flag string&lt;br /&gt;
---@param value boolean?&lt;br /&gt;
function FeatureFlag.set(flag, value)&lt;br /&gt;
	FeatureFlag.getConfig(flag)&lt;br /&gt;
	if value ~= nil then&lt;br /&gt;
		mw.ext.VariablesLua.vardefine(&amp;#039;feature_&amp;#039; .. flag, value and &amp;#039;1&amp;#039; or &amp;#039;0&amp;#039;)&lt;br /&gt;
	else&lt;br /&gt;
		mw.ext.VariablesLua.vardefine(&amp;#039;feature_&amp;#039; .. flag, &amp;#039;&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	cachedFlags[flag] = nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Runs a function inside a scope where the specified flags are set.&lt;br /&gt;
---@generic V&lt;br /&gt;
---@param flags? {[string]: boolean}&lt;br /&gt;
---@param f fun(): V&lt;br /&gt;
---@return V|Error&lt;br /&gt;
function FeatureFlag.with(flags, f)&lt;br /&gt;
	if Table.isEmpty(flags) then&lt;br /&gt;
		return f()&lt;br /&gt;
	end&lt;br /&gt;
	---@cast flags -nil&lt;br /&gt;
&lt;br /&gt;
	-- Remember previous flags&lt;br /&gt;
	local oldFlags = Table.map(flags, function(flag, value)&lt;br /&gt;
		return flag, mw.ext.VariablesLua.var(&amp;#039;feature_&amp;#039; .. flag)&lt;br /&gt;
	end)&lt;br /&gt;
&lt;br /&gt;
	-- Set new flags&lt;br /&gt;
	for flag, value in pairs(flags) do&lt;br /&gt;
		FeatureFlag.set(flag, value)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return Logic.try(f)&lt;br /&gt;
		:finally(function()&lt;br /&gt;
			-- Restore previous flags&lt;br /&gt;
			for flag, oldValue in pairs(oldFlags) do&lt;br /&gt;
				mw.ext.VariablesLua.vardefine(&amp;#039;feature_&amp;#039; .. flag, oldValue)&lt;br /&gt;
				cachedFlags[flag] = nil&lt;br /&gt;
			end&lt;br /&gt;
		end)&lt;br /&gt;
		:get()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---@param flag string&lt;br /&gt;
---@return {defaultValue: boolean}&lt;br /&gt;
function FeatureFlag.getConfig(flag)&lt;br /&gt;
	local config = FeatureFlagConfig[flag]&lt;br /&gt;
	if not config then&lt;br /&gt;
		error(&amp;#039;Unrecognized feature flag \&amp;#039;&amp;#039; .. flag .. &amp;#039;\&amp;#039;&amp;#039;, 2)&lt;br /&gt;
	end&lt;br /&gt;
	return config&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return FeatureFlag&lt;/div&gt;</summary>
		<author><name>DarkMuse</name></author>
	</entry>
</feed>