From d2399cc6a2d13d4516442d4ec9c368294683ea5c Mon Sep 17 00:00:00 2001 From: Tingluo Huang Date: Mon, 18 Jul 2016 17:09:25 -0400 Subject: [PATCH] remove extra loc strings. --- src/Agent.Worker/TaskCommandExtension.cs | 2 +- src/Misc/layoutbin/en-US/strings.json | 18 ------ src/Test/L0/LocStringsL0.cs | 76 ++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/src/Agent.Worker/TaskCommandExtension.cs b/src/Agent.Worker/TaskCommandExtension.cs index 08b3b90e3f..6dd384c4ca 100644 --- a/src/Agent.Worker/TaskCommandExtension.cs +++ b/src/Agent.Worker/TaskCommandExtension.cs @@ -248,7 +248,7 @@ private void ProcessTaskUploadFileCommand(IExecutionContext context, string data } else { - throw new Exception("CannotUploadFile"); + throw new Exception(StringUtil.Loc("CannotUploadFile")); } } diff --git a/src/Misc/layoutbin/en-US/strings.json b/src/Misc/layoutbin/en-US/strings.json index 01c6820a94..9e73e027d1 100644 --- a/src/Misc/layoutbin/en-US/strings.json +++ b/src/Misc/layoutbin/en-US/strings.json @@ -27,14 +27,9 @@ "BuildTagRequired": "Build tag is required.", "BuildTagsForBuild": "Build '{0}' has following tags now: {1}", "CannotChangeParentTimelineRecord": "Can't change parent timeline record of an existing timeline record.", - "CannotChangePermission": "Cannot change permission of configuration store, report this error. You can still run the agent in interactive mode", - "CanNotFindLoginUserName": "Cannot find logged in username", "CanNotFindService": "Cannot find service {0}", "CanNotFindSystemd": "Cannot find if systemd is installed", "CanNotGrantPermission": "Cannot grant LogonAsService permission to the user {0}", - "CanNotInstallService": "Cannot install the service, check the logs for more details ", - "CanNotRunAgent": "Cannot run. Must configure first.", - "CanNotSetPermissionForAccount": "Cannot set permission for service account. Check the logs for more details.", "CanNotStartService": "Cannot start the service. Check the logs for more details.", "CanNotStopService": "Cannot stop the service {0} in a timely fashion. Please stop the service and reconfigure again.", "CannotUploadFile": "Cannot upload file because file location is not specified.", @@ -72,7 +67,6 @@ "EulasSectionHeader": "End User License Agreements", "Failed": "Failed: ", "FailedDeletingTempDirectory0Message1": "Failed to delete temporary directory '{0}'. {1}", - "FailedToConfigureService": "Service configuration failed, try configuring again after resolving the error", "FailedToConnect": "Failed to connect. Try again or ctrl-c to quit", "FailedToDeleteTempScript": "Failed to delete temporary inline script file '{0}'. {1}", "FailedToFindPool": "Failed to find pool name. Try again or ctrl-c to quit", @@ -81,7 +75,6 @@ "FailedToOpenSCManager": "Failed to Open Service Control Manager", "FailedToPublishTestResults": "Failed to publish test results: {0}", "FailedToReadFile": "Failed to read {0}. Error : {1}.", - "FailedToRemoveService": "Cannot remove the service, remove the service manually and configure again", "FailedToReplaceAgent": "Failed to replace the agent. Try again or ctrl-c to quit", "FileContainerUploadFailed": "Unable to copy file to server StatusCode={0}: {1}. Source file path: {2}. Target server path: {3}", "FileDoesNotExist": "File '{0}' does not exist or is not accessible.", @@ -90,7 +83,6 @@ "FileUploadProgress": "Total file: {0} ---- Uploaded file: {1}", "GetSources": "Get Sources", "GroupDoesNotExists": "Group: {0} does not Exist", - "InstalledGitNotSupport": "The version of the installed Git is less than min-supported Git version {0}.", "InvalidBuildOrCoverageTool": "An internal error occurred. Details: Invalid build or code coverage tool provided. Build tool = '{0}'. Coverage tool = '{1}'. ", "InvalidBuildXml": "Invalid build xml '{0}'. Error '{1}' occured while parsing the file. Ensure the file provided is well-formed and try again.", "InvalidClassFilesDirectory": "Invalid input for 'Class Files Directory' field. It should not be a regular expression or a file path. 'Class Files Directory' accepts comma seperated list of class directories.", @@ -108,8 +100,6 @@ "InvalidWindowsCredential": "Invalid windows credentials entered. Try again or ctrl-c to quit", "IsMultiModuleParameterNotAvailable": "Parameter IsMultiModule is not available. Considering the project as a single module project.", "JobCompleted": "{0:u}: Job {1} completed with result: {2}", - "LinuxServiceConfigured": "Service {0} successfully configured", - "LinuxServiceStartFailed": "Could not start the service. Start the service manually", "ListenerHelp": [ "Visual Studio Team Services Agent", "Copyright (c) Microsoft Corporation", @@ -252,13 +242,11 @@ "RenameIndexFileCoberturaFailed": "Renaming '{0}' to '{1}' failed while publishing code coverage files for '{2}'. Inner Exception: '{3}'", "Replace": "replace? (Y/N)", "ResultsCommandNotFound": "##vso[results.{0}] is not a recognized command for Task command extension. TODO: DOC aka link", - "RMAgentVariableInfo": "ReleaseId={0}, TeamProjectId={1}, ReleaseDefinitionName={2}", "RMArtifactDetailsIncomplete": "Cannot find the required information to download the artifact", "RMArtifactDirectoryNotFoundError": "The artifact directory does not exist: {0}", "RMArtifactDownloadBegin": "Downloading linked artifact {0} of type {1}...", "RMArtifactDownloadFinished": "Downloaded linked artifact {0}", "RMArtifactFolderCreated": "Created artifact folder {0}", - "RMArtifactIsNotContainerType": "The following is not a server drop artifact: {0}", "RMArtifactMatchNotFound": "The build artifact '{0}' does not match any naming patterns, skipping download", "RMArtifactNameDirectoryNotFound": "Directory '{0}' does not exist. Falling back to parent directory: {1}", "RMArtifactsDownloadFinished": "Finished artifacts download", @@ -273,7 +261,6 @@ "RMGitEndpointNotFound": "Cannot find required information in the job to download the Team Foundation Git artifact.", "RMGitHubEndpointNotFound": "Cannot find required information in the job to download the GitHub artifact: {0}", "RMGotJenkinsArtifactDetails": "Received Jenkins Artifact Details", - "RMInitializeTask": "Initialize", "RMJenkinsBuildId": "BuildId: {0}", "RMJenkinsEndpointNotFound": "Cannot find required information in the job to download the Jenkins artifact: {0}", "RMJenkinsJobName": "Job Name: {0}", @@ -291,7 +278,6 @@ "RunAgentAsServiceDescription": "run agent as service? (Y/N)", "RunningJob": "{0:u}: Running job: {1}", "SavedSettings": "{0:u}: Settings Saved.", - "SavingCredential": "Saving credentials...", "ScanToolCapabilities": "Scanning for tool capabilities.", "SelfManageGitCreds": "You are in self manage git creds mode. Make sure your agent host machine can bypass any git authentication challenge.", "ServerUrl": "server URL", @@ -322,8 +308,6 @@ "SvnMappingIgnored": "The entire mapping set is ignored. Proceeding with the full branch mapping.", "SvnNotInstalled": "Can't find installed svn command line utility", "SvnSyncingRepo": "Syncing repository: {0} (Svn)", - "SystemdCannotReload": "Cannot reload systemd daemon", - "SystemdDoesNotExists": "Systemd does not exist, if you are having init.d or any other init system you can manually configure it", "TaskCommandNotFound": "##vso[task.{0}] is not a recognized command for Task command extension. Please reference documentaion (http://go.microsoft.com/fwlink/?LinkId=817296)", "TeeEula": [ "Building sources from a TFVC repository requires accepting the Team Explorer Everywhere End User License Agreement. This step is not required for building sources from Git repositories.", @@ -333,13 +317,11 @@ ], "TestAgentConnection": "Testing agent connection.", "TestResultsRemaining": "Test results remaining: {0}. Test run id: {1}", - "TFSConnectionDownRetrying": "The TFS service is currently unavailable. Error: '{1}'. Retrying to establing a connection - attempt '{0}'.", "TotalUploadFiles": "Uploading {0} files", "TypeRequiredForTimelineRecord": "Type is required for this new timeline record.", "UnableResolveArtifactType": "Can't infer artifact type from artifact location: {0}.", "UnableToArchiveResults": "Unable to archive the test results: {0}", "UnableToParseBuildTrackingConfig0": "Unable to parse the legacy build tracking configuration. A new build directory will be created instead. The previous directory may be left in an unreclaimed state. Legacy configuration contents: {0}", - "UnauthorizedAccess": "You do not have access to {0} to create systemd unit file. Did you forget to run with sudo permission?", "UninstallingService": "Removing service", "UnknownCodeCoverageTool": "Code coverage tool '{0}' is not supported.", "UnregisteringAgent": "Removing agent from the server", diff --git a/src/Test/L0/LocStringsL0.cs b/src/Test/L0/LocStringsL0.cs index 3c346e7aff..7c99e1b884 100644 --- a/src/Test/L0/LocStringsL0.cs +++ b/src/Test/L0/LocStringsL0.cs @@ -1,13 +1,10 @@ -using Microsoft.VisualStudio.Services.Agent; using Microsoft.VisualStudio.Services.Agent.Util; -using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; using System.IO; using System.Linq; using System.Text.RegularExpressions; using Xunit; +using System; namespace Microsoft.VisualStudio.Services.Agent.Tests { @@ -61,11 +58,80 @@ public void IsLocStringsPrettyPrint() IOUtil.SaveObject(sortedResourceDictionary, prettyStringsFile); Assert.True(string.Equals(File.ReadAllText(stringsFile), File.ReadAllText(prettyStringsFile)), $"Orginal string.json file: {stringsFile} is not pretty printed, replace it with: {prettyStringsFile}"); - + // delete file on succeed File.Delete(prettyStringsFile); } + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "LocString")] + public void FindExtraLocStrings() + { + // Load the strings. + string stringsFile = Path.Combine(TestUtil.GetSrcPath(), "Misc", "layoutbin", "en-US", "strings.json"); + Assert.True(File.Exists(stringsFile), $"File does not exist: {stringsFile}"); + var resourceDictionary = IOUtil.LoadObject>(stringsFile); + + // find all loc string key in source file + var keys = new List(); + string[] sourceFiles = Directory.GetFiles( + TestUtil.GetSrcPath(), + "*.cs", + SearchOption.AllDirectories); + foreach (string sourceFile in sourceFiles) + { + // Skip files in the obj directory. + if (sourceFile.Contains(StringUtil.Format("{0}obj{0}", Path.DirectorySeparatorChar))) + { + continue; + } + + foreach (string line in File.ReadAllLines(sourceFile)) + { + // Search for calls to the StringUtil.Loc method within the line. + const string Pattern = "StringUtil.Loc("; + int searchIndex = 0; + int patternIndex; + while (searchIndex < line.Length && + (patternIndex = line.IndexOf(Pattern, searchIndex)) >= 0) + { + // Bump the search index in preparation for the for the next iteration within the same line. + searchIndex = patternIndex + Pattern.Length; + + // Extract the resource key. + int keyStartIndex = patternIndex + Pattern.Length; + int keyEndIndex; + if (keyStartIndex + 2 < line.Length && // Key should start with a ", be followed by at least + line[keyStartIndex] == '"' && // one character, and end with a ". + (keyEndIndex = line.IndexOf('"', keyStartIndex + 1)) > 0) + { + // Remove the first and last double quotes. + keyStartIndex++; + keyEndIndex--; + string key = line.Substring( + startIndex: keyStartIndex, + length: keyEndIndex - keyStartIndex + 1); + if (ValidKeyRegex.IsMatch(key)) + { + // A valid key was extracted. + keys.Add(key); + continue; + } + } + } + } + } + + // find extra loc strings. + var extraKeys = resourceDictionary.Keys.Where(x => !keys.Contains(x))?.ToList(); + + if (extraKeys != null) + { + Assert.True(extraKeys.Count == 0, $"Please save company's money by removing extra loc strings:{Environment.NewLine}{string.Join(Environment.NewLine, extraKeys)}"); + } + } + private void ValidateLocStrings(TestHostContext hc, string project) { using (hc)