extract.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!/usr/bin/env python
  2. # Copyright 2017 The Kubernetes Authors.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. """Extract strings from command files and externalize into translation files.
  16. Expects to be run from the root directory of the repository.
  17. Usage:
  18. extract.py pkg/kubectl/cmd/apply.go
  19. """
  20. import fileinput
  21. import sys
  22. import re
  23. class MatchHandler(object):
  24. """ Simple holder for a regular expression and a function
  25. to run if that regular expression matches a line.
  26. The function should expect (re.match, file, linenumber) as parameters
  27. """
  28. def __init__(self, regex, replace_fn):
  29. self.regex = re.compile(regex)
  30. self.replace_fn = replace_fn
  31. def short_replace(match, file, line_number):
  32. """Replace a Short: ... cobra command description with an internationalization
  33. """
  34. sys.stdout.write('{}i18n.T({}),\n'.format(match.group(1), match.group(2)))
  35. SHORT_MATCH = MatchHandler(r'(\s+Short:\s+)("[^"]+"),', short_replace)
  36. def import_replace(match, file, line_number):
  37. """Add an extra import for the i18n library.
  38. Doesn't try to be smart and detect if it's already present, assumes a
  39. gofmt round wil fix things.
  40. """
  41. sys.stdout.write('{}\n"k8s.io/kubectl/pkg/util/i18n"\n'.format(match.group(1)))
  42. IMPORT_MATCH = MatchHandler('(.*"k8s.io/kubectl/pkg/cmd/util")', import_replace)
  43. def string_flag_replace(match, file, line_number):
  44. """Replace a cmd.Flags().String("...", "", "...") with an internationalization
  45. """
  46. sys.stdout.write('{}i18n.T("{})"))\n'.format(match.group(1), match.group(2)))
  47. STRING_FLAG_MATCH = MatchHandler('(\s+cmd\.Flags\(\).String\("[^"]*", "[^"]*", )"([^"]*)"\)', string_flag_replace)
  48. def long_string_replace(match, file, line_number):
  49. return '{}i18n.T({}){}'.format(match.group(1), match.group(2), match.group(3))
  50. LONG_DESC_MATCH = MatchHandler('(LongDesc\()(`[^`]+`)([^\n]\n)', long_string_replace)
  51. EXAMPLE_MATCH = MatchHandler('(Examples\()(`[^`]+`)([^\n]\n)', long_string_replace)
  52. def replace(filename, matchers, multiline_matchers):
  53. """Given a file and a set of matchers, run those matchers
  54. across the file and replace it with the results.
  55. """
  56. # Run all the matchers
  57. line_number = 0
  58. for line in fileinput.input(filename, inplace=True):
  59. line_number += 1
  60. matched = False
  61. for matcher in matchers:
  62. match = matcher.regex.match(line)
  63. if match:
  64. matcher.replace_fn(match, filename, line_number)
  65. matched = True
  66. break
  67. if not matched:
  68. sys.stdout.write(line)
  69. sys.stdout.flush()
  70. with open(filename, 'r') as datafile:
  71. content = datafile.read()
  72. for matcher in multiline_matchers:
  73. match = matcher.regex.search(content)
  74. while match:
  75. rep = matcher.replace_fn(match, filename, 0)
  76. # Escape back references in the replacement string
  77. # (And escape for Python)
  78. # (And escape for regex)
  79. rep = re.sub('\\\\(\\d)', '\\\\\\\\\\1', rep)
  80. content = matcher.regex.sub(rep, content, 1)
  81. match = matcher.regex.search(content)
  82. sys.stdout.write(content)
  83. # gofmt the file again
  84. from subprocess import call
  85. call(["goimports", "-w", filename])
  86. replace(sys.argv[1], [SHORT_MATCH, IMPORT_MATCH, STRING_FLAG_MATCH], [LONG_DESC_MATCH, EXAMPLE_MATCH])