blob: b67cde8f5033eb8d37942d5d2d60499d10ad1769 [file] [log] [blame]
Joe Gregoriobce596b2011-04-05 00:45:40 -04001#!/usr/bin/env python
2#
3# Copyright 2007 Google Inc.
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"""Copy the sources for google-api-python-client into an App Engine project.
18
Joe Gregoriob17c7632011-04-05 01:31:55 -040019Copies the sources of the google-api-python-client
Joe Gregoriobce596b2011-04-05 00:45:40 -040020library into a Google App Engine project. This is necessary so that the
21source can be uploaded when the application is deployed.
Joe Gregoriob17c7632011-04-05 01:31:55 -040022
23 $ enable-app-engine-project [flags] directory
24
Joe Gregoriobce596b2011-04-05 00:45:40 -040025"""
26
27__author__ = 'jcgregorio@google.com (Joe Gregorio)'
28
29import gflags
30import logging
31import sys
32import os
33
34from distutils.dir_util import copy_tree
35from distutils.file_util import copy_file
36from distutils.errors import DistutilsFileError
37
38FLAGS = gflags.FLAGS
39SOURCES = [
40 'gflags',
41 'gflags_validators',
42 'httplib2',
43 'oauth2client',
44 'oauth2',
45 'apiclient',
46 'uritemplate',
47 ]
48
49gflags.DEFINE_enum('logging_level', 'ERROR',
50 ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
51 'Set the level of logging detail.')
52
53gflags.DEFINE_boolean('force', 'False',
54 'Forcibly copy over client library files.')
55
56gflags.DEFINE_boolean('dry_run', 'False', 'Don\'t actually do anything.')
57
58def find_source(module):
Joe Gregoriob17c7632011-04-05 01:31:55 -040059 """Find the absolute path for the source of a module.
60
61 Args:
62 module: str, Name of the module.
63 Returns:
Joe Gregoriobe927fb2011-05-22 23:21:54 -040064 A tuple of (isdir, location), a boolean that's True if
65 the source is a directory, False is it's a file,
66 and the absolute path of the source.
Joe Gregoriob17c7632011-04-05 01:31:55 -040067 """
Joe Gregoriobce596b2011-04-05 00:45:40 -040068 isdir = False
69 location = ''
70 m = __import__(module)
71 logging.debug('Absolute path for module %s: %s' % (module, m.__file__))
72 basename = os.path.basename(m.__file__)
73 if basename.startswith('__init__.'):
74 isdir = True
75 location = os.path.dirname(m.__file__)
76 else:
Joe Gregoriobe927fb2011-05-22 23:21:54 -040077 if os.path.isfile(m.__file__):
78 location = m.__file__.rsplit('.', 1)[0] + '.py'
79 else:
80 # The file is an egg, extract to a temporary location
81 import pkg_resources
82 location = pkg_resources.resource_filename(module, module + '.py')
Joe Gregoriobce596b2011-04-05 00:45:40 -040083
84 return (isdir, location)
85
86def main(argv):
87 # Let the gflags module process the command-line arguments
88 try:
89 argv = FLAGS(argv)
90 except gflags.FlagsError, e:
Joe Gregoriob17c7632011-04-05 01:31:55 -040091 print '%s\nUsage: %s ARGS\n%s' % (e, argv[0], FLAGS)
92 sys.exit(1)
93
94 if len(argv) == 1:
95 print 'Usage: %s ARGS\n%s' % (argv[0], FLAGS)
Joe Gregoriobce596b2011-04-05 00:45:40 -040096 sys.exit(1)
97
98 # Set the logging according to the command-line flag
99 logging.getLogger().setLevel(getattr(logging, FLAGS.logging_level))
100
101 logging.info('Setting up the directories: %s' % argv[1:])
102 for dir in argv[1:]:
103 # Check if the supplied directory is an App Engine project by looking
104 # for an app.yaml
105 if not os.path.isfile(os.path.join(dir, 'app.yaml')):
Joe Gregoriob17c7632011-04-05 01:31:55 -0400106 sys.exit('The given directory is not a Google App Engine project: %s' % dir)
Joe Gregoriobce596b2011-04-05 00:45:40 -0400107
108
109 # Build up the set of file or directory copying actions we need to do
110 action = [] # (src, dst, isdir)
111 for source in SOURCES:
112 isdir, source_location = find_source(source)
113 if isdir:
114 target = source
115 else:
116 target = source + ".py"
117 full_target = os.path.join(dir, target)
118 if not FLAGS.force and os.path.exists(full_target):
119 noun = isdir and 'Directory' or 'File'
120 sys.exit("%s already exists in project: %s" % (noun, target))
121 action.append((source_location, full_target, isdir))
122
123 # Now perform all the copying actions we collected
124 try:
125 for src, dst, isdir in action:
126 if isdir:
127 results = copy_tree(src, dst, FLAGS.dry_run)
128 for filename in results:
Joe Gregoriob17c7632011-04-05 01:31:55 -0400129 print 'Copied: %s' % filename
Joe Gregoriobce596b2011-04-05 00:45:40 -0400130 else:
131 filename, copied = copy_file(src, dst, FLAGS.dry_run)
Joe Gregoriob17c7632011-04-05 01:31:55 -0400132 print 'Copied: %s Successfully: %s' % (filename, copied)
Joe Gregoriobce596b2011-04-05 00:45:40 -0400133 except DistutilsFileError, e:
134 sys.exit(str(e))
135
136if __name__ == '__main__':
137 main(sys.argv)