1function parse_sources( sources_len, raw_sources, i, j, k, original_crate_source, url, crate_source, crate_names, crate_name) { 2 sources_len = 0 3 split(GIT_SOURCES, raw_sources) 4 for (i = 1; i <= length(raw_sources); i++) { 5 j = index(raw_sources[i], "@") 6 if (j == 0) { 7 warn("invalid source: %s\n", raw_sources[i]) 8 continue 9 } 10 original_crate_source = substr(raw_sources[i], j + 1) 11 split_url(url, original_crate_source) 12 sub(/^git\+/, "", url["scheme"]) 13 delete url["fragment"] 14 delete url["query"] 15 #sub(/\.git$/, "", url["path"]) 16 crate_source = join_url(url) 17 18 split(substr(raw_sources[i], 1, j - 1), crate_names, ",") 19 for (k = 1; k <= length(crate_names); k++) { 20 crate_name = crate_names[k] 21 if (!source_crates[crate_source]) { 22 sources[++sources_len] = crate_source 23 } 24 source_crates[crate_source] = source_crates[crate_source] " " crate_name 25 original_crate_sources[crate_source, crate_name] = original_crate_source 26 } 27 } 28} 29 30function get_source_dir(crate_source, crate_name, git_info, path, in_package, pattern, cmd, cargotoml, line) { 31 if (!split_git_url(git_info, original_crate_sources[crate_source, crate_name])) { 32 exit 1 33 } 34 path = WRKDIR "/" git_info["dir"] 35 # Try to find the first Cargo.toml that defines our crate 36 # We are looking for 37 # [package] 38 # name = "$crate_name" 39 in_package = 0 40 pattern = sprintf("^[ \t]*name[ \t]*=[ \t]*['\"]%s['\"]", crate_name) 41 cmd = FIND " " path " -name Cargo.toml -type f" 42 while ((cmd | getline cargotoml) > 0) { 43 while (getline line <cargotoml) { 44 if (in_package && line ~ pattern) { 45 path = cargotoml 46 sub(/\/Cargo\.toml$/, "", path) 47 close(cmd) 48 close(cargotoml) 49 return path 50 } else if (line ~ /^[ \t]*\[[ \t]*package[ \t]*\][ \t]*$/) { 51 in_package = 1 52 } else if (line ~ /^[ \t]*\[/) { 53 in_package = 0 54 } 55 } 56 close(cargotoml) 57 } 58 close(cmd) 59 60 return path 61} 62 63function find_replaced_crates(input, output, in_patch_crates_io, line, cols) { 64 delete replaced_crates 65# When Cargo.toml has constructs like this (e.g., www/miniserve, x11/wezterm ) 66# [patch.crates-io] 67# mime_guess = { git = "https://github.com/svenstaro/mime_guess.git" } 68# cargo fails to find the replacements we setup. Check for this 69# and replace with our own [patch.crates-io] section. 70# Note that we need to filter out the original patch section. 71 in_patch_crates_io = 0 72 while (getline line <input) { 73 if (in_patch_crates_io) { 74 if (line ~ /[ \t]*git[ \t]*=/ && line !~ /^[ \t]*#/) { 75 split(line, cols) 76 replaced_crates[cols[1]] = 1 77 print "# " line >output 78 continue 79 } 80 } else if (line ~ /^[ \t]*\[[ \t]*patch\.crates-io[ \t]*\][ \t]*$/) { 81 in_patch_crates_io = 1 82 } else if (line ~ /^[ \t]*\[/) { 83 in_patch_crates_io = 0 84 } 85 print line >output 86 } 87 close(input) 88 close(output) 89} 90 91function add_crates_io_patches( header_printed, cmd, cargotoml, source, crates) { 92 header_printed = 0 93# --exclude-dir not supported on FreeBSD < 13 94# cmd = GREP " --include='*/Cargo.toml' --exclude-dir='" CARGO_VENDOR_DIR "' -Flr 'patch.crates-io' " WRKSRC 95 cmd = FIND " " WRKSRC " -name Cargo.toml -not -path '" CARGO_VENDOR_DIR "/*' -exec " GREP " -Flr 'patch.crates-io' {} \\\+" 96 while (cmd | getline cargotoml) { 97 if (0 != system(CP " " cargotoml " " cargotoml ".orig-cargo")) { 98 exit 1 99 } 100 find_replaced_crates(cargotoml ".orig-cargo", cargotoml) 101 if (length(replaced_crates) > 0) { 102 for (i in sources) { 103 source = sources[i] 104 split(source_crates[source], crates) 105 for (j in crates) { 106 if (replaced_crates[crates[j]]) { 107 if (!header_printed) { 108 printf("[patch.crates-io]\n") 109 header_printed = 1 110 } 111 printf("%s = { path = '%s' }\n", crates[j], get_source_dir(source, crates[j])) 112 } 113 } 114 } 115 } 116 } 117 close(cmd) 118} 119 120function add_git_patches( i, j, source, crates) { 121 for (i = 1; i <= length(sources); i++) { 122 source = sources[i] 123 split(source_crates[source], crates) 124 printf("[patch.'%s']\n", source) 125 for (j = 1; j <= length(crates); j++) { 126 printf("%s = { path = '%s' }\n", crates[j], get_source_dir(source, crates[j])) 127 } 128 } 129} 130 131END { 132 parse_sources() 133 add_crates_io_patches() 134 add_git_patches() 135} 136