github.com/swiftstack/proxyfs@v0.0.0-20201223034610-5434d919416e/bin/autodoc (about) 1 #!/usr/bin/env python 2 # Copyright (c) 2015 SwiftStack, Inc. 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 13 # implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 import argparse 18 import os 19 import Queue 20 import sys 21 import threading 22 23 PROJECTS = { 24 'swift': { 25 'root': '/vagrant/swift/doc/', 26 'dir': ['../swift', 'saio'], 27 'container': 'doc', 28 }, 29 'swiftclient': { 30 'root': '/vagrant/python-swiftclient/doc/', 31 'dir': [], 32 'container': 'swiftclient', 33 } 34 } 35 36 parser = argparse.ArgumentParser() 37 parser.add_argument('-r', '--root', default=None, 38 help="the root of the doc tree") 39 parser.add_argument('--dir', action='append', default=[], 40 help="extra dirs to append, if relative path, " 41 "it's relative to the root") 42 parser.add_argument('--container', default=None, 43 help="the swift container into which the " 44 "compiled html will be uploaded") 45 parser.add_argument('project', nargs='?', default='swift', 46 choices=PROJECTS.keys(), 47 help="use defaults for pre-configured projects") 48 49 50 def iter_path_mtime(source_dir): 51 for root, dirs, files in os.walk(source_dir): 52 for filename in files: 53 if filename.rsplit('.', 1)[-1] not in ('rst', 'py'): 54 continue 55 full_path = os.path.join(root, filename) 56 current_mtime = os.path.getmtime(full_path) 57 yield full_path, current_mtime 58 59 60 def watch_changed_files(q, *source_dirs): 61 last_changed_time = {} 62 while True: 63 full_pass_has_changes = False 64 for source_dir in source_dirs: 65 for path, mtime in iter_path_mtime(source_dir): 66 if (path in last_changed_time and 67 last_changed_time[path] < mtime): 68 yield path 69 full_pass_has_changes = True 70 last_changed_time = {} 71 last_changed_time[path] = mtime 72 if not full_pass_has_changes: 73 # sleep for three seconds (or till user hits enter...) 74 try: 75 q.get(timeout=1.0) 76 except Queue.Empty: 77 pass 78 else: 79 yield 'User says path...' 80 81 82 def main(): 83 options = parser.parse_args() 84 if options.root: 85 root = options.root 86 montior_paths = options.dir 87 default_container = 'doc' 88 else: 89 root = PROJECTS[options.project]['root'] 90 montior_paths = PROJECTS[options.project]['dir'] + options.dir 91 default_container = PROJECTS[options.project]['container'] 92 93 container = options.container or default_container 94 source_dir = os.path.join(root, 'source') 95 build_dir = os.path.join(root, 'build/html') 96 extra_dirs = [os.path.join(root, path) for path in montior_paths] 97 98 # intial build 99 rv = os.system('sphinx-build -b html %s %s' % (source_dir, build_dir)) 100 if rv != 0: 101 # bail on build fail 102 return rv 103 os.chdir(build_dir) 104 os.system('swift post %s -r .r:*' % container) 105 print 'uploading...' 106 os.system('swift upload --changed %s . > /dev/null' % container) 107 print 'done...' 108 os.system('swift stat -v %s index.html | grep URL' % container) 109 # we're gunna let the user hit enter to rebuild immediately 110 q = Queue.Queue() 111 112 def get_input(): 113 while True: 114 q.put(raw_input()) 115 continue_thread = threading.Thread(target=get_input) 116 continue_thread.daemon = True 117 continue_thread.start() 118 for filename in watch_changed_files(q, source_dir, *extra_dirs): 119 print '%s has CHANGED!' % filename 120 print 'rebuilding...' 121 os.system('sphinx-build -q -b html %s %s' % (source_dir, build_dir)) 122 print 'uploading...' 123 os.system('swift upload --changed %s . > /dev/null' % container) 124 print 'done...' 125 os.system('swift stat -v %s index.html | grep URL' % container) 126 127 128 if __name__ == "__main__": 129 try: 130 sys.exit(main()) 131 except KeyboardInterrupt: 132 print 'quit.'