Skip to content

Internationalize dsc_lib #631

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions dsc/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dsc/examples/brew_uninstall.dsc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ resources:
- name: os_check
type: Microsoft/OSInfo
properties:
family: MacOS
family: macOS
- name: brew
type: DSC.PackageManagement/Brew
properties:
Expand Down
8 changes: 4 additions & 4 deletions dsc/locales/en-us.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ foundProcesses = "Found processes"
failedToGetPid = "Could not get current process id"
currentPid = "Current process id"
failedToGetProcess = "Could not get current process"
terminatingSubprocess ="Terminating subprocesses of process"
terminatingSubprocess = "Terminating subprocesses of process"
terminatingProcess = "Terminating process"
failedTerminatingProcess = "Failed to terminate process"
storeMessage = """DSC.exe is a command-line tool and cannot be run directly from the Windows Store or Explorer.
Expand All @@ -58,11 +58,11 @@ failedToOpenFile = "Failed to open included file"
invalidFileContent = "Invalid UTF-8 sequence in included file"
invalidFile = "Failed to read the configuration file as YAML or JSON"
resolvingParameters = "Resolving parameters from file"
failedParseParametersFile = "Failed to parse parameters file to JSON"
failedResolveParametersFile = "Failed to resolve parameters file"
noParametersFile = "No parameters file found"
failedParseParametersFile = "Failed to parse parameters file or conetnt to JSON"
couldNotReadParametersFile = "Could not read parameters file"
invalidPath = "Include path must not contain '..'"
failedGetCurrentDirectory = "Failed to get current directory"
noParameters = "No parameters specified"

[resource_command]
implementedAs = "implemented as"
Expand Down
6 changes: 3 additions & 3 deletions dsc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn main() {
debug!("{}: {}", t!("main.usingDscVersion"), env!("CARGO_PKG_VERSION"));

let progress_format = args.progress_format.unwrap_or( ProgressFormat::Default );

match args.subcommand {
SubCommand::Completer { shell } => {
info!("{} {:?}", t!("main.generatingCompleter"), shell);
Expand All @@ -55,7 +55,7 @@ fn main() {
match std::fs::read_to_string(&file_name) {
Ok(parameters) => subcommand::config(&subcommand, &Some(parameters), system_root.as_ref(), &as_group, &as_include, progress_format),
Err(err) => {
error!("{} '{file_name}': {err}", t!("main.failedToReadParametersFile"));
error!("{} '{file_name}': {err}", t!("main.failedReadingParametersFile"));
exit(util::EXIT_INVALID_INPUT);
}
}
Expand Down Expand Up @@ -111,7 +111,7 @@ fn terminate_subprocesses(sys: &System, process: &Process) {

info!("{}: {:?} {}", t!("main.terminatingProcess"), process.name(), process.pid());
if !process.kill() {
error!("{}: {:?} {}", t!("main.failedTerminateProcess"), process.name(), process.pid());
error!("{}: {:?} {}", t!("main.failedTerminatingProcess"), process.name(), process.pid());
}
}

Expand Down
4 changes: 2 additions & 2 deletions dsc/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,15 @@ pub fn get_contents(input: &str) -> Result<(Option<String>, String), String> {
Some(parameters_json)
},
Err(err) => {
return Err(format!("{} '{parameters_file:?}': {err}", t!("resolve.failedResolveParametersFile")));
return Err(format!("{} '{parameters_file:?}': {err}", t!("resolve.couldNotReadParametersFile")));
}
}
},
Some(IncludeParametersKind::ParametersContent(text)) => {
let parameters_json = match parse_input_to_json(&text) {
Ok(json) => json,
Err(err) => {
return Err(format!("{}: {err}", t!("resolve.invalidParametersContent")));
return Err(format!("{}: {err}", t!("resolve.failedParseParametersFile")));
}
};
Some(parameters_json)
Expand Down
2 changes: 1 addition & 1 deletion dsc/tests/dsc.exit_code.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Describe 'exit code tests' {
}
It 'non-zero exit code not in manifest has generic message' {
dsc resource get -r Test/ExitCode --input "{ exitCode: 1 }" 2> $TestDrive/tracing.txt
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Exit code 1'
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'exit code 1'
}
It 'success exit code executes without error' {
$result = dsc resource get -r Test/ExitCode --input "{ exitCode: 0 }" | ConvertFrom-Json
Expand Down
56 changes: 56 additions & 0 deletions dsc/tests/dsc_i18n.tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

BeforeDiscovery {
$tomls = Get-ChildItem $PSScriptRoot/../../en-us.toml -Recurse -File
$projects = @()
$tomls | ForEach-Object {
$projectName = (Split-Path $_ -Parent | Split-Path -Parent)
$projects += @{ project = $projectName; toml = $_ }
}
}

Describe 'Internationalization tests' {
It 'Project <project> uses i18n strings from <toml>' -TestCases $projects {
param($project, $toml)

$i18n = [System.Collections.Hashtable]::new([System.StringComparer]::Ordinal)
$prefix = ''
Get-Content -Path $toml | ForEach-Object {
if ($_ -match '\[(?<prefix>.*?)\]') {
$prefix = $Matches['prefix']
}
elseif ($_ -match '^(?<key>\w+)\s?=\s?"(?<value>.*?)"') {
$key = $prefix + '.' + $Matches['key']
$i18n[$key] = 0
}
}

$missing = @()
Get-ChildItem -Recurse -Path $project -Include *.rs -File | ForEach-Object {
# Write-Verbose -Verbose "File: $_"
$line = 0
Get-Content -Path $_ | ForEach-Object {
$line++
($_ | Select-String -Pattern '[^\w]t\!\("(?<key>.*?)".*?\)' -AllMatches).Matches | ForEach-Object {
# write-verbose -verbose "Line: $_"
if ($null -ne $_) {
$key = $_.Groups['key'].Value
if ($i18n.ContainsKey($key)) {
$i18n[$key] = 1
# write-verbose -verbose "Found on line $line : $key"
}
else {
$missing += $key
# write-verbose -verbose "Missing: $key"
}
}
}
}
}

$missing | Should -BeNullOrEmpty -Because "The following i18n keys are missing from $toml :`n$($missing | Out-String)"
$unused = $i18n.GetEnumerator() | Where-Object { $_.Value -eq 0 } | ForEach-Object { $_.Key }
$unused | Should -BeNullOrEmpty -Because "The following i18n keys are unused in the project:`n$($unused | Out-String)"
}
}
2 changes: 1 addition & 1 deletion dsc/tests/dsc_resource_list.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,6 @@ Describe 'Tests for listing resources' {
It 'Invalid adapter returns an error' {
$out = dsc resource list --adapter 'foo*' 2>&1 | Out-String
$LASTEXITCODE | Should -Be 0
$out | Should -BeLike "*ERROR*Adapter 'foo`*' not found*"
$out | Should -BeLike "*ERROR*Adapter not found: foo`*"
}
}
16 changes: 8 additions & 8 deletions dsc/tests/dsc_settings.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Describe 'tests for dsc settings' {
}

It 'ensure a new tracing value in settings has effect' {

$script:dscDefaultv1Settings."tracing"."level" = "TRACE"
$script:dscDefaultv1Settings | ConvertTo-Json -Depth 90 | Set-Content -Force -Path $script:dscSettingsFilePath

Expand All @@ -57,11 +57,11 @@ Describe 'tests for dsc settings' {
}

It 'ensure a new resource_path value in settings has effect' {

$script:dscDefaultv1Settings."resourcePath"."directories" = @("TestDir1","TestDir2")
$script:dscDefaultv1Settings | ConvertTo-Json -Depth 90 | Set-Content -Force -Path $script:dscSettingsFilePath
dsc -l debug resource list 2> $TestDrive/tracing.txt
$expectedString = 'Using Resource Path: "TestDir1'+[System.IO.Path]::PathSeparator+'TestDir2'
$expectedString = 'Using Resource Path: TestDir1'+[System.IO.Path]::PathSeparator+'TestDir2'
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly $expectedString
}

Expand All @@ -71,7 +71,7 @@ Describe 'tests for dsc settings' {
Set-ItResult -Skip -Because "Setting policy requires sudo"
return
}

$script:dscDefaultv1Settings."tracing"."level" = "TRACE"
$script:dscDefaultv1Settings."resourcePath"."directories" = @("PolicyDir")
$script:dscDefaultv1Settings | ConvertTo-Json -Depth 90 | Set-Content -Force -Path $script:policyFilePath
Expand All @@ -87,23 +87,23 @@ Describe 'tests for dsc settings' {
# ensure policy overrides everything
dsc -l debug resource list 2> $TestDrive/tracing.txt
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly "Trace-level is Trace"
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Using Resource Path: "PolicyDir'
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Using Resource Path: PolicyDir'

# without policy, command-line args have priority
Remove-Item -Path $script:policyFilePath
dsc -l debug resource list 2> $TestDrive/tracing.txt
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly "Trace-level is Debug"
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Using Resource Path: "SettingsDir'
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Using Resource Path: SettingsDir'

# without policy and command-line args, settings file is used
dsc resource list 2> $TestDrive/tracing.txt
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly "Trace-level is Trace"
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Using Resource Path: "SettingsDir'
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Using Resource Path: SettingsDir'

# without policy and command-line args and settings file, the default settings file is used
Remove-Item -Path $script:dscSettingsFilePath
dsc resource list 2> $TestDrive/tracing.txt
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly "Trace-level is Trace"
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Using Resource Path: "Defaultv1SettingsDir'
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Using Resource Path: Defaultv1SettingsDir'
}
}
Loading