Home | History | Annotate | Download | only in upstream
      1 #!/usr/bin/python
      2 #
      3 # Copyright (C) 2017 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 
     17 """
     18 Compares one or more corresponding files from ojluni against one or
     19 more upstream or from upstreams against each other.
     20 The repositories (default: ojluni vs. expected current upstream) and
     21 the diff tool (default: meld) can be specified by command line options.
     22 
     23 This tool is for libcore maintenance; if you're not maintaining libcore,
     24 you won't need it (and might not have access to some of the instructions
     25 below).
     26 
     27 The naming of the repositories (expected, ojluni, 7u40, 8u121-b13,
     28 9b113+, 9+181) is based on the directory name where corresponding
     29 snapshots are stored when following the instructions at
     30 http://go/libcore-o-verify
     31 
     32 This in turn derives from the instructions at the top of:
     33 libcore/tools/upstream/src/main/java/libcore/CompareUpstreams.java
     34 
     35 Possible uses:
     36 
     37 To verify that ArrayList has been updated to the expected upstream
     38 and that all local patches carry change markers, we compare that
     39 file from ojluni against the expected upstream (the default):
     40   upstream-diff java/util/ArrayList.java
     41 
     42 To verify multiple files:
     43 
     44   upstream-diff java.util.ArrayList java.util.LinkedList
     45 
     46 Use a three-way merge to integrate changes from 9+181 into ArrayList:
     47   upstream-diff -r 8u121-b13,ojluni,9+181 java/util/ArrayList.java
     48 or to investigate which version of upstream introduced a change:
     49   upstream-diff -r 7u40,8u60,8u121-b13 java/util/ArrayList.java
     50 """
     51 
     52 import argparse
     53 import os
     54 import subprocess
     55 import sys
     56 
     57 def run_diff(diff, repositories, rel_paths):
     58     # Root of checked-out Android sources, set by the "lunch" command.
     59     android_build_top = os.environ['ANDROID_BUILD_TOP']
     60     # Root of repository snapshots. See go/libcore-o-verify for how you'd want to set this.
     61     ojluni_upstreams = os.environ['OJLUNI_UPSTREAMS']
     62     for rel_path in rel_paths:
     63         if not rel_path.endswith('.java'):
     64             # Might be a fully qualified class name
     65             rel_path = rel_path.replace('.', '/') + '.java'
     66         paths = []
     67         for repository in repositories:
     68             if repository == "ojluni":
     69                 paths.append('%s/libcore/ojluni/src/main/java/%s' % (android_build_top, rel_path))
     70             else:
     71                 paths.append('%s/%s/%s' % (ojluni_upstreams, repository, rel_path))
     72         subprocess.call([diff] + paths)
     73 
     74 def main():
     75     parser = argparse.ArgumentParser(
     76         description='Compare files between libcore/ojluni and ${OJLUNI_UPSTREAMS}.')
     77     parser.add_argument('-r', '--repositories', default='ojluni,expected',
     78                     help='Comma-separated list of >= 2 repositories to compare.')
     79     parser.add_argument('-d', '--diff', default='meld',
     80                         help='Application to use for diffing.')
     81     parser.add_argument('rel_path', nargs="+",
     82                         help='File to compare: either a relative path below '
     83                              'libcore/ojluni/src/main/java, or a fully qualified class name.')
     84     args = parser.parse_args()
     85     repositories = args.repositories.split(',')
     86     if (len(repositories) < 2):
     87         print('Expected >= 2 repositories to compare, got: ' + str(repositories))
     88         parser.print_help()
     89         sys.exit(1)
     90     run_diff(args.diff, repositories, args.rel_path)
     91 
     92 if __name__ == "__main__":
     93     main()
     94 
     95