blob: e2f2a357330708810cde465ace7cfe061b200088 [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
Joe Gregoriod667c9d2011-10-17 13:25:24 -040033import pkg_resources
Joe Gregoriobce596b2011-04-05 00:45:40 -040034
35from distutils.dir_util import copy_tree
36from distutils.file_util import copy_file
37from distutils.errors import DistutilsFileError
38
39FLAGS = gflags.FLAGS
40SOURCES = [
41 'gflags',
42 'gflags_validators',
43 'httplib2',
44 'oauth2client',
45 'oauth2',
46 'apiclient',
47 'uritemplate',
48 ]
49
50gflags.DEFINE_enum('logging_level', 'ERROR',
51 ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
52 'Set the level of logging detail.')
53
54gflags.DEFINE_boolean('force', 'False',
55 'Forcibly copy over client library files.')
56
57gflags.DEFINE_boolean('dry_run', 'False', 'Don\'t actually do anything.')
58
59def find_source(module):
Joe Gregoriob17c7632011-04-05 01:31:55 -040060 """Find the absolute path for the source of a module.
61
62 Args:
63 module: str, Name of the module.
64 Returns:
Joe Gregoriobe927fb2011-05-22 23:21:54 -040065 A tuple of (isdir, location), a boolean that's True if
66 the source is a directory, False is it's a file,
67 and the absolute path of the source.
Joe Gregoriob17c7632011-04-05 01:31:55 -040068 """
Joe Gregoriobce596b2011-04-05 00:45:40 -040069 isdir = False
70 location = ''
71 m = __import__(module)
72 logging.debug('Absolute path for module %s: %s' % (module, m.__file__))
73 basename = os.path.basename(m.__file__)
74 if basename.startswith('__init__.'):
75 isdir = True
Joe Gregoriod667c9d2011-10-17 13:25:24 -040076 location = os.path.dirname(
77 pkg_resources.resource_filename(module, '__init__.py'))
Joe Gregoriobce596b2011-04-05 00:45:40 -040078 else:
Joe Gregoriobe927fb2011-05-22 23:21:54 -040079 if os.path.isfile(m.__file__):
80 location = m.__file__.rsplit('.', 1)[0] + '.py'
81 else:
82 # The file is an egg, extract to a temporary location
Joe Gregoriobe927fb2011-05-22 23:21:54 -040083 location = pkg_resources.resource_filename(module, module + '.py')
Joe Gregoriobce596b2011-04-05 00:45:40 -040084
85 return (isdir, location)
86
87def main(argv):
88 # Let the gflags module process the command-line arguments
89 try:
90 argv = FLAGS(argv)
91 except gflags.FlagsError, e:
Joe Gregoriob17c7632011-04-05 01:31:55 -040092 print '%s\nUsage: %s ARGS\n%s' % (e, argv[0], FLAGS)
93 sys.exit(1)
94
95 if len(argv) == 1:
96 print 'Usage: %s ARGS\n%s' % (argv[0], FLAGS)
Joe Gregoriobce596b2011-04-05 00:45:40 -040097 sys.exit(1)
98
99 # Set the logging according to the command-line flag
100 logging.getLogger().setLevel(getattr(logging, FLAGS.logging_level))
101
102 logging.info('Setting up the directories: %s' % argv[1:])
103 for dir in argv[1:]:
104 # Check if the supplied directory is an App Engine project by looking
105 # for an app.yaml
106 if not os.path.isfile(os.path.join(dir, 'app.yaml')):
Joe Gregoriod667c9d2011-10-17 13:25:24 -0400107 sys.exit('The given directory is not a Google App Engine project: %s' %
108 dir)
Joe Gregoriobce596b2011-04-05 00:45:40 -0400109
110 # Build up the set of file or directory copying actions we need to do
111 action = [] # (src, dst, isdir)
112 for source in SOURCES:
113 isdir, source_location = find_source(source)
114 if isdir:
115 target = source
116 else:
117 target = source + ".py"
118 full_target = os.path.join(dir, target)
119 if not FLAGS.force and os.path.exists(full_target):
120 noun = isdir and 'Directory' or 'File'
121 sys.exit("%s already exists in project: %s" % (noun, target))
122 action.append((source_location, full_target, isdir))
123
124 # Now perform all the copying actions we collected
125 try:
126 for src, dst, isdir in action:
127 if isdir:
128 results = copy_tree(src, dst, FLAGS.dry_run)
129 for filename in results:
Joe Gregoriob17c7632011-04-05 01:31:55 -0400130 print 'Copied: %s' % filename
Joe Gregoriobce596b2011-04-05 00:45:40 -0400131 else:
132 filename, copied = copy_file(src, dst, FLAGS.dry_run)
Joe Gregoriob17c7632011-04-05 01:31:55 -0400133 print 'Copied: %s Successfully: %s' % (filename, copied)
Joe Gregoriobce596b2011-04-05 00:45:40 -0400134 except DistutilsFileError, e:
135 sys.exit(str(e))
136
137if __name__ == '__main__':
138 main(sys.argv)