go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/scripts/check_go_mod_tidy.py (about) 1 #!/usr/bin/env python3 2 # Copyright 2021 The LUCI Authors. 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 16 from __future__ import absolute_import 17 from __future__ import print_function 18 19 import os 20 import shutil 21 import subprocess 22 import sys 23 24 25 # A list of (original file, what to rename it to prior to a check). 26 MOD_FILES = [ 27 ('go.mod', '.go.mod.current'), 28 ('go.sum', '.go.sum.current'), 29 ] 30 31 32 def main(args): 33 if len(args) != 1: 34 print('Want 1 argument: a path to a directory with go.mod') 35 return 1 36 os.chdir(args[0]) 37 38 # Backup existing go.mod and go.sum since we possibly will modify them. 39 for old, new in MOD_FILES: 40 shutil.copyfile(old, new) 41 42 try: 43 # This command modifies go.mod and/or go.sum if they are untidy. There's 44 # currently no way to ask it to check their tidiness without overriding 45 # them. See https://github.com/golang/go/issues/27005. 46 subprocess.check_call(['go', 'mod', 'tidy']) 47 48 # Check the diff, it should be empty. 49 for old, new in MOD_FILES: 50 mod_diff = diff(new, old) 51 if mod_diff: 52 print('%s file is stale:' % old) 53 print(mod_diff) 54 print() 55 print('Run "go mod tidy" to update it.') 56 return 1 57 58 except subprocess.CalledProcessError as exc: 59 print( 60 'Failed to call %s, return code %d:\n%s' % 61 (exc.cmd, exc.returncode, exc.output)) 62 return 2 63 64 finally: 65 for old, new in MOD_FILES: 66 shutil.move(new, old) 67 68 69 def diff(a, b): 70 cmd = ['git', 'diff', '--no-index', a, b] 71 proc = subprocess.Popen( 72 args=cmd, 73 stdout=subprocess.PIPE, 74 stderr=subprocess.PIPE, 75 universal_newlines=True) 76 out, err = proc.communicate() 77 if proc.returncode and err: 78 raise subprocess.CalledProcessError( 79 returncode=proc.returncode, cmd=cmd, output=err) 80 return out.strip() 81 82 83 if __name__ == '__main__': 84 sys.exit(main(sys.argv[1:]))