2010年2月21日日曜日

自作commandクラスをロードする step(2)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
setup.pyから相対パスでcommandクラスを実装したファイルをロードできるようにします。
def get_command_class (self, command):
        """Return the class that implements the Distutils command named by
        'command'.  First we check the 'cmdclass' dictionary; if the
        command is mentioned there, we fetch the class object from the
        dictionary and return it.  Otherwise we load the command module
        ("distutils.command." + command) and fetch the command class from
        the module.  The loaded class is also stored in 'cmdclass'
        to speed future calls to 'get_command_class()'.

        Raises DistutilsModuleError if the expected module could not be
        found, or if that module does not define the expected class.
        """
        klass = self.cmdclass.get(command)
        if klass:
            return klass

        for pkgname in self.get_command_packages():
            module_name = "%s.%s" % (pkgname, command)
            klass_name = command

            try:
                __import__ (module_name)
                module = sys.modules[module_name]
            except ImportError:
                continue

            try:
                klass = getattr(module, klass_name)
            except AttributeError:
                raise DistutilsModuleError, \
                      "invalid command '%s' (no class '%s' in module '%s')" \
                      % (command, klass_name, module_name)

            self.cmdclass[command] = klass
            return klass

        raise DistutilsModuleError("invalid command '%s'" % command)
cmdclassは辞書で、setupの引数で渡すことができます。
from distutils.cmd import Command
class build_js(Command):
  def initialize_options(self):
    pass
  def  finalize_options(self):
    pass
  def run(self):
    print 'build_js is here!'

setup(
  ...
  cmdclass={'build_js':build_js},
  ...
)
前のエントリに加えてこのようにしてやると、次の実行結果を得られます。
[nori@shinano]~/Desktop/study/JavaScript/closure-proj% python setup.py build
running build
build:has_js
Distribution:has_js
running build_js
build_js is here!

build_js.pyとしてまとめるとこのようになる。
#!/usr/bin/env python
# -*- coding: us-ascii -*-
# vim: syntax=python
#
# Copyright 2010 Noriyuki Hosaka bgnori@gmail.com
#


import calcdeps 


def jscompile(inputs, search_paths, output, compiler_jar, compiler_flags):
  import logging
  import os
  import os.path
  cwd = os.getcwd()
  output = os.path.join(cwd, output)
  inputs = [os.path.join(cwd, f) for f in inputs]

  logging.basicConfig(format='calcdeps.py: %(message)s', level=logging.INFO)
  logging.info('Scanning files...')
  logging.info('cwd: %s'%(os.getcwd(),))
  logging.info('search_paths: %s'%(search_paths,))
  search_paths = calcdeps.ExpandDirectories(search_paths)
  #logging.info('expanded paths: %s'%(search_paths,))
  out = open(output, 'w')
  logging.info('Finding Closure dependencies...')
  deps = calcdeps.CalculateDependencies(search_paths, inputs)

  calcdeps.Compile(compiler_jar, deps, out, compiler_flags)
  return output

the_args = {}

from distutils.cmd import Command
class build_js(Command):
  def initialize_options(self):
    pass
  def  finalize_options(self):
    print dir(self)
  def run(self):
    print the_args
    jscompile(**the_args)
def CompiledJS(**attr):
  the_args.update(attr)
  return [True] #place holder

def blackmagic(Distribution, build):
  def xxx(self):
    print 'Distribution:has_js'
    return self.js and len(self.js) > 0
  Distribution.has_js = xxx

  def yyy(self):
    print 'build:has_js'
    return self.distribution.has_js() 
  build.has_js = yyy
  build.sub_commands.append( ('build_js', build.has_js),)

  orig = Distribution.__init__
  def myinit(self, attrs):
    self.js = None
    orig(self, attrs)
  Distribution.__init__ = myinit

setup.pyでこのように呼んであげる。
from build_js import build_js
from build_js import blackmagic
from build_js import CompiledJS

from distutils.dist import Distribution
from distutils.command.build import build

blackmagic(Distribution, build)
setup()の引数。
js=CompiledJS(
    inputs=['src/notepad.js'],
    search_paths=['/home/nori/lib/closure/'],
    output='static/notepad.c.js',
    compiler_jar='/home/nori/bin/closure/compiler.jar',
    compiler_flags=['ADVANCED_OPTIMIZATION'],
  ),
bdist_rpmするとコンパイルして生成したjsファイルがパッケージに含まれない問題があるので、明日はそれに対処したいと思います。

0 件のコメント: