Skip to content

Instantly share code, notes, and snippets.

@callumbwhyte
Last active January 19, 2019 16:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save callumbwhyte/583d56705e8ed10dd9413970b83e6b47 to your computer and use it in GitHub Desktop.
Save callumbwhyte/583d56705e8ed10dd9413970b83e6b47 to your computer and use it in GitHub Desktop.
Powershell script to detect unused Umbraco language file dictionary keys
Function Get-KeyInSource($sourcePath, $key)
{
# Separate key alias from area
$keyParts = $key.Split("/")
$areaAlias = $keyParts[0]
$keyAlias = $keyParts[1]
# Add conditions to an array
$conditions = @($key)
# Front-end key paths are _ separated
$conditions += "$areaAlias`_$keyAlias"
# Localization sevice in C#
$conditions += "Localize(""$areaAlias"", ""$keyAlias"")"
# Angular and C# localization sevices accept aliases without an area
$conditions += "localize(""$keyAlias"")"
# Front-end assumes if no area is given it must be "general"
# If key is in general area
# Add condition for key without path
If ($areaAlias -eq "general")
{
# Keys in HTML properties
$conditions += """@$keyAlias"""
# Angular <localize> directive
$conditions += "localize key=""$keyAlias"""
}
# Recurse all files in $sourcePath
# Find matches for conditions
Get-ChildItem -Path $sourcePath -Recurse | Select-String -Pattern "($($conditions -Join "|"))" -AllMatches
}
Function Get-LanguageFile($filePath)
{
$xmlObject = New-Object XML
Try
{
# Load file from path as XML object
$xmlObject.Load($filePath)
}
Catch
{
throw "Could not load language file"
}
# Validate parsed language object
# Check there is a culture set
$culture = $xmlObject.language.culture
If (!$culture)
{
throw "Failed to get language file culture"
}
New-Object psobject $xmlObject.language
}
Function Get-LanguageFileKeys($languageFile)
{
Foreach ($currentArea in $languageFile.area)
{
# Get the alias for the current area
$currentAreaAlias = $currentArea.alias
# Get aliases for all keys in the current area
$keyAliases = $currentArea.key.alias
Foreach ($keyAlias in $keyAliases)
{
# Build path to key
$keyPath = "$($currentAreaAlias)/$($keyAlias)"
New-Object psobject $keyPath
}
}
}
# Include language file functions
. ".\Get-LanguageFile.ps1"
. ".\Get-LanguageFileKeys.ps1"
# Include key helper functions
. ".\Get-KeyInSource.ps1"
# Initialize arrays
$allKeys = @()
$unusedKeys = @()
# Paths to scan
$sourcePath = ".\src"
$langsPath = "$sourcePath\Umbraco.Web.UI\Umbraco\config\lang"
Write-Host "Starting scan of $sourcePath" -ForegroundColor Green
# Get paths for all language XML files
$languageFilePaths = Get-ChildItem -Path $langsPath -Include *.xml -Recurse | % { $_.FullName }
Write-Host "Loaded $($languageFilePaths.count) language files" -ForegroundColor Yellow
Foreach ($languageFilePath in $languageFilePaths)
{
# Get language XML object from file
$languageFile = Get-LanguageFile $languageFilePath
# Get keys from language file
$keys = Get-LanguageFileKeys $languageFile
$allKeys += $keys
}
# Eliminate duplicate keys from all files
$uniqueKeys = $allKeys | Sort -Unique
Write-Host "Loaded $($uniqueKeys.count) keys" -ForegroundColor Yellow
Write-Host "Finding keys in source" -ForegroundColor Yellow
Foreach ($key in $uniqueKeys)
{
# Find instances of key in path files
# Count number of matched files
$count = Get-KeyInSource $sourcePath $key | Measure-Object | Select-Object -Exp Count
Write-Host "$key found $count matches"
# If no match was found, add to list
If ($count -eq 0)
{
$unusedKeys += $key
}
}
If ($unusedKeys.count -gt 0)
{
Write-Host "Found $($unusedKeys.count) unused keys" -ForegroundColor Red
# Save list to file
$unusedKeys | Out-File output.txt
}
Else
{
Write-Host "All good! No unused keys found" -ForegroundColor Green
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment