aconfig: rename namespace -> package
What used to be referred to as a namespace is now called a package. This CL is a semantic change only. Bug: 285000854 Test: m nothing Test: atest aconfig.test Change-Id: If3fca67c415af75b44f316e16666b97089407069
This commit is contained in:
@@ -40,12 +40,12 @@ message flag_declaration {
|
|||||||
};
|
};
|
||||||
|
|
||||||
message flag_declarations {
|
message flag_declarations {
|
||||||
required string namespace = 1;
|
required string package = 1;
|
||||||
repeated flag_declaration flag = 2;
|
repeated flag_declaration flag = 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
message flag_value {
|
message flag_value {
|
||||||
required string namespace = 1;
|
required string package = 1;
|
||||||
required string name = 2;
|
required string name = 2;
|
||||||
required flag_state state = 3;
|
required flag_state state = 3;
|
||||||
required flag_permission permission = 4;
|
required flag_permission permission = 4;
|
||||||
@@ -65,7 +65,7 @@ message tracepoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message parsed_flag {
|
message parsed_flag {
|
||||||
required string namespace = 1;
|
required string package = 1;
|
||||||
required string name = 2;
|
required string name = 2;
|
||||||
required string description = 3;
|
required string description = 3;
|
||||||
required flag_state state = 4;
|
required flag_state state = 4;
|
||||||
|
@@ -109,7 +109,7 @@ impl TryFrom<ProtoFlagDeclaration> for FlagDeclaration {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct FlagDeclarations {
|
pub struct FlagDeclarations {
|
||||||
pub namespace: String,
|
pub package: String,
|
||||||
pub flags: Vec<FlagDeclaration>,
|
pub flags: Vec<FlagDeclaration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,20 +117,20 @@ impl FlagDeclarations {
|
|||||||
pub fn try_from_text_proto(text_proto: &str) -> Result<FlagDeclarations> {
|
pub fn try_from_text_proto(text_proto: &str) -> Result<FlagDeclarations> {
|
||||||
let proto: ProtoFlagDeclarations = crate::protos::try_from_text_proto(text_proto)
|
let proto: ProtoFlagDeclarations = crate::protos::try_from_text_proto(text_proto)
|
||||||
.with_context(|| text_proto.to_owned())?;
|
.with_context(|| text_proto.to_owned())?;
|
||||||
let Some(namespace) = proto.namespace else {
|
let Some(package) = proto.package else {
|
||||||
bail!("missing 'namespace' field");
|
bail!("missing 'package' field");
|
||||||
};
|
};
|
||||||
let mut flags = vec![];
|
let mut flags = vec![];
|
||||||
for proto_flag in proto.flag.into_iter() {
|
for proto_flag in proto.flag.into_iter() {
|
||||||
flags.push(proto_flag.try_into()?);
|
flags.push(proto_flag.try_into()?);
|
||||||
}
|
}
|
||||||
Ok(FlagDeclarations { namespace, flags })
|
Ok(FlagDeclarations { package, flags })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct FlagValue {
|
pub struct FlagValue {
|
||||||
pub namespace: String,
|
pub package: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub state: FlagState,
|
pub state: FlagState,
|
||||||
pub permission: Permission,
|
pub permission: Permission,
|
||||||
@@ -153,8 +153,8 @@ impl TryFrom<ProtoFlagValue> for FlagValue {
|
|||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(proto: ProtoFlagValue) -> Result<Self, Self::Error> {
|
fn try_from(proto: ProtoFlagValue) -> Result<Self, Self::Error> {
|
||||||
let Some(namespace) = proto.namespace else {
|
let Some(package) = proto.package else {
|
||||||
bail!("missing 'namespace' field");
|
bail!("missing 'package' field");
|
||||||
};
|
};
|
||||||
let Some(name) = proto.name else {
|
let Some(name) = proto.name else {
|
||||||
bail!("missing 'name' field");
|
bail!("missing 'name' field");
|
||||||
@@ -167,7 +167,7 @@ impl TryFrom<ProtoFlagValue> for FlagValue {
|
|||||||
bail!("missing 'permission' field");
|
bail!("missing 'permission' field");
|
||||||
};
|
};
|
||||||
let permission = proto_permission.try_into()?;
|
let permission = proto_permission.try_into()?;
|
||||||
Ok(FlagValue { namespace, name, state, permission })
|
Ok(FlagValue { package, name, state, permission })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ impl From<Cache> for ProtoParsedFlags {
|
|||||||
impl From<Item> for ProtoParsedFlag {
|
impl From<Item> for ProtoParsedFlag {
|
||||||
fn from(item: Item) -> Self {
|
fn from(item: Item) -> Self {
|
||||||
let mut proto = crate::protos::ProtoParsedFlag::new();
|
let mut proto = crate::protos::ProtoParsedFlag::new();
|
||||||
proto.set_namespace(item.namespace.to_owned());
|
proto.set_package(item.package.to_owned());
|
||||||
proto.set_name(item.name.clone());
|
proto.set_name(item.name.clone());
|
||||||
proto.set_description(item.description.clone());
|
proto.set_description(item.description.clone());
|
||||||
proto.set_state(item.state.into());
|
proto.set_state(item.state.into());
|
||||||
@@ -242,9 +242,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_namespace_try_from_text_proto() {
|
fn test_package_try_from_text_proto() {
|
||||||
let expected = FlagDeclarations {
|
let expected = FlagDeclarations {
|
||||||
namespace: "ns".to_owned(),
|
package: "ns".to_owned(),
|
||||||
flags: vec![
|
flags: vec![
|
||||||
FlagDeclaration { name: "a".to_owned(), description: "A".to_owned() },
|
FlagDeclaration { name: "a".to_owned(), description: "A".to_owned() },
|
||||||
FlagDeclaration { name: "b".to_owned(), description: "B".to_owned() },
|
FlagDeclaration { name: "b".to_owned(), description: "B".to_owned() },
|
||||||
@@ -252,7 +252,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let s = r#"
|
let s = r#"
|
||||||
namespace: "ns"
|
package: "ns"
|
||||||
flag {
|
flag {
|
||||||
name: "a"
|
name: "a"
|
||||||
description: "A"
|
description: "A"
|
||||||
@@ -270,14 +270,14 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_flag_declaration_try_from_text_proto_list() {
|
fn test_flag_declaration_try_from_text_proto_list() {
|
||||||
let expected = FlagValue {
|
let expected = FlagValue {
|
||||||
namespace: "ns".to_owned(),
|
package: "ns".to_owned(),
|
||||||
name: "1234".to_owned(),
|
name: "1234".to_owned(),
|
||||||
state: FlagState::Enabled,
|
state: FlagState::Enabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
};
|
};
|
||||||
|
|
||||||
let s = r#"
|
let s = r#"
|
||||||
namespace: "ns"
|
package: "ns"
|
||||||
name: "1234"
|
name: "1234"
|
||||||
state: ENABLED
|
state: ENABLED
|
||||||
permission: READ_ONLY
|
permission: READ_ONLY
|
||||||
|
@@ -34,11 +34,11 @@ pub struct Tracepoint {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
// TODO: duplicating the Cache.namespace as Item.namespace makes the internal representation
|
// TODO: duplicating the Cache.package as Item.package makes the internal representation
|
||||||
// closer to the proto message `parsed_flag`; hopefully this will enable us to replace the Item
|
// closer to the proto message `parsed_flag`; hopefully this will enable us to replace the Item
|
||||||
// struct and use a newtype instead once aconfig has matured. Until then, namespace should
|
// struct and use a newtype instead once aconfig has matured. Until then, package should
|
||||||
// really be a Cow<String>.
|
// really be a Cow<String>.
|
||||||
pub namespace: String,
|
pub package: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub state: FlagState,
|
pub state: FlagState,
|
||||||
@@ -48,7 +48,7 @@ pub struct Item {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct Cache {
|
pub struct Cache {
|
||||||
namespace: String,
|
package: String,
|
||||||
items: Vec<Item>,
|
items: Vec<Item>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,9 +96,9 @@ impl Cache {
|
|||||||
self.items.into_iter()
|
self.items.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn namespace(&self) -> &str {
|
pub fn package(&self) -> &str {
|
||||||
debug_assert!(!self.namespace.is_empty());
|
debug_assert!(!self.package.is_empty());
|
||||||
&self.namespace
|
&self.package
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,9 +108,9 @@ pub struct CacheBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CacheBuilder {
|
impl CacheBuilder {
|
||||||
pub fn new(namespace: String) -> Result<CacheBuilder> {
|
pub fn new(package: String) -> Result<CacheBuilder> {
|
||||||
ensure!(codegen::is_valid_identifier(&namespace), "bad namespace");
|
ensure!(codegen::is_valid_identifier(&package), "bad package");
|
||||||
let cache = Cache { namespace, items: vec![] };
|
let cache = Cache { package, items: vec![] };
|
||||||
Ok(CacheBuilder { cache })
|
Ok(CacheBuilder { cache })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ impl CacheBuilder {
|
|||||||
source
|
source
|
||||||
);
|
);
|
||||||
self.cache.items.push(Item {
|
self.cache.items.push(Item {
|
||||||
namespace: self.cache.namespace.clone(),
|
package: self.cache.package.clone(),
|
||||||
name: declaration.name.clone(),
|
name: declaration.name.clone(),
|
||||||
description: declaration.description,
|
description: declaration.description,
|
||||||
state: DEFAULT_FLAG_STATE,
|
state: DEFAULT_FLAG_STATE,
|
||||||
@@ -147,18 +147,18 @@ impl CacheBuilder {
|
|||||||
source: Source,
|
source: Source,
|
||||||
value: FlagValue,
|
value: FlagValue,
|
||||||
) -> Result<&mut CacheBuilder> {
|
) -> Result<&mut CacheBuilder> {
|
||||||
ensure!(codegen::is_valid_identifier(&value.namespace), "bad flag namespace");
|
ensure!(codegen::is_valid_identifier(&value.package), "bad flag package");
|
||||||
ensure!(codegen::is_valid_identifier(&value.name), "bad flag name");
|
ensure!(codegen::is_valid_identifier(&value.name), "bad flag name");
|
||||||
ensure!(
|
ensure!(
|
||||||
value.namespace == self.cache.namespace,
|
value.package == self.cache.package,
|
||||||
"failed to set values for flag {}/{} from {}: expected namespace {}",
|
"failed to set values for flag {}/{} from {}: expected package {}",
|
||||||
value.namespace,
|
value.package,
|
||||||
value.name,
|
value.name,
|
||||||
source,
|
source,
|
||||||
self.cache.namespace
|
self.cache.package
|
||||||
);
|
);
|
||||||
let Some(existing_item) = self.cache.items.iter_mut().find(|item| item.name == value.name) else {
|
let Some(existing_item) = self.cache.items.iter_mut().find(|item| item.name == value.name) else {
|
||||||
bail!("failed to set values for flag {}/{} from {}: flag not declared", value.namespace, value.name, source);
|
bail!("failed to set values for flag {}/{} from {}: flag not declared", value.package, value.name, source);
|
||||||
};
|
};
|
||||||
existing_item.state = value.state;
|
existing_item.state = value.state;
|
||||||
existing_item.permission = value.permission;
|
existing_item.permission = value.permission;
|
||||||
@@ -222,7 +222,7 @@ mod tests {
|
|||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: "ns".to_string(),
|
package: "ns".to_string(),
|
||||||
name: "foo".to_string(),
|
name: "foo".to_string(),
|
||||||
state: FlagState::Enabled,
|
state: FlagState::Enabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
@@ -245,7 +245,7 @@ mod tests {
|
|||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: "ns".to_string(),
|
package: "ns".to_string(),
|
||||||
name: "foo".to_string(),
|
name: "foo".to_string(),
|
||||||
state: FlagState::Disabled,
|
state: FlagState::Disabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
@@ -257,7 +257,7 @@ mod tests {
|
|||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: "ns".to_string(),
|
package: "ns".to_string(),
|
||||||
name: "foo".to_string(),
|
name: "foo".to_string(),
|
||||||
state: FlagState::Enabled,
|
state: FlagState::Enabled,
|
||||||
permission: Permission::ReadWrite,
|
permission: Permission::ReadWrite,
|
||||||
@@ -265,19 +265,19 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// different namespace -> no-op
|
// different package -> no-op
|
||||||
let error = builder
|
let error = builder
|
||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: "some_other_namespace".to_string(),
|
package: "some_other_package".to_string(),
|
||||||
name: "foo".to_string(),
|
name: "foo".to_string(),
|
||||||
state: FlagState::Enabled,
|
state: FlagState::Enabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_eq!(&format!("{:?}", error), "failed to set values for flag some_other_namespace/foo from <memory>: expected namespace ns");
|
assert_eq!(&format!("{:?}", error), "failed to set values for flag some_other_package/foo from <memory>: expected package ns");
|
||||||
|
|
||||||
let cache = builder.build();
|
let cache = builder.build();
|
||||||
let item = cache.iter().find(|&item| item.name == "foo").unwrap();
|
let item = cache.iter().find(|&item| item.name == "foo").unwrap();
|
||||||
@@ -286,7 +286,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_reject_empty_cache_namespace() {
|
fn test_reject_empty_cache_package() {
|
||||||
CacheBuilder::new("".to_string()).unwrap_err();
|
CacheBuilder::new("".to_string()).unwrap_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,20 +325,20 @@ mod tests {
|
|||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: "".to_string(),
|
package: "".to_string(),
|
||||||
name: "foo".to_string(),
|
name: "foo".to_string(),
|
||||||
state: FlagState::Enabled,
|
state: FlagState::Enabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_eq!(&format!("{:?}", error), "bad flag namespace");
|
assert_eq!(&format!("{:?}", error), "bad flag package");
|
||||||
|
|
||||||
let error = builder
|
let error = builder
|
||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: "ns".to_string(),
|
package: "ns".to_string(),
|
||||||
name: "".to_string(),
|
name: "".to_string(),
|
||||||
state: FlagState::Enabled,
|
state: FlagState::Enabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
|
@@ -25,18 +25,18 @@ use crate::commands::OutputFile;
|
|||||||
pub fn generate_cpp_code(cache: &Cache) -> Result<OutputFile> {
|
pub fn generate_cpp_code(cache: &Cache) -> Result<OutputFile> {
|
||||||
let class_elements: Vec<ClassElement> = cache.iter().map(create_class_element).collect();
|
let class_elements: Vec<ClassElement> = cache.iter().map(create_class_element).collect();
|
||||||
let readwrite = class_elements.iter().any(|item| item.readwrite);
|
let readwrite = class_elements.iter().any(|item| item.readwrite);
|
||||||
let namespace = cache.namespace().to_lowercase();
|
let package = cache.package().to_lowercase();
|
||||||
let context = Context { namespace: namespace.clone(), readwrite, class_elements };
|
let context = Context { package: package.clone(), readwrite, class_elements };
|
||||||
let mut template = TinyTemplate::new();
|
let mut template = TinyTemplate::new();
|
||||||
template.add_template("cpp_code_gen", include_str!("../templates/cpp.template"))?;
|
template.add_template("cpp_code_gen", include_str!("../templates/cpp.template"))?;
|
||||||
let contents = template.render("cpp_code_gen", &context)?;
|
let contents = template.render("cpp_code_gen", &context)?;
|
||||||
let path = ["aconfig", &(namespace + ".h")].iter().collect();
|
let path = ["aconfig", &(package + ".h")].iter().collect();
|
||||||
Ok(OutputFile { contents: contents.into(), path })
|
Ok(OutputFile { contents: contents.into(), path })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct Context {
|
struct Context {
|
||||||
pub namespace: String,
|
pub package: String,
|
||||||
pub readwrite: bool,
|
pub readwrite: bool,
|
||||||
pub class_elements: Vec<ClassElement>,
|
pub class_elements: Vec<ClassElement>,
|
||||||
}
|
}
|
||||||
@@ -69,8 +69,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cpp_codegen_build_time_flag_only() {
|
fn test_cpp_codegen_build_time_flag_only() {
|
||||||
let namespace = "my_namespace";
|
let package = "my_package";
|
||||||
let mut builder = CacheBuilder::new(namespace.to_string()).unwrap();
|
let mut builder = CacheBuilder::new(package.to_string()).unwrap();
|
||||||
builder
|
builder
|
||||||
.add_flag_declaration(
|
.add_flag_declaration(
|
||||||
Source::File("aconfig_one.txt".to_string()),
|
Source::File("aconfig_one.txt".to_string()),
|
||||||
@@ -83,7 +83,7 @@ mod tests {
|
|||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: namespace.to_string(),
|
package: package.to_string(),
|
||||||
name: "my_flag_one".to_string(),
|
name: "my_flag_one".to_string(),
|
||||||
state: FlagState::Disabled,
|
state: FlagState::Disabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
@@ -101,7 +101,7 @@ mod tests {
|
|||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: namespace.to_string(),
|
package: package.to_string(),
|
||||||
name: "my_flag_two".to_string(),
|
name: "my_flag_two".to_string(),
|
||||||
state: FlagState::Enabled,
|
state: FlagState::Enabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
@@ -109,11 +109,11 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let cache = builder.build();
|
let cache = builder.build();
|
||||||
let expect_content = r#"#ifndef my_namespace_HEADER_H
|
let expect_content = r#"#ifndef my_package_HEADER_H
|
||||||
#define my_namespace_HEADER_H
|
#define my_package_HEADER_H
|
||||||
#include "my_namespace.h"
|
#include "my_package.h"
|
||||||
|
|
||||||
namespace my_namespace {
|
namespace my_package {
|
||||||
|
|
||||||
class my_flag_one {
|
class my_flag_one {
|
||||||
public:
|
public:
|
||||||
@@ -133,7 +133,7 @@ mod tests {
|
|||||||
#endif
|
#endif
|
||||||
"#;
|
"#;
|
||||||
let file = generate_cpp_code(&cache).unwrap();
|
let file = generate_cpp_code(&cache).unwrap();
|
||||||
assert_eq!("aconfig/my_namespace.h", file.path.to_str().unwrap());
|
assert_eq!("aconfig/my_package.h", file.path.to_str().unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expect_content.replace(' ', ""),
|
expect_content.replace(' ', ""),
|
||||||
String::from_utf8(file.contents).unwrap().replace(' ', "")
|
String::from_utf8(file.contents).unwrap().replace(' ', "")
|
||||||
@@ -142,8 +142,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cpp_codegen_runtime_flag() {
|
fn test_cpp_codegen_runtime_flag() {
|
||||||
let namespace = "my_namespace";
|
let package = "my_package";
|
||||||
let mut builder = CacheBuilder::new(namespace.to_string()).unwrap();
|
let mut builder = CacheBuilder::new(package.to_string()).unwrap();
|
||||||
builder
|
builder
|
||||||
.add_flag_declaration(
|
.add_flag_declaration(
|
||||||
Source::File("aconfig_one.txt".to_string()),
|
Source::File("aconfig_one.txt".to_string()),
|
||||||
@@ -164,7 +164,7 @@ mod tests {
|
|||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: namespace.to_string(),
|
package: package.to_string(),
|
||||||
name: "my_flag_two".to_string(),
|
name: "my_flag_two".to_string(),
|
||||||
state: FlagState::Enabled,
|
state: FlagState::Enabled,
|
||||||
permission: Permission::ReadWrite,
|
permission: Permission::ReadWrite,
|
||||||
@@ -172,20 +172,20 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let cache = builder.build();
|
let cache = builder.build();
|
||||||
let expect_content = r#"#ifndef my_namespace_HEADER_H
|
let expect_content = r#"#ifndef my_package_HEADER_H
|
||||||
#define my_namespace_HEADER_H
|
#define my_package_HEADER_H
|
||||||
#include "my_namespace.h"
|
#include "my_package.h"
|
||||||
|
|
||||||
#include <server_configurable_flags/get_flags.h>
|
#include <server_configurable_flags/get_flags.h>
|
||||||
using namespace server_configurable_flags;
|
using namespace server_configurable_flags;
|
||||||
|
|
||||||
namespace my_namespace {
|
namespace my_package {
|
||||||
|
|
||||||
class my_flag_one {
|
class my_flag_one {
|
||||||
public:
|
public:
|
||||||
virtual const bool value() {
|
virtual const bool value() {
|
||||||
return GetServerConfigurableFlag(
|
return GetServerConfigurableFlag(
|
||||||
"my_namespace",
|
"my_package",
|
||||||
"my_flag_one",
|
"my_flag_one",
|
||||||
"false") == "true";
|
"false") == "true";
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ mod tests {
|
|||||||
public:
|
public:
|
||||||
virtual const bool value() {
|
virtual const bool value() {
|
||||||
return GetServerConfigurableFlag(
|
return GetServerConfigurableFlag(
|
||||||
"my_namespace",
|
"my_package",
|
||||||
"my_flag_two",
|
"my_flag_two",
|
||||||
"true") == "true";
|
"true") == "true";
|
||||||
}
|
}
|
||||||
@@ -205,7 +205,7 @@ mod tests {
|
|||||||
#endif
|
#endif
|
||||||
"#;
|
"#;
|
||||||
let file = generate_cpp_code(&cache).unwrap();
|
let file = generate_cpp_code(&cache).unwrap();
|
||||||
assert_eq!("aconfig/my_namespace.h", file.path.to_str().unwrap());
|
assert_eq!("aconfig/my_package.h", file.path.to_str().unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expect_content.replace(' ', ""),
|
expect_content.replace(' ', ""),
|
||||||
String::from_utf8(file.contents).unwrap().replace(' ', "")
|
String::from_utf8(file.contents).unwrap().replace(' ', "")
|
||||||
|
@@ -26,12 +26,12 @@ use crate::commands::OutputFile;
|
|||||||
pub fn generate_java_code(cache: &Cache) -> Result<OutputFile> {
|
pub fn generate_java_code(cache: &Cache) -> Result<OutputFile> {
|
||||||
let class_elements: Vec<ClassElement> = cache.iter().map(create_class_element).collect();
|
let class_elements: Vec<ClassElement> = cache.iter().map(create_class_element).collect();
|
||||||
let readwrite = class_elements.iter().any(|item| item.readwrite);
|
let readwrite = class_elements.iter().any(|item| item.readwrite);
|
||||||
let namespace = cache.namespace();
|
let package = cache.package();
|
||||||
let context = Context { namespace: namespace.to_string(), readwrite, class_elements };
|
let context = Context { package: package.to_string(), readwrite, class_elements };
|
||||||
let mut template = TinyTemplate::new();
|
let mut template = TinyTemplate::new();
|
||||||
template.add_template("java_code_gen", include_str!("../templates/java.template"))?;
|
template.add_template("java_code_gen", include_str!("../templates/java.template"))?;
|
||||||
let contents = template.render("java_code_gen", &context)?;
|
let contents = template.render("java_code_gen", &context)?;
|
||||||
let mut path: PathBuf = ["aconfig", namespace].iter().collect();
|
let mut path: PathBuf = ["aconfig", package].iter().collect();
|
||||||
// TODO: Allow customization of the java class name
|
// TODO: Allow customization of the java class name
|
||||||
path.push("Flags.java");
|
path.push("Flags.java");
|
||||||
Ok(OutputFile { contents: contents.into(), path })
|
Ok(OutputFile { contents: contents.into(), path })
|
||||||
@@ -39,7 +39,7 @@ pub fn generate_java_code(cache: &Cache) -> Result<OutputFile> {
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct Context {
|
struct Context {
|
||||||
pub namespace: String,
|
pub package: String,
|
||||||
pub readwrite: bool,
|
pub readwrite: bool,
|
||||||
pub class_elements: Vec<ClassElement>,
|
pub class_elements: Vec<ClassElement>,
|
||||||
}
|
}
|
||||||
@@ -76,8 +76,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_generate_java_code() {
|
fn test_generate_java_code() {
|
||||||
let namespace = "example";
|
let package = "example";
|
||||||
let mut builder = CacheBuilder::new(namespace.to_string()).unwrap();
|
let mut builder = CacheBuilder::new(package.to_string()).unwrap();
|
||||||
builder
|
builder
|
||||||
.add_flag_declaration(
|
.add_flag_declaration(
|
||||||
Source::File("test.txt".to_string()),
|
Source::File("test.txt".to_string()),
|
||||||
@@ -98,7 +98,7 @@ mod tests {
|
|||||||
.add_flag_value(
|
.add_flag_value(
|
||||||
Source::Memory,
|
Source::Memory,
|
||||||
FlagValue {
|
FlagValue {
|
||||||
namespace: namespace.to_string(),
|
package: package.to_string(),
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
state: FlagState::Disabled,
|
state: FlagState::Disabled,
|
||||||
permission: Permission::ReadOnly,
|
permission: Permission::ReadOnly,
|
||||||
|
@@ -23,10 +23,10 @@ use crate::cache::{Cache, Item};
|
|||||||
use crate::commands::OutputFile;
|
use crate::commands::OutputFile;
|
||||||
|
|
||||||
pub fn generate_rust_code(cache: &Cache) -> Result<OutputFile> {
|
pub fn generate_rust_code(cache: &Cache) -> Result<OutputFile> {
|
||||||
let namespace = cache.namespace();
|
let package = cache.package();
|
||||||
let parsed_flags: Vec<TemplateParsedFlag> =
|
let parsed_flags: Vec<TemplateParsedFlag> =
|
||||||
cache.iter().map(|item| create_template_parsed_flag(namespace, item)).collect();
|
cache.iter().map(|item| create_template_parsed_flag(package, item)).collect();
|
||||||
let context = TemplateContext { namespace: namespace.to_string(), parsed_flags };
|
let context = TemplateContext { package: package.to_string(), parsed_flags };
|
||||||
let mut template = TinyTemplate::new();
|
let mut template = TinyTemplate::new();
|
||||||
template.add_template("rust_code_gen", include_str!("../templates/rust.template"))?;
|
template.add_template("rust_code_gen", include_str!("../templates/rust.template"))?;
|
||||||
let contents = template.render("rust_code_gen", &context)?;
|
let contents = template.render("rust_code_gen", &context)?;
|
||||||
@@ -36,7 +36,7 @@ pub fn generate_rust_code(cache: &Cache) -> Result<OutputFile> {
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct TemplateContext {
|
struct TemplateContext {
|
||||||
pub namespace: String,
|
pub package: String,
|
||||||
pub parsed_flags: Vec<TemplateParsedFlag>,
|
pub parsed_flags: Vec<TemplateParsedFlag>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,10 +53,10 @@ struct TemplateParsedFlag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::nonminimal_bool)]
|
#[allow(clippy::nonminimal_bool)]
|
||||||
fn create_template_parsed_flag(namespace: &str, item: &Item) -> TemplateParsedFlag {
|
fn create_template_parsed_flag(package: &str, item: &Item) -> TemplateParsedFlag {
|
||||||
let template = TemplateParsedFlag {
|
let template = TemplateParsedFlag {
|
||||||
name: item.name.clone(),
|
name: item.name.clone(),
|
||||||
fn_name: format!("{}_{}", namespace, &item.name),
|
fn_name: format!("{}_{}", package, &item.name),
|
||||||
is_read_only_enabled: item.permission == Permission::ReadOnly
|
is_read_only_enabled: item.permission == Permission::ReadOnly
|
||||||
&& item.state == FlagState::Enabled,
|
&& item.state == FlagState::Enabled,
|
||||||
is_read_only_disabled: item.permission == Permission::ReadOnly
|
is_read_only_disabled: item.permission == Permission::ReadOnly
|
||||||
|
@@ -55,12 +55,8 @@ pub struct OutputFile {
|
|||||||
pub contents: Vec<u8>,
|
pub contents: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_cache(
|
pub fn create_cache(package: &str, declarations: Vec<Input>, values: Vec<Input>) -> Result<Cache> {
|
||||||
namespace: &str,
|
let mut builder = CacheBuilder::new(package.to_owned())?;
|
||||||
declarations: Vec<Input>,
|
|
||||||
values: Vec<Input>,
|
|
||||||
) -> Result<Cache> {
|
|
||||||
let mut builder = CacheBuilder::new(namespace.to_owned())?;
|
|
||||||
|
|
||||||
for mut input in declarations {
|
for mut input in declarations {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
@@ -68,11 +64,11 @@ pub fn create_cache(
|
|||||||
let dec_list = FlagDeclarations::try_from_text_proto(&contents)
|
let dec_list = FlagDeclarations::try_from_text_proto(&contents)
|
||||||
.with_context(|| format!("Failed to parse {}", input.source))?;
|
.with_context(|| format!("Failed to parse {}", input.source))?;
|
||||||
ensure!(
|
ensure!(
|
||||||
namespace == dec_list.namespace,
|
package == dec_list.package,
|
||||||
"Failed to parse {}: expected namespace {}, got {}",
|
"Failed to parse {}: expected package {}, got {}",
|
||||||
input.source,
|
input.source,
|
||||||
namespace,
|
package,
|
||||||
dec_list.namespace
|
dec_list.package
|
||||||
);
|
);
|
||||||
for d in dec_list.flags.into_iter() {
|
for d in dec_list.flags.into_iter() {
|
||||||
builder.add_flag_declaration(input.source.clone(), d)?;
|
builder.add_flag_declaration(input.source.clone(), d)?;
|
||||||
@@ -111,7 +107,7 @@ pub fn create_device_config_defaults(caches: Vec<Cache>) -> Result<Vec<u8>> {
|
|||||||
{
|
{
|
||||||
let line = format!(
|
let line = format!(
|
||||||
"{}/{}:{}\n",
|
"{}/{}:{}\n",
|
||||||
item.namespace,
|
item.package,
|
||||||
item.name,
|
item.name,
|
||||||
match item.state {
|
match item.state {
|
||||||
FlagState::Enabled => "enabled",
|
FlagState::Enabled => "enabled",
|
||||||
@@ -129,7 +125,7 @@ pub fn create_device_config_sysprops(caches: Vec<Cache>) -> Result<Vec<u8>> {
|
|||||||
{
|
{
|
||||||
let line = format!(
|
let line = format!(
|
||||||
"persist.device_config.{}.{}={}\n",
|
"persist.device_config.{}.{}={}\n",
|
||||||
item.namespace,
|
item.package,
|
||||||
item.name,
|
item.name,
|
||||||
match item.state {
|
match item.state {
|
||||||
FlagState::Enabled => "true",
|
FlagState::Enabled => "true",
|
||||||
@@ -155,7 +151,7 @@ pub fn dump_cache(caches: Vec<Cache>, format: DumpFormat) -> Result<Vec<u8>> {
|
|||||||
for item in sort_and_iter_items(caches) {
|
for item in sort_and_iter_items(caches) {
|
||||||
let line = format!(
|
let line = format!(
|
||||||
"{}/{}: {:?} {:?}\n",
|
"{}/{}: {:?} {:?}\n",
|
||||||
item.namespace, item.name, item.state, item.permission
|
item.package, item.name, item.state, item.permission
|
||||||
);
|
);
|
||||||
output.extend_from_slice(line.as_bytes());
|
output.extend_from_slice(line.as_bytes());
|
||||||
}
|
}
|
||||||
@@ -181,7 +177,7 @@ fn sort_and_iter_items(caches: Vec<Cache>) -> impl Iterator<Item = Item> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn sort_and_iter_caches(mut caches: Vec<Cache>) -> impl Iterator<Item = Cache> {
|
fn sort_and_iter_caches(mut caches: Vec<Cache>) -> impl Iterator<Item = Cache> {
|
||||||
caches.sort_by_cached_key(|cache| cache.namespace().to_string());
|
caches.sort_by_cached_key(|cache| cache.package().to_string());
|
||||||
caches.into_iter()
|
caches.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +188,7 @@ mod tests {
|
|||||||
|
|
||||||
fn create_test_cache_ns1() -> Cache {
|
fn create_test_cache_ns1() -> Cache {
|
||||||
let s = r#"
|
let s = r#"
|
||||||
namespace: "ns1"
|
package: "ns1"
|
||||||
flag {
|
flag {
|
||||||
name: "a"
|
name: "a"
|
||||||
description: "Description of a"
|
description: "Description of a"
|
||||||
@@ -205,7 +201,7 @@ mod tests {
|
|||||||
let declarations = vec![Input { source: Source::Memory, reader: Box::new(s.as_bytes()) }];
|
let declarations = vec![Input { source: Source::Memory, reader: Box::new(s.as_bytes()) }];
|
||||||
let o = r#"
|
let o = r#"
|
||||||
flag_value {
|
flag_value {
|
||||||
namespace: "ns1"
|
package: "ns1"
|
||||||
name: "a"
|
name: "a"
|
||||||
state: DISABLED
|
state: DISABLED
|
||||||
permission: READ_ONLY
|
permission: READ_ONLY
|
||||||
@@ -217,7 +213,7 @@ mod tests {
|
|||||||
|
|
||||||
fn create_test_cache_ns2() -> Cache {
|
fn create_test_cache_ns2() -> Cache {
|
||||||
let s = r#"
|
let s = r#"
|
||||||
namespace: "ns2"
|
package: "ns2"
|
||||||
flag {
|
flag {
|
||||||
name: "c"
|
name: "c"
|
||||||
description: "Description of c"
|
description: "Description of c"
|
||||||
@@ -226,7 +222,7 @@ mod tests {
|
|||||||
let declarations = vec![Input { source: Source::Memory, reader: Box::new(s.as_bytes()) }];
|
let declarations = vec![Input { source: Source::Memory, reader: Box::new(s.as_bytes()) }];
|
||||||
let o = r#"
|
let o = r#"
|
||||||
flag_value {
|
flag_value {
|
||||||
namespace: "ns2"
|
package: "ns2"
|
||||||
name: "c"
|
name: "c"
|
||||||
state: DISABLED
|
state: DISABLED
|
||||||
permission: READ_ONLY
|
permission: READ_ONLY
|
||||||
@@ -284,7 +280,7 @@ mod tests {
|
|||||||
|
|
||||||
let item =
|
let item =
|
||||||
actual.parsed_flag.iter().find(|item| item.name == Some("b".to_string())).unwrap();
|
actual.parsed_flag.iter().find(|item| item.name == Some("b".to_string())).unwrap();
|
||||||
assert_eq!(item.namespace(), "ns1");
|
assert_eq!(item.package(), "ns1");
|
||||||
assert_eq!(item.name(), "b");
|
assert_eq!(item.name(), "b");
|
||||||
assert_eq!(item.description(), "Description of b");
|
assert_eq!(item.description(), "Description of b");
|
||||||
assert_eq!(item.state(), ProtoFlagState::DISABLED);
|
assert_eq!(item.state(), ProtoFlagState::DISABLED);
|
||||||
@@ -304,7 +300,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
dump.parsed_flag
|
dump.parsed_flag
|
||||||
.iter()
|
.iter()
|
||||||
.map(|parsed_flag| format!("{}/{}", parsed_flag.namespace(), parsed_flag.name()))
|
.map(|parsed_flag| format!("{}/{}", parsed_flag.package(), parsed_flag.name()))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
vec!["ns1/a".to_string(), "ns1/b".to_string(), "ns2/c".to_string()]
|
vec!["ns1/a".to_string(), "ns1/b".to_string(), "ns2/c".to_string()]
|
||||||
);
|
);
|
||||||
|
@@ -44,7 +44,7 @@ fn cli() -> Command {
|
|||||||
.subcommand_required(true)
|
.subcommand_required(true)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("create-cache")
|
Command::new("create-cache")
|
||||||
.arg(Arg::new("namespace").long("namespace").required(true))
|
.arg(Arg::new("package").long("package").required(true))
|
||||||
.arg(Arg::new("declarations").long("declarations").action(ArgAction::Append))
|
.arg(Arg::new("declarations").long("declarations").action(ArgAction::Append))
|
||||||
.arg(Arg::new("values").long("values").action(ArgAction::Append))
|
.arg(Arg::new("values").long("values").action(ArgAction::Append))
|
||||||
.arg(Arg::new("cache").long("cache").required(true)),
|
.arg(Arg::new("cache").long("cache").required(true)),
|
||||||
@@ -134,10 +134,10 @@ fn main() -> Result<()> {
|
|||||||
let matches = cli().get_matches();
|
let matches = cli().get_matches();
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
Some(("create-cache", sub_matches)) => {
|
Some(("create-cache", sub_matches)) => {
|
||||||
let namespace = get_required_arg::<String>(sub_matches, "namespace")?;
|
let package = get_required_arg::<String>(sub_matches, "package")?;
|
||||||
let declarations = open_zero_or_more_files(sub_matches, "declarations")?;
|
let declarations = open_zero_or_more_files(sub_matches, "declarations")?;
|
||||||
let values = open_zero_or_more_files(sub_matches, "values")?;
|
let values = open_zero_or_more_files(sub_matches, "values")?;
|
||||||
let cache = commands::create_cache(namespace, declarations, values)?;
|
let cache = commands::create_cache(package, declarations, values)?;
|
||||||
let path = get_required_arg::<String>(sub_matches, "cache")?;
|
let path = get_required_arg::<String>(sub_matches, "cache")?;
|
||||||
let file = fs::File::create(path)?;
|
let file = fs::File::create(path)?;
|
||||||
cache.write_to_writer(file)?;
|
cache.write_to_writer(file)?;
|
||||||
|
@@ -1,18 +1,18 @@
|
|||||||
#ifndef {namespace}_HEADER_H
|
#ifndef {package}_HEADER_H
|
||||||
#define {namespace}_HEADER_H
|
#define {package}_HEADER_H
|
||||||
#include "{namespace}.h"
|
#include "{package}.h"
|
||||||
{{ if readwrite }}
|
{{ if readwrite }}
|
||||||
#include <server_configurable_flags/get_flags.h>
|
#include <server_configurable_flags/get_flags.h>
|
||||||
using namespace server_configurable_flags;
|
using namespace server_configurable_flags;
|
||||||
{{ endif }}
|
{{ endif }}
|
||||||
namespace {namespace} \{
|
namespace {package} \{
|
||||||
{{ for item in class_elements}}
|
{{ for item in class_elements}}
|
||||||
class {item.flag_name} \{
|
class {item.flag_name} \{
|
||||||
public:
|
public:
|
||||||
virtual const bool value() \{
|
virtual const bool value() \{
|
||||||
{{ if item.readwrite- }}
|
{{ if item.readwrite- }}
|
||||||
return GetServerConfigurableFlag(
|
return GetServerConfigurableFlag(
|
||||||
"{namespace}",
|
"{package}",
|
||||||
"{item.flag_name}",
|
"{item.flag_name}",
|
||||||
"{item.default_value}") == "true";
|
"{item.default_value}") == "true";
|
||||||
{{ -else- }}
|
{{ -else- }}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package aconfig.{namespace};
|
package aconfig.{package};
|
||||||
{{ if readwrite }}
|
{{ if readwrite }}
|
||||||
import android.provider.DeviceConfig;
|
import android.provider.DeviceConfig;
|
||||||
{{ endif }}
|
{{ endif }}
|
||||||
@@ -7,7 +7,7 @@ public final class Flags \{
|
|||||||
public static boolean {item.method_name}() \{
|
public static boolean {item.method_name}() \{
|
||||||
{{ if item.readwrite- }}
|
{{ if item.readwrite- }}
|
||||||
return DeviceConfig.getBoolean(
|
return DeviceConfig.getBoolean(
|
||||||
"{namespace}",
|
"{package}",
|
||||||
"{item.feature_name}__{item.flag_name}",
|
"{item.feature_name}__{item.flag_name}",
|
||||||
{item.default_value}
|
{item.default_value}
|
||||||
);
|
);
|
||||||
|
@@ -16,7 +16,7 @@ pub const fn r#{parsed_flag.fn_name}() -> bool \{
|
|||||||
{{- if parsed_flag.is_read_write -}}
|
{{- if parsed_flag.is_read_write -}}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn r#{parsed_flag.fn_name}() -> bool \{
|
pub fn r#{parsed_flag.fn_name}() -> bool \{
|
||||||
flags_rust::GetServerConfigurableFlag("{namespace}", "{parsed_flag.name}", "false") == "true"
|
flags_rust::GetServerConfigurableFlag("{package}", "{parsed_flag.name}", "false") == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
{{ endif -}}
|
{{ endif -}}
|
||||||
|
6
tools/aconfig/testdata/first.values
vendored
6
tools/aconfig/testdata/first.values
vendored
@@ -1,17 +1,17 @@
|
|||||||
flag_value {
|
flag_value {
|
||||||
namespace: "test"
|
package: "test"
|
||||||
name: "disabled_ro"
|
name: "disabled_ro"
|
||||||
state: DISABLED
|
state: DISABLED
|
||||||
permission: READ_ONLY
|
permission: READ_ONLY
|
||||||
}
|
}
|
||||||
flag_value {
|
flag_value {
|
||||||
namespace: "test"
|
package: "test"
|
||||||
name: "enabled_ro"
|
name: "enabled_ro"
|
||||||
state: DISABLED
|
state: DISABLED
|
||||||
permission: READ_WRITE
|
permission: READ_WRITE
|
||||||
}
|
}
|
||||||
flag_value {
|
flag_value {
|
||||||
namespace: "test"
|
package: "test"
|
||||||
name: "enabled_rw"
|
name: "enabled_rw"
|
||||||
state: ENABLED
|
state: ENABLED
|
||||||
permission: READ_WRITE
|
permission: READ_WRITE
|
||||||
|
2
tools/aconfig/testdata/second.values
vendored
2
tools/aconfig/testdata/second.values
vendored
@@ -1,5 +1,5 @@
|
|||||||
flag_value {
|
flag_value {
|
||||||
namespace: "test"
|
package: "test"
|
||||||
name: "enabled_ro"
|
name: "enabled_ro"
|
||||||
state: ENABLED
|
state: ENABLED
|
||||||
permission: READ_ONLY
|
permission: READ_ONLY
|
||||||
|
2
tools/aconfig/testdata/test.aconfig
vendored
2
tools/aconfig/testdata/test.aconfig
vendored
@@ -1,4 +1,4 @@
|
|||||||
namespace: "test"
|
package: "test"
|
||||||
|
|
||||||
# This flag's final value is calculated from:
|
# This flag's final value is calculated from:
|
||||||
# - test.aconfig: DISABLED + READ_WRITE (default)
|
# - test.aconfig: DISABLED + READ_WRITE (default)
|
||||||
|
Reference in New Issue
Block a user