setconst global FOO = "bar"#!/bin/bash -e # Copyright 2015 Google Inc. 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. # Kythe's arcanist script-and-regex linter. Expected output format: # /^((?P.+?)::)?(?Pwarning|error|advice):(?P\\d+)? (?P.*)$/m # # Usage: linter.sh # # Optionally uses shellcheck if it is found on PATH along with jq. # # Arcanist Documentation: # https://secure.phabricator.com/book/phabricator/article/arcanist_lint_script_and_regex/ readonly file = $1setconst global FOO = "bar" readonly name = $[basename $1]setconst global FOO = "bar" readonly dir = $[dirname $1] matchstr $file { AUTHORS|CONTRIBUTORS|WORKSPACE|third_party/*|tools/*|*.md|BUILD|*/BUILD|*/testdata/*|*.yaml|*.json|*.html|*.pb.go|.arclint|.gitignore|*/.gitignore|.arcconfig|*/__phutil_*|*.bzl|.kythe|kythe/web/site/* { } # skip copyright checks *.sh|*.bash { if command -v shellcheck &>/dev/null && command -v jq &>/dev/null; { shellcheck -f json $file | \ jq -r '.[] | "shellcheck::" + (if .level == "info" then "advice" else .level end) + ":" + (.line | tostring) + " " + .message' } } * { if ! grep -q 'Copyright 201[4-9] Google Inc. All rights reserved.' $file { echo 'copyright header::error:1 File missing copyright header' } } } # Ensure filenames/paths do not clash on case-insensitive file systems. if grep -q [A-Z] <<<$dir { echo "case-insensitivity::error:1 $dir directory contains an uppercase letter" } if [[ $(find "$dir" -maxdepth 0 -iname "$name" | wc -l) -gt 1 ]] { echo "case-insensitivity::error:1 $name filename clashes on case-insensitive file systems" } (CommandList children: [ (Assignment keyword: Assign_Readonly pairs: [ (assign_pair lhs: (LhsName name:file) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [74] ) ] spids: [72] ) (Assignment keyword: Assign_Readonly pairs: [ (assign_pair lhs: (LhsName name:name) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children:[(C {(basename)} {(DQ ($ VSub_Number "$1"))})]) left_token: spids: [83 89] ) ) } spids: [81] ) ] spids: [79] ) (Assignment keyword: Assign_Readonly pairs: [ (assign_pair lhs: (LhsName name:dir) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children:[(C {(dirname)} {(DQ ($ VSub_Number "$1"))})]) left_token: spids: [96 102] ) ) } spids: [94] ) ] spids: [92] ) (Case to_match: {($ VSub_Name "$file")} arms: [ (case_arm pat_list: [ {(AUTHORS)} {(CONTRIBUTORS)} {(WORKSPACE)} {(third_party/) (Lit_Other "*")} {(tools/) (Lit_Other "*")} {(Lit_Other "*") (.md)} {(BUILD)} {(Lit_Other "*") (/BUILD)} {(Lit_Other "*") (/testdata/) (Lit_Other "*")} {(Lit_Other "*") (.yaml)} {(Lit_Other "*") (.json)} {(Lit_Other "*") (.html)} {(Lit_Other "*") (.pb.go)} {(.arclint)} {(.gitignore)} {(Lit_Other "*") (/.gitignore)} {(.arcconfig)} {(Lit_Other "*") (/__phutil_) (Lit_Other "*")} {(Lit_Other "*") (.bzl)} {(.kythe)} {(kythe/web/site/) (Lit_Other "*")} ] spids: [113 169 172 -1] ) (case_arm pat_list: [{(Lit_Other "*") (.sh)} {(Lit_Other "*") (.bash)}] action: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(command)} {(-v)} {(shellcheck)}) terminator: ) (Sentence child: (AndOr children: [ (SimpleCommand redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(/dev/null)} spids: [195] ) ] ) (C {(command)} {(-v)} {(jq)}) ] op_id: Op_DAmp ) terminator: ) (Sentence child: (SimpleCommand redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(/dev/null)} spids: [207] ) ] ) terminator: ) ] action: [ (Pipeline children: [ (C {(shellcheck)} {(-f)} {(json)} {(DQ ($ VSub_Name "$file"))}) (C {(jq)} {(-r)} { (SQ < ".[] | \"shellcheck::\" + (if .level == \"info\" then \"advice\" else .level end) + \":\" + (.line | tostring) + \" \" + .message" > ) } ) ] negated: False ) ] spids: [-1 211] ) ] spids: [-1 237] ) ] spids: [178 183 239 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [ (If arms: [ (if_arm cond: [ (Sentence child: (Pipeline children: [ (C {(grep)} {(-q)} {(SQ <"Copyright 201[4-9] Google Inc. All rights reserved.">)} {(DQ ($ VSub_Name "$file"))} ) ] negated: True ) terminator: ) ] action: [ (C {(echo)} {(SQ <"copyright header::error:1 File missing copyright header">)}) ] spids: [-1 263] ) ] spids: [-1 273] ) ] spids: [242 243 275 -1] ) ] spids: [106 110 277] ) (If arms: [ (if_arm cond: [ (Sentence child: (SimpleCommand words: [{(grep)} {(-q)} {(Lit_Other "[") (A-Z) (Lit_Other "]")}] redirects: [ (Redir op_id: Redir_TLess fd: -1 arg_word: {(DQ ($ VSub_Name "$dir"))} spids: [293] ) ] ) terminator: ) ] action: [ (C {(echo)} { (DQ ("case-insensitivity::error:1 ") ($ VSub_Name "$dir") (" directory contains an uppercase letter") ) } ) ] spids: [-1 299] ) ] spids: [-1 310] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_gt left: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(find)} {(DQ ($ VSub_Name "$dir"))} {(-maxdepth)} {(0)} {(-iname)} {(DQ ($ VSub_Name "$name"))} ) (C {(wc)} {(-l)}) ] negated: False ) ] ) left_token: spids: [316 338] ) } right: {(1)} ) ) terminator: ) ] action: [ (C {(echo)} { (DQ ("case-insensitivity::error:1 ") ($ VSub_Name "$name") (" filename clashes on case-insensitive file systems") ) } ) ] spids: [-1 347] ) ] spids: [-1 358] ) ] )