Text Replacement
Text Replacement
Section titled “Text Replacement”Use core.replace for find-and-replace operations on file contents.
core.replace
Section titled “core.replace”Basic text replacement:
core.replace( before = "old_text", after = "new_text",)Simple Replacement
Section titled “Simple Replacement”# Replace all occurrencescore.replace("internal.corp.com", "api.example.com")
# Equivalent explicit formcore.replace( before = "internal.corp.com", after = "api.example.com",)Path Filtering
Section titled “Path Filtering”# Only replace in specific filescore.replace( before = "internal.corp.com", after = "api.example.com", paths = glob(["**/*.md", "**/*.txt"]),)Regex Replacement
Section titled “Regex Replacement”Use regex_groups for pattern matching:
core.replace( before = "version = ${ver}", after = "version = ${ver}-public", regex_groups = {"ver": "[0-9]+\\.[0-9]+\\.[0-9]+"},)Regex Groups
Section titled “Regex Groups”Groups are defined as ${name} in before/after and regex patterns in regex_groups:
# Capture and reuse groupscore.replace( before = "TODO(${user}): ${message}", after = "TODO: ${message}", # Remove user, keep message regex_groups = { "user": "[a-z]+", "message": ".*", },)Common Patterns
Section titled “Common Patterns”# Version numbersregex_groups = {"version": "[0-9]+\\.[0-9]+\\.[0-9]+"}
# Usernamesregex_groups = {"user": "[a-zA-Z_][a-zA-Z0-9_]*"}
# URLsregex_groups = {"url": "https?://[^\\s]+"}
# File pathsregex_groups = {"path": "[a-zA-Z0-9_/.-]+"}Multiline Replacement
Section titled “Multiline Replacement”For patterns spanning multiple lines:
core.replace( before = "// BEGIN INTERNAL\n${content}// END INTERNAL\n", after = "", regex_groups = {"content": "[\\s\\S]*?"}, # Non-greedy match multiline = True,)Removing Content
Section titled “Removing Content”Replace with empty string to remove:
# Remove single-line commentscore.replace( before = "// INTERNAL: ${content}\n", after = "", regex_groups = {"content": ".*"},)
# Remove block commentscore.replace( before = "/* INTERNAL\n${content}*/\n", after = "", regex_groups = {"content": "[\\s\\S]*?"}, multiline = True,)core.filter_replace
Section titled “core.filter_replace”For complex replacements with mapping:
core.filter_replace( regex = "TODO\\(([a-z]+)\\)", mapping = { "alice": "team-frontend", "bob": "team-backend", },)# TODO(alice) → TODO(team-frontend)# TODO(bob) → TODO(team-backend)With Default
Section titled “With Default”core.filter_replace( regex = "@([a-z]+)\\.internal", mapping = { "alice": "alice@example.com", "bob": "bob@example.com", }, default = "support@example.com", # For unmatched users)Replacement Order
Section titled “Replacement Order”Replacements are independent; order usually doesn’t matter unless patterns overlap:
transformations = [ # These are independent, order doesn't matter core.replace("foo", "bar"), core.replace("baz", "qux"),]
transformations = [ # These overlap, order matters! core.replace("foobar", "special"), # First: specific core.replace("foo", "bar"), # Then: general]Common Use Cases
Section titled “Common Use Cases”Replace URLs
Section titled “Replace URLs”core.replace( before = "https://internal.corp.com", after = "https://api.example.com",)Replace Import Paths
Section titled “Replace Import Paths”core.replace( before = "@internal/", after = "@public/", paths = glob(["**/*.ts", "**/*.js"]),)Remove Internal Comments
Section titled “Remove Internal Comments”core.replace( before = "# INTERNAL: ${comment}\n", after = "", regex_groups = {"comment": ".*"},)Update Package Names
Section titled “Update Package Names”core.replace( before = "com.internal.${pkg}", after = "com.public.${pkg}", regex_groups = {"pkg": "[a-z.]+"}, paths = glob(["**/*.java"]),)Replace in Specific File
Section titled “Replace in Specific File”core.replace( before = '"version": "${ver}"', after = '"version": "${ver}-public"', regex_groups = {"ver": "[0-9.]+"}, paths = glob(["package.json"]),)Escaping
Section titled “Escaping”Special regex characters need escaping:
# Match literal dotscore.replace( before = "example\\.com", after = "example.org",)
# Match literal bracescore.replace( before = "\\{\\{template\\}\\}", after = "{{new_template}}",)Debugging
Section titled “Debugging”Test replacements locally:
# Use folder destination to previewjava -jar copybara.jar migrate copy.bara.sky workflow \ --folder-destination /tmp/output
# Check specific filesdiff original/file.txt /tmp/output/file.txt