diff options
Diffstat (limited to 'resources/tools/block_replacer')
-rw-r--r-- | resources/tools/block_replacer/apache2gpl.sh | 27 | ||||
-rw-r--r-- | resources/tools/block_replacer/apache_block.txt | 11 | ||||
-rw-r--r-- | resources/tools/block_replacer/gpl2apache.sh | 27 | ||||
-rw-r--r-- | resources/tools/block_replacer/gpl_block.txt | 13 | ||||
-rw-r--r-- | resources/tools/block_replacer/replace.py | 126 |
5 files changed, 204 insertions, 0 deletions
diff --git a/resources/tools/block_replacer/apache2gpl.sh b/resources/tools/block_replacer/apache2gpl.sh new file mode 100644 index 0000000000..f248393d50 --- /dev/null +++ b/resources/tools/block_replacer/apache2gpl.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# Copyright (c) 2020 Cisco and/or its affiliates. +# 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. + +set -exuo pipefail + +if [[ "${#}" != "1" ]]; then + echo 'An utility to switch license comment blocks.' + echo 'Requires files "gpl_block.txt" and "apache_block.txt" in the working' + echo 'directory, and a single argument pointing to root directory.' + echo 'Affects only .sh and .py files.' + exit 1 +fi + +find "${1}" \( -name "*.py" -o -name "*.sh" \) -print0 | xargs -0 \ +python3 replace.py "apache_block.txt" "gpl_block.txt" diff --git a/resources/tools/block_replacer/apache_block.txt b/resources/tools/block_replacer/apache_block.txt new file mode 100644 index 0000000000..790a3c4ea1 --- /dev/null +++ b/resources/tools/block_replacer/apache_block.txt @@ -0,0 +1,11 @@ +# 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. diff --git a/resources/tools/block_replacer/gpl2apache.sh b/resources/tools/block_replacer/gpl2apache.sh new file mode 100644 index 0000000000..a1ef8df075 --- /dev/null +++ b/resources/tools/block_replacer/gpl2apache.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# Copyright (c) 2020 Cisco and/or its affiliates. +# 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. + +set -exuo pipefail + +if [[ "${#}" != "1" ]]; then + echo 'An utility to switch license comment blocks.' + echo 'Requires files "gpl_block.txt" and "apache_block.txt" in the working' + echo 'directory, and a single argument pointing to root directory.' + echo 'Affects only .sh and .py files.' + exit 1 +fi + +find "${1}" \( -name "*.py" -o -name "*.sh" \) -print0 | xargs -0 \ +python3 replace.py "gpl_block.txt" "apache_block.txt" diff --git a/resources/tools/block_replacer/gpl_block.txt b/resources/tools/block_replacer/gpl_block.txt new file mode 100644 index 0000000000..2dbbb2af06 --- /dev/null +++ b/resources/tools/block_replacer/gpl_block.txt @@ -0,0 +1,13 @@ +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this file. If not, see <https://www.gnu.org/licenses/>. diff --git a/resources/tools/block_replacer/replace.py b/resources/tools/block_replacer/replace.py new file mode 100644 index 0000000000..02d1889331 --- /dev/null +++ b/resources/tools/block_replacer/replace.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2020 Cisco and/or its affiliates. +# 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. + +"""A script simplifying replacement of blocks of lines. + +A bash solution created by combining these two: + https://unix.stackexchange.com/a/181215 + https://stackoverflow.com/a/23849180 +does not seem to work if the blocks contain complicated characters. +""" + +import argparse +import os +import tempfile + +def main(): + """Main function for the block replacing script.""" + + description = '''Replace a block of lines with another block. + + Both block-to-replace and replacing-block are read from a file. + The replacement is performed on a file, in-place. + Only first block occurence is replaced. + If the block-to-replace is preceded by a partial match, + it may not be recognized. + + The current implementation uses temporary files, + created in the working directory. + if something fails, thise temporary files need to be deleted manually. + + TODO: Preserve target attributes. Maybe https://pypi.org/project/in-place/ +''' + parser = argparse.ArgumentParser(description) + parser.add_argument( + u"before", type=str, + help=u"Path to file containing the old content to replace." + ) + parser.add_argument( + u"after", type=str, + help=u"Path to file containing the new content to replace with." + ) + parser.add_argument( + u"targets", metavar=u"target", nargs=u"+", type=str, + help=u"Paths to file where the replacement should be made." + ) + args = parser.parse_args() + + do_it(args) + + +def do_it(args): + """Read contents, create edited target, replace the original target with it. + + :param args: Parsed command line arguments. + :type args: Object (typically argparse.Namespace) which contains + "before", "after" and "target" fields. + """ + with open(args.before, u"r") as file_in: + content_before = file_in.readlines() + before_len = len(content_before) + with open(args.after, u"r") as file_in: + content_after = file_in.readlines() + + for target in args.targets: + with tempfile.NamedTemporaryFile( + dir=u".", mode=u"w", delete=False + ) as file_out: + with open(target, u"r") as file_in: + # Phase one, searching for content, copying what does not match. + buffer_lines = list() + line_index_to_check = 0 + content_found = False + while 1: + line_in = file_in.readline() + if not line_in: + print(f"{target}: Content not found.") + for line_out in buffer_lines: + file_out.write(line_out) + buffer_lines = list() + break + if line_in != content_before[line_index_to_check]: + line_index_to_check = 0 + if buffer_lines: + for line_out in buffer_lines: + file_out.write(line_out) + buffer_lines = list() + file_out.write(line_in) + continue + buffer_lines.append(line_in) + line_index_to_check += 1 + if line_index_to_check < before_len: + continue + # Buffer has the match! Do not write it. + content_found = True + break + if not content_found: + file_out.close() + os.remove(file_out.name) + continue + # Phase two, write the replacement instead. + for line_out in content_after: + file_out.write(line_out) + # Phase three, copy the rest of the file. + while 1: + line_in = file_in.readline() + if not line_in: + print(f"{target}: Replacement done.") + break + file_out.write(line_in) + os.replace(file_out.name, target) + + +if __name__ == u"__main__": + main() |