#!/bin/bash # # Copyright 2016 The Bazel Authors. All rights reserved. # # 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 -euo pipefail global PLATFORM := $[uname -s | tr 'A-Z' 'a-z] # Print the resolved path of a symbolic link (or the path itself if not a link). # # The result may be relative to the current working directory and may contain # "." and ".." references. Use `normalize_path` to remove those. # # Fail and print nothing if the input path doesn't exist, i.e. it's a # non-existent file, dangling symlink, or circular symlink. proc resolve_links { var name = $1 if test -e $name { # resolve all links, keep path absolute while [ -L "$name" ] { var target = $[readlink $name] if test $[echo $target | head -c1] = "/" { name := $target } else { name := ""$[dirname $name]/$target"" } } echo $name } else { false # fail the function } } # Normalize a path string by removing "." and ".." references from it. # # Print the result to stdout. # # The path doesn't have to point to an existing file. proc normalize_path { var name = $1 var path = ''"" var uplevels = '0' while [ "$name" != "/" -a "$name" != "." ] { var segment = $[basename $name] name := $[dirname $name] test $segment = "." && continue if test $segment = ".." { uplevels := "$(${uplevels}+1)" } else { if test $uplevels -gt 0 { uplevels := "$(${uplevels}-1)" } else { path := ""$(segment)/$(path)"" } } } if test $name = "." { while [ "$uplevels" -gt 0 ] { path := ""../$path"" uplevels := "$(${uplevels}-1)" } } path := $(path%/) if test $name = "/" { echo "/$path" } else { test -n $path && echo $path || echo "." } } # Custom implementation of `realpath(1)`. # # Resolves a symlink to the absolute path it points to. Fails if the link or # its target does not exist. # # Fails and prints nothing if the input path doesn't exist, i.e. it's a # non-existent file, dangling symlink, or circular symlink. # # We use this method instead of `realpath(1)` because the latter is not # available on Mac OS X by default. proc get_real_path { var name = $1 name := $[resolve_links $name || echo] if test -n $name { normalize_path "$[pwd]/$name" } else { false # fail the function } } proc md5_file { if test $Argc -gt 0 { var result = ''"" if [[ ${PLATFORM} == "darwin" ]] { result := $[md5 -q $ifsjoin(Argv) || echo] } else { result := $[md5sum $ifsjoin(Argv) | awk '{print $1}' || echo] } if test -n $result { echo $result } else { false } } else { false } } (CommandList children: [ (C {(set)} {(-euo)} {(pipefail)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:PLATFORM) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [(C {(uname)} {(-s)}) (C {(tr)} {(SQ )} {(SQ )})] negated: False ) ] ) left_token: spids: [55 71] ) ) } spids: [53] ) ] spids: [53] ) (FuncDef name: resolve_links body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:name) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [107] ) ] spids: [105] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-e)} {(DQ ($ VSub_Name "$name"))} {(Lit_Other "]")}) terminator: ) ] action: [ (While cond: [ (Sentence child: (C {(Lit_Other "[")} {(-L)} {(DQ ($ VSub_Name "$name"))} {(Lit_Other "]")}) terminator: ) ] body: (DoGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:target) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(readlink)} {(DQ ($ VSub_Name "$name"))})] ) left_token: spids: [153 159] ) } spids: [152] ) ] spids: [150] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} { (DQ (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Name "$target"))}) (C {(head)} {(-c1)}) ] negated: False ) ] ) left_token: spids: [167 179] ) ) } {(Lit_Other "=")} {(DQ (/))} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:name) op: Equal rhs: {(DQ ($ VSub_Name "$target"))} spids: [194] ) ] spids: [194] ) ] spids: [-1 191] ) ] else_action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:name) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(dirname)} {(DQ ($ VSub_Name "$name"))}) ] ) left_token: spids: [205 211] ) (/) ($ VSub_Name "$target") ) } spids: [203] ) ] spids: [203] ) ] spids: [200 217] ) ] spids: [147 220] ) ) (C {(echo)} {(DQ ($ VSub_Name "$name"))}) ] spids: [-1 127] ) ] else_action: [(C {(false)})] spids: [230 239] ) ] spids: [102] ) spids: [96 101] ) (FuncDef name: normalize_path body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:name) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [270] ) ] spids: [268] ) (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:path) op:Equal rhs:{(DQ )} spids:[279])] spids: [277] ) (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:uplevels) op:Equal rhs:{(0)} spids:[286])] spids: [284] ) (While cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$name"))} {(KW_Bang "!") (Lit_Other "=")} {(DQ (/))} {(-a)} {(DQ ($ VSub_Name "$name"))} {(KW_Bang "!") (Lit_Other "=")} {(DQ (.))} {(Lit_Other "]")} ) terminator: ) ] body: (DoGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:segment) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [(C {(basename)} {(DQ ($ VSub_Name "$name"))})] ) left_token: spids: [328 334] ) ) } spids: [326] ) ] spids: [324] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:name) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [(C {(dirname)} {(DQ ($ VSub_Name "$name"))})] ) left_token: spids: [340 346] ) ) } spids: [338] ) ] spids: [338] ) (AndOr children: [ (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$segment"))} {(Lit_Other "=")} {(DQ (.))} {(Lit_Other "]")} ) (ControlFlow token:) ] op_id: Op_DAmp ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$segment"))} {(Lit_Other "=")} {(DQ (..))} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:uplevels) op: Equal rhs: { (DQ (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{(${ VSub_Name uplevels)}) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [393 400] ) ) } spids: [391] ) ] spids: [391] ) ] spids: [-1 388] ) ] else_action: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$uplevels"))} {(-gt)} {(0)} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:uplevels) op: Equal rhs: { (DQ (ArithSubPart anode: (ArithBinary op_id: Arith_Minus left: (ArithWord w:{(${ VSub_Name uplevels)}) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [427 434] ) ) } spids: [425] ) ] spids: [425] ) ] spids: [-1 422] ) ] else_action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:path) op: Equal rhs: {(DQ (${ VSub_Name segment) (/) (${ VSub_Name path))} spids: [441] ) ] spids: [441] ) ] spids: [438 453] ) ] spids: [404 456] ) ] spids: [321 459] ) ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$name"))} {(Lit_Other "=")} {(DQ (.))} {(Lit_Other "]")} ) terminator: ) ] action: [ (While cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$uplevels"))} {(-gt)} {(0)} {(Lit_Other "]")} ) terminator: ) ] body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:path) op: Equal rhs: {(DQ (../) ($ VSub_Name "$path"))} spids: [501] ) ] spids: [501] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:uplevels) op: Equal rhs: { (DQ (ArithSubPart anode: (ArithBinary op_id: Arith_Minus left: (ArithWord w:{(${ VSub_Name uplevels)}) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [510 517] ) ) } spids: [508] ) ] spids: [508] ) ] spids: [498 521] ) ) ] spids: [-1 480] ) ] spids: [-1 524] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:path) op: Equal rhs: { (DQ (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_Percent arg_word:{(Lit_Slash /)}) spids: [530 534] ) ) } spids: [528] ) ] spids: [528] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$name"))} {(Lit_Other "=")} {(DQ (/))} {(Lit_Other "]")} ) terminator: ) ] action: [(C {(echo)} {(DQ (/) ($ VSub_Name "$path"))})] spids: [-1 556] ) ] else_action: [ (AndOr children: [ (C {(Lit_Other "[")} {(-n)} {(DQ ($ VSub_Name "$path"))} {(Lit_Other "]")}) (AndOr children: [(C {(echo)} {(DQ ($ VSub_Name "$path"))}) (C {(echo)} {(DQ (.))})] op_id: Op_DPipe ) ] op_id: Op_DAmp ) ] spids: [567 597] ) ] spids: [265] ) spids: [259 264] ) (FuncDef name: get_real_path body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:name) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [643] ) ] spids: [641] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:name) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (AndOr children: [ (C {(resolve_links)} {(DQ ($ VSub_Name "$name"))}) (C {(echo)}) ] op_id: Op_DPipe ) ] ) left_token: spids: [651 661] ) ) } spids: [649] ) ] spids: [649] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ ($ VSub_Name "$name"))} {(Lit_Other "]")}) terminator: ) ] action: [ (C {(normalize_path)} { (DQ (CommandSubPart command_list: (CommandList children:[(C {(pwd)})]) left_token: spids: [684 686] ) (/) ($ VSub_Name "$name") ) } ) ] spids: [-1 678] ) ] else_action: [(C {(false)})] spids: [692 701] ) ] spids: [638] ) spids: [632 637] ) (FuncDef name: md5_file body: (BraceGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {($ VSub_Pound "$#")} {(-gt)} {(0)} {(Lit_Other "]")}) terminator: ) ] action: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:result) op: Equal rhs: {(DQ )} spids: [733] ) ] spids: [731] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobDEqual left: {(${ VSub_Name PLATFORM)} right: {(DQ (darwin))} ) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:result) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (AndOr children: [ (C {(md5)} {(-q)} {($ VSub_At "$@")}) (C {(echo)}) ] op_id: Op_DPipe ) ] ) left_token: spids: [759 769] ) } spids: [758] ) ] spids: [758] ) ] spids: [-1 755] ) ] else_action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:result) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (AndOr children: [ (Pipeline children: [ (C {(md5sum)} {($ VSub_At "$@")}) (C {(awk)} {(SQ <"{print $1}">)}) ] negated: False ) (C {(echo)}) ] op_id: Op_DPipe ) ] ) left_token: spids: [776 792] ) } spids: [775] ) ] spids: [775] ) ] spids: [772 795] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ ($ VSub_Name "$result"))} {(Lit_Other "]")} ) terminator: ) ] action: [(C {(echo)} {(DQ ($ VSub_Name "$result"))})] spids: [-1 812] ) ] else_action: [(C {(false)})] spids: [822 828] ) ] spids: [-1 728] ) ] else_action: [(C {(false)})] spids: [831 837] ) ] spids: [712] ) spids: [706 711] ) ] )