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