Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

strings' externalization - simple step to multi-lingual options help #22

Closed
wants to merge 3 commits into from

1 participant

El Kodus
El Kodus

It is nice to have.
You'll give non English native speakers easier way to show help descriptors in their native languages (by changing messages.properties only).

El Kodus elkodus closed this
El Kodus

There is cleaner, single commit: fd647c9576

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 28, 2012
  1. El Kodus
Commits on Sep 29, 2012
  1. El Kodus
  2. El Kodus

    better i18n

    elkodus authored
This page is out of date. Refresh to see the latest.
10 src/main/java/joptsimple/BuiltinHelpFormatter.java
View
@@ -46,9 +46,9 @@ a copy of this software and associated documentation files (the
public String format( Map<String, ? extends OptionDescriptor> options ) {
if ( options.isEmpty() )
- return "No options specified";
+ return Messages.getString( "BuiltinHelpFormatter.noOptionsSpecified" );
- grid = new ColumnarData( optionHeader( options ), "Description" );
+ grid = new ColumnarData( optionHeader( options ), Messages.getString( "BuiltinHelpFormatter.description" ) );
Comparator<OptionDescriptor> comparator =
new Comparator<OptionDescriptor>() {
@@ -69,10 +69,10 @@ public int compare( OptionDescriptor first, OptionDescriptor second ) {
private String optionHeader( Map<String, ? extends OptionDescriptor> options ) {
for ( OptionDescriptor each : options.values() ) {
if ( each.isRequired() )
- return "Option (* = required)";
+ return Messages.getString( "BuiltinHelpFormatter.optionRequired" );
}
- return "Option";
+ return Messages.getString( "BuiltinHelpFormatter.option" );
}
private void addHelpLineFor( OptionDescriptor descriptor ) {
@@ -131,7 +131,7 @@ private String createDescriptionDisplay( OptionDescriptor descriptor ) {
return descriptor.description();
String defaultValuesDisplay = createDefaultValuesDisplay( defaultValues );
- return descriptor.description() + ' ' + surround( "default: " + defaultValuesDisplay, '(', ')' );
+ return descriptor.description() + ' ' + surround( Messages.getString( "BuiltinHelpFormatter.default" ) + defaultValuesDisplay, '(', ')' );
}
private String createDefaultValuesDisplay( List<?> defaultValues ) {
22 src/main/java/joptsimple/Messages.java
View
@@ -0,0 +1,22 @@
+package joptsimple;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+ private static final String BUNDLE_NAME = "joptsimple.messages";
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME, Locale.getDefault() );
+
+ private Messages() {
+ }
+
+ public static String getString( String key ) {
+ try {
+ return RESOURCE_BUNDLE.getString( key );
+ } catch ( MissingResourceException e ) {
+ return '!' + key + '!';
+ }
+ }
+}
5 src/main/java/joptsimple/messages.properties
View
@@ -0,0 +1,5 @@
+BuiltinHelpFormatter.default=default:
+BuiltinHelpFormatter.description=Description
+BuiltinHelpFormatter.noOptionsSpecified=No options specified
+BuiltinHelpFormatter.option=Option
+BuiltinHelpFormatter.optionRequired=Option (* = required)
5 src/main/java/joptsimple/messages_en_US.properties
View
@@ -0,0 +1,5 @@
+BuiltinHelpFormatter.default=default:
+BuiltinHelpFormatter.description=Description
+BuiltinHelpFormatter.noOptionsSpecified=No options specified
+BuiltinHelpFormatter.option=Option
+BuiltinHelpFormatter.optionRequired=Option (* = required)
5 src/main/java/joptsimple/messages_pl_PL.properties
View
@@ -0,0 +1,5 @@
+BuiltinHelpFormatter.default=domy\u015Blnie:
+BuiltinHelpFormatter.description=Opis
+BuiltinHelpFormatter.noOptionsSpecified=Brak opcji
+BuiltinHelpFormatter.option=Opcja
+BuiltinHelpFormatter.optionRequired=Opcja (* = wymagana)
197 src/test/java/joptsimple/OptionParserHelpTest.java
View
@@ -21,7 +21,7 @@ a copy of this software and associated documentation files (the
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
+ */
package joptsimple;
@@ -31,6 +31,7 @@ a copy of this software and associated documentation files (the
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import static java.lang.System.*;
@@ -62,6 +63,7 @@ a copy of this software and associated documentation files (the
@Before
public final void createSink() {
+ Locale.setDefault( Locale.US );
sink = new StringWriter();
}
@@ -69,7 +71,7 @@ public final void createSink() {
public void unconfiguredParser() throws Exception {
parser.printHelpOn( sink );
- assertEquals( "No options specified", sink.toString() );
+ assertEquals( Messages.getString( "BuiltinHelpFormatter.noOptionsSpecified" ), sink.toString() );
}
@Test
@@ -78,8 +80,7 @@ public void oneOptionNoArgNoDescription() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "--apple " );
+ assertStandardHelpLines( "--apple " );
}
@Test
@@ -88,8 +89,7 @@ public void oneOptionNoArgWithDescription() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-a some description " );
+ assertStandardHelpLines( "-a some description " );
}
@Test
@@ -99,8 +99,7 @@ public void twoOptionsNoArgWithDescription() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-a some description ",
+ assertStandardHelpLines( "-a some description ",
"--verbose even more description " );
}
@@ -110,8 +109,7 @@ public void oneOptionRequiredArgNoDescription() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-a " );
+ assertStandardHelpLines( "-a " );
}
@Test
@@ -120,30 +118,26 @@ public void oneOptionRequiredArgNoDescriptionWithType() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-a <Integer> " );
+ assertStandardHelpLines( "-a <Integer> " );
}
@Test
public void oneOptionRequiredArgWithDescription() throws Exception {
- parser.accepts( "a", "some value you need" )
- .withRequiredArg().describedAs( "numerical" );
+ parser.accepts( "a", "some value you need" ).withRequiredArg().describedAs( "numerical" );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-a <numerical> some value you need " );
+ assertStandardHelpLines( "-a <numerical> some value you need " );
}
@Test
public void oneOptionRequiredArgWithDescriptionAndType() throws Exception {
- parser.accepts( "a", "some value you need" )
- .withRequiredArg().describedAs( "numerical" ).ofType( Integer.class );
+ parser.accepts( "a", "some value you need" ).withRequiredArg().describedAs( "numerical" )
+ .ofType( Integer.class );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-a <Integer: numerical> some value you need " );
+ assertStandardHelpLines( "-a <Integer: numerical> some value you need " );
}
@Test
@@ -152,8 +146,7 @@ public void oneOptionOptionalArgNoDescription() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "--threshold " );
+ assertStandardHelpLines( "--threshold " );
}
@Test
@@ -162,33 +155,28 @@ public void oneOptionOptionalArgNoDescriptionWithType() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-a [Float] " );
+ assertStandardHelpLines( "-a [Float] " );
}
@Test
public void oneOptionOptionalArgWithDescription() throws Exception {
- parser.accepts( "threshold", "some value you need" )
- .withOptionalArg().describedAs( "positive integer" );
+ parser.accepts( "threshold", "some value you need" ).withOptionalArg().describedAs( "positive integer" );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "--threshold [positive integer] some value you need " );
+ assertStandardHelpLines( "--threshold [positive integer] some value you need " );
}
@Test
public void oneOptionOptionalArgWithDescriptionAndType() throws Exception {
- parser.accepts( "threshold", "some value you need" )
- .withOptionalArg().describedAs( "positive decimal" ).ofType( Double.class );
+ parser.accepts( "threshold", "some value you need" ).withOptionalArg().describedAs( "positive decimal" )
+ .ofType( Double.class );
parser.printHelpOn( sink );
- assertHelpLines(
- "Option Description ",
+ assertHelpLines( "Option Description ",
"------ ----------- ",
- "--threshold [Double: positive decimal] some value you need ",
- "" );
+ "--threshold [Double: positive decimal] some value you need ", "" );
}
@Test
@@ -197,8 +185,7 @@ public void alternativeLongOptions() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-W <opt=value> Alternative form of long options " );
+ assertStandardHelpLines( "-W <opt=value> Alternative form of long options " );
}
@Test
@@ -207,30 +194,26 @@ public void optionSynonymsWithoutArguments() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-v, --chatty be verbose " );
+ assertStandardHelpLines( "-v, --chatty be verbose " );
}
@Test
public void optionSynonymsWithRequiredArgument() throws Exception {
- parser.acceptsAll( asList( "L", "index" ), "set level" )
- .withRequiredArg().ofType( Integer.class );
+ parser.acceptsAll( asList( "L", "index" ), "set level" ).withRequiredArg().ofType( Integer.class );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-L, --index <Integer> set level " );
+ assertStandardHelpLines( "-L, --index <Integer> set level " );
}
@Test
public void optionSynonymsWithOptionalArgument() throws Exception {
- parser.acceptsAll( asList( "d", "since" ), "date filter" )
- .withOptionalArg().describedAs( "yyyyMMdd" ).ofType( Date.class );
+ parser.acceptsAll( asList( "d", "since" ), "date filter" ).withOptionalArg().describedAs( "yyyyMMdd" )
+ .ofType( Date.class );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-d, --since [Date: yyyyMMdd] date filter " );
+ assertStandardHelpLines( "-d, --since [Date: yyyyMMdd] date filter " );
}
@Test
@@ -239,8 +222,7 @@ public void optionSynonymsSortedByShortOptionThenLexicographical() throws Except
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-v, --chatty, --prolix " );
+ assertStandardHelpLines( "-v, --chatty, --prolix " );
}
@Test
@@ -254,8 +236,7 @@ public void writingToOutputStream() throws Exception {
// Bug 1956418
@Test
- public void outputStreamFlushedButNotClosedWhenPrintingHelp()
- throws Exception {
+ public void outputStreamFlushedButNotClosedWhenPrintingHelp() throws Exception {
FakeOutputStream fake = new FakeOutputStream();
@@ -267,16 +248,16 @@ public void outputStreamFlushedButNotClosedWhenPrintingHelp()
@Test
public void bothColumnsExceedingAllocatedWidths() throws Exception {
- parser.acceptsAll( asList( "t", "threshold", "cutoff" ),
- "a threshold value beyond which a certain level of the application should cease to write logs" )
+ parser
+ .acceptsAll( asList( "t", "threshold", "cutoff" ),
+ "a threshold value beyond which a certain level of the application should cease to write logs" )
.withRequiredArg()
.describedAs( "a positive decimal number that will represent the threshold that has been outlined" )
.ofType( Double.class );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-t, --cutoff, --threshold <Double: a a threshold value beyond which a ",
+ assertStandardHelpLines( "-t, --cutoff, --threshold <Double: a a threshold value beyond which a ",
" positive decimal number that will certain level of the application ",
" represent the threshold that has should cease to write logs ",
" been outlined> " );
@@ -285,61 +266,52 @@ public void bothColumnsExceedingAllocatedWidths() throws Exception {
// Bug 2018262
@Test
public void gradleHelp() throws Exception {
- parser.acceptsAll( asList( "n", "non-recursive" ),
- "Do not execute primary tasks of child projects." );
+ parser.acceptsAll( asList( "n", "non-recursive" ), "Do not execute primary tasks of child projects." );
parser.acceptsAll( singletonList( "S" ),
"Don't trigger a System.exit(0) for normal termination. Used for Gradle's internal testing." );
- parser.acceptsAll( asList( "I", "no-imports" ),
- "Disable usage of default imports for build script files." );
+ parser.acceptsAll( asList( "I", "no-imports" ), "Disable usage of default imports for build script files." );
parser.acceptsAll( asList( "u", "no-search-upward" ),
"Don't search in parent folders for a settings.gradle file." );
- parser.acceptsAll( asList( "x", "cache-off" ),
- "No caching of compiled build scripts." );
- parser.acceptsAll( asList( "r", "rebuild-cache" ),
- "Rebuild the cache of compiled build scripts." );
+ parser.acceptsAll( asList( "x", "cache-off" ), "No caching of compiled build scripts." );
+ parser.acceptsAll( asList( "r", "rebuild-cache" ), "Rebuild the cache of compiled build scripts." );
parser.acceptsAll( asList( "v", "version" ), "Print version info." );
- parser.acceptsAll( asList( "d", "debug" ),
- "Log in debug mode (includes normal stacktrace)." );
+ parser.acceptsAll( asList( "d", "debug" ), "Log in debug mode (includes normal stacktrace)." );
parser.acceptsAll( asList( "q", "quiet" ), "Log errors only." );
- parser.acceptsAll( asList( "j", "ivy-debug" ),
- "Set Ivy log level to debug (very verbose)." );
+ parser.acceptsAll( asList( "j", "ivy-debug" ), "Set Ivy log level to debug (very verbose)." );
parser.acceptsAll( asList( "i", "ivy-quiet" ), "Set Ivy log level to quiet." );
parser.acceptsAll( asList( "s", "stacktrace" ),
"Print out the stacktrace also for user exceptions (e.g. compile error)." );
parser.acceptsAll( asList( "f", "full-stacktrace" ),
"Print out the full (very verbose) stacktrace for any exceptions." );
- parser.acceptsAll( asList( "t", "tasks" ),
- "Show list of all available tasks and their dependencies." );
- parser.acceptsAll( asList( "p", "project-dir" ),
- "Specifies the start dir for Gradle. Defaults to current dir." )
- .withRequiredArg().ofType( String.class );
- parser.acceptsAll( asList( "g", "gradle-user-home" ),
- "Specifies the gradle user home dir." )
- .withRequiredArg().ofType( String.class );
- parser.acceptsAll( asList( "l", "plugin-properties-file" ),
- "Specifies the plugin.properties file." )
+ parser.acceptsAll( asList( "t", "tasks" ), "Show list of all available tasks and their dependencies." );
+ parser
+ .acceptsAll( asList( "p", "project-dir" ), "Specifies the start dir for Gradle. Defaults to current dir." )
.withRequiredArg().ofType( String.class );
- parser.acceptsAll( asList( "b", "buildfile" ),
- "Specifies the build file name (also for subprojects). Defaults to build.gradle." )
+ parser.acceptsAll( asList( "g", "gradle-user-home" ), "Specifies the gradle user home dir." ).withRequiredArg()
+ .ofType( String.class );
+ parser.acceptsAll( asList( "l", "plugin-properties-file" ), "Specifies the plugin.properties file." )
.withRequiredArg().ofType( String.class );
- parser.acceptsAll( asList( "D", "systemprop" ),
- "Set system property of the JVM (e.g. -Dmyprop=myvalue)." )
+ parser
+ .acceptsAll( asList( "b", "buildfile" ),
+ "Specifies the build file name (also for subprojects). Defaults to build.gradle." ).withRequiredArg()
+ .ofType( String.class );
+ parser.acceptsAll( asList( "D", "systemprop" ), "Set system property of the JVM (e.g. -Dmyprop=myvalue)." )
.withRequiredArg().ofType( String.class );
- parser.acceptsAll( asList( "P", "projectprop" ),
- "Set project property for the build script (e.g. -Pmyprop=myvalue)." )
- .withRequiredArg().ofType( String.class );
- parser.acceptsAll( asList( "e", "embedded" ),
- "Specify an embedded build script." )
- .withRequiredArg().ofType( String.class );
- parser.acceptsAll( asList( "B", "bootstrap-debug" ),
- "Specify a text to be logged at the beginning (e.g. used by Gradle's bootstrap class." )
+ parser
+ .acceptsAll( asList( "P", "projectprop" ),
+ "Set project property for the build script (e.g. -Pmyprop=myvalue)." ).withRequiredArg()
+ .ofType( String.class );
+ parser.acceptsAll( asList( "e", "embedded" ), "Specify an embedded build script." ).withRequiredArg()
+ .ofType( String.class );
+ parser
+ .acceptsAll( asList( "B", "bootstrap-debug" ),
+ "Specify a text to be logged at the beginning (e.g. used by Gradle's bootstrap class." )
.withRequiredArg().ofType( String.class );
parser.acceptsAll( asList( "h", "?" ), "Shows this help message" ).forHelp();
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-?, -h Shows this help message ",
+ assertStandardHelpLines( "-?, -h Shows this help message ",
"-B, --bootstrap-debug Specify a text to be logged at the ",
" beginning (e.g. used by Gradle's ",
" bootstrap class. ",
@@ -384,26 +356,21 @@ public void gradleHelp() throws Exception {
@Test
public void dateConverterShowsDatePattern() throws Exception {
- parser.accepts( "date", "a date" ).withRequiredArg()
- .withValuesConvertedBy( datePattern( "MM/dd/yy" ) );
+ parser.accepts( "date", "a date" ).withRequiredArg().withValuesConvertedBy( datePattern( "MM/dd/yy" ) );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "--date <MM/dd/yy> a date " );
+ assertStandardHelpLines( "--date <MM/dd/yy> a date " );
}
@Test
- public void dateConverterShowsDatePatternInCombinationWithDescription()
- throws Exception {
- parser.accepts( "date", "a date" ).withOptionalArg()
- .describedAs( "your basic date pattern" )
+ public void dateConverterShowsDatePatternInCombinationWithDescription() throws Exception {
+ parser.accepts( "date", "a date" ).withOptionalArg().describedAs( "your basic date pattern" )
.withValuesConvertedBy( datePattern( "MM/dd/yy" ) );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "--date [MM/dd/yy: your basic date a date ",
+ assertStandardHelpLines( "--date [MM/dd/yy: your basic date a date ",
" pattern] " );
}
@@ -415,8 +382,7 @@ public void leavesEmbeddedNewlinesInDescriptionsAlone() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "--type Specify the output type. ",
+ assertStandardHelpLines( "--type Specify the output type. ",
" 'raw' = raw data. ",
" 'java' = java class " );
}
@@ -427,8 +393,7 @@ public void includesDefaultValueForRequiredOptionArgument() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-a (default: boo) " );
+ assertStandardHelpLines( "-a (default: boo) " );
}
@Test
@@ -437,30 +402,27 @@ public void includesDefaultValueForOptionalOptionArgument() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-b [Integer] (default: 5) " );
+ assertStandardHelpLines( "-b [Integer] (default: 5) " );
}
@Test
public void includesDefaultValueForArgumentWithDescription() throws Exception {
- parser.accepts( "c", "a quantity" ).withOptionalArg().ofType( BigDecimal.class )
- .describedAs( "quantity" ).defaultsTo( TEN );
+ parser.accepts( "c", "a quantity" ).withOptionalArg().ofType( BigDecimal.class ).describedAs( "quantity" )
+ .defaultsTo( TEN );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-c [BigDecimal: quantity] a quantity (default: 10) " );
+ assertStandardHelpLines( "-c [BigDecimal: quantity] a quantity (default: 10) " );
}
@Test
public void includesListOfDefaultsForArgumentWithDescription() throws Exception {
- parser.accepts( "d", "dizzle" ).withOptionalArg().ofType( Integer.class )
- .describedAs( "double dizzle" ).defaultsTo( 2, 3, 5, 7 );
+ parser.accepts( "d", "dizzle" ).withOptionalArg().ofType( Integer.class ).describedAs( "double dizzle" )
+ .defaultsTo( 2, 3, 5, 7 );
parser.printHelpOn( sink );
- assertStandardHelpLines(
- "-d [Integer: double dizzle] dizzle (default: [2, 3, 5, 7]) " );
+ assertStandardHelpLines( "-d [Integer: double dizzle] dizzle (default: [2, 3, 5, 7]) " );
}
@Test
@@ -469,8 +431,7 @@ public void marksRequiredOptionsSpecially() throws Exception {
parser.printHelpOn( sink );
- assertStandardHelpLinesWithRequiredIndicator(
- "* -e " );
+ assertStandardHelpLinesWithRequiredIndicator( "* -e " );
}
@Test
@@ -506,7 +467,7 @@ private void assertStandardHelpLines( String... expectedLines ) {
addAll( lines, expectedLines );
lines.add( EMPTY );
- assertHelpLines( lines.toArray( new String[ lines.size() ] ) );
+ assertHelpLines( lines.toArray( new String[lines.size()] ) );
}
private void assertStandardHelpLinesWithRequiredIndicator( String... expectedLines ) {
@@ -516,7 +477,7 @@ private void assertStandardHelpLinesWithRequiredIndicator( String... expectedLin
addAll( lines, expectedLines );
lines.add( EMPTY );
- assertHelpLines( lines.toArray( new String[ lines.size() ] ) );
+ assertHelpLines( lines.toArray( new String[lines.size()] ) );
}
private void assertHelpLines( String... expectedLines ) {
Something went wrong with that request. Please try again.