Fix crash in tidytool.py when processing non-ASCII Robot file
[integration/test.git] / tools / robot_check / tidytool.py
1 import os
2 import sys
3 import stat
4 import robot.tidy
5
6
7 def Error(FileSpec, Message):
8     global ErrorsReported
9     print "File", FileSpec + ":", Message
10     ErrorsReported = True
11
12
13 def traverse_and_process(DirList, Processor):
14     """Traverse the directory and process all .robot files found"""
15     Stack = []
16     for Dir in DirList:
17         if Dir[-1] == "/":
18             Dir = Dir[:-1]
19         Stack.append(Dir)
20     while len(Stack) > 0:
21         Dir = Stack.pop() + "/"
22         try:
23             List = os.listdir(Dir)
24         except (IOError, OSError), e:
25             Error(Dir, "Directory not accessible: " + str(e))
26             continue
27         for Item in List:
28             Spec = Dir + Item
29             Stat = os.stat(Spec)
30             if stat.S_ISDIR(Stat.st_mode):
31                 Stack.append(Spec)
32             elif Item.endswith(".robot"):
33                 Processor(Spec)
34
35
36 def check_quietly(FileSpec):
37     try:
38         Data = open(FileSpec).read()
39     except (IOError, OSError), e:
40         Error(FileSpec, "Not accessible: " + str(e))
41         return
42     try:
43         Data = Data.decode("utf8")
44     except:
45         Error(FileSpec, "Has invalid UTF8 data")
46         return
47     TidyTool = robot.tidy.Tidy()
48     CleanedData = TidyTool.file(FileSpec)
49     if Data != CleanedData:
50         Error(FileSpec, "Found to be untidy")
51
52
53 def check(FileSpec):
54     Index = FileSpec.rfind("/")
55     FileName = FileSpec
56     if Index >= 0:
57         FileName = FileSpec[Index + 1:]
58     sys.stdout.write("  " + FileName + "\r")
59     sys.stdout.flush()
60     check_quietly(FileSpec)
61     sys.stdout.write(" " * (2 + len(FileName)) + "\r")
62
63
64 def tidy(FileSpec):
65     print "Processing file:", FileSpec
66     TidyTool = robot.tidy.Tidy()
67     try:
68         CleanedData = TidyTool.file(FileSpec)
69         CleanedData = CleanedData.encode("utf8")
70         open(FileSpec, "w").write(CleanedData)
71     except (IOError, OSError), e:
72         Error(FileSpec, "Not accessible: " + str(e))
73
74
75 # TODO: Refactor the command line argument parsing to use argparse. Since I
76 #       wanted to just quickly make this tool to get rid of manual robot.tidy
77 #       runs I did not have time to create polished argparse based command
78 #       line argument parsing code. Remember also to update the convenience
79 #       scripts.
80
81
82 def usage():
83     print "Usage:\ttidytool.py <command>k <dir1> [<dir2> <dir3> ...]"
84     print
85     print "where <command> is one of these:"
86     print
87     print "check\tCheck that the Robot test data is tidy."
88     print "quiet\tCheck quietly that the Robot test data is tidy."
89     print "tidy\tTidy the Robot test data."
90     print
91     print "The program traverses the specified directories, searching for"
92     print "Robot test data (.robot files) and performing the specified"
93     print "command on them."
94
95
96 if __name__ == "__main__":
97     if len(sys.argv) < 2:
98         usage()
99         raise SystemExit
100     Command = sys.argv[1]
101     DirList = sys.argv[2:]
102     if Command == "check":
103         Processor = check
104     elif Command == "quiet":
105         Processor = check_quietly
106     elif Command == "tidy":
107         Processor = tidy
108     else:
109         print "Unrecognized command:", Command
110         sys.exit(1)
111     ErrorsReported = False
112     traverse_and_process(DirList, Processor)
113     if ErrorsReported:
114         print "tidytool run FAILED !!!"
115         sys.exit(1)