| #!/usr/bin/env python |
| |
| # Copyright 2017 The Kubernetes Authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """Extract strings from command files and externalize into translation files. |
| Expects to be run from the root directory of the repository. |
| |
| Usage: |
| extract.py pkg/kubectl/cmd/apply.go |
| |
| """ |
| import fileinput |
| import sys |
| import re |
| |
| class MatchHandler(object): |
| """ Simple holder for a regular expression and a function |
| to run if that regular expression matches a line. |
| The function should expect (re.match, file, linenumber) as parameters |
| """ |
| def __init__(self, regex, replace_fn): |
| self.regex = re.compile(regex) |
| self.replace_fn = replace_fn |
| |
| def short_replace(match, file, line_number): |
| """Replace a Short: ... cobra command description with an internationalization |
| """ |
| sys.stdout.write('{}i18n.T({}),\n'.format(match.group(1), match.group(2))) |
| |
| SHORT_MATCH = MatchHandler(r'(\s+Short:\s+)("[^"]+"),', short_replace) |
| |
| def import_replace(match, file, line_number): |
| """Add an extra import for the i18n library. |
| Doesn't try to be smart and detect if it's already present, assumes a |
| gofmt round wil fix things. |
| """ |
| sys.stdout.write('{}\n"k8s.io/kubernetes/pkg/util/i18n"\n'.format(match.group(1))) |
| |
| IMPORT_MATCH = MatchHandler('(.*"k8s.io/kubernetes/pkg/kubectl/cmd/util")', import_replace) |
| |
| |
| def string_flag_replace(match, file, line_number): |
| """Replace a cmd.Flags().String("...", "", "...") with an internationalization |
| """ |
| sys.stdout.write('{}i18n.T("{})"))\n'.format(match.group(1), match.group(2))) |
| |
| STRING_FLAG_MATCH = MatchHandler('(\s+cmd\.Flags\(\).String\("[^"]*", "[^"]*", )"([^"]*)"\)', string_flag_replace) |
| |
| |
| def long_string_replace(match, file, line_number): |
| return '{}i18n.T({}){}'.format(match.group(1), match.group(2), match.group(3)) |
| |
| LONG_DESC_MATCH = MatchHandler('(LongDesc\()(`[^`]+`)([^\n]\n)', long_string_replace) |
| |
| EXAMPLE_MATCH = MatchHandler('(Examples\()(`[^`]+`)([^\n]\n)', long_string_replace) |
| |
| def replace(filename, matchers, multiline_matchers): |
| """Given a file and a set of matchers, run those matchers |
| across the file and replace it with the results. |
| """ |
| # Run all the matchers |
| line_number = 0 |
| for line in fileinput.input(filename, inplace=True): |
| line_number += 1 |
| matched = False |
| for matcher in matchers: |
| match = matcher.regex.match(line) |
| if match: |
| matcher.replace_fn(match, filename, line_number) |
| matched = True |
| break |
| if not matched: |
| sys.stdout.write(line) |
| sys.stdout.flush() |
| with open(filename, 'r') as datafile: |
| content = datafile.read() |
| for matcher in multiline_matchers: |
| match = matcher.regex.search(content) |
| while match: |
| rep = matcher.replace_fn(match, filename, 0) |
| # Escape back references in the replacement string |
| # (And escape for Python) |
| # (And escape for regex) |
| rep = re.sub('\\\\(\\d)', '\\\\\\\\\\1', rep) |
| content = matcher.regex.sub(rep, content, 1) |
| match = matcher.regex.search(content) |
| sys.stdout.write(content) |
| |
| # gofmt the file again |
| from subprocess import call |
| call(["goimports", "-w", filename]) |
| |
| replace(sys.argv[1], [SHORT_MATCH, IMPORT_MATCH, STRING_FLAG_MATCH], [LONG_DESC_MATCH, EXAMPLE_MATCH]) |