Skip to content

Commit

Permalink
rework www plugin pkg creation (again)
Browse files Browse the repository at this point in the history
With previous version, the plugins shared "static" directory inside site-package dir!

We create one real module dir per plugin, so that we can use pkg_resource to store
the built js.

This way, we even have bdist_egg working and are ready for py2exe :)

Signed-off-by: Pierre Tardy <pierre.tardy@intel.com>
  • Loading branch information
Pierre Tardy committed Aug 13, 2014
1 parent fa6850a commit b1c961b
Show file tree
Hide file tree
Showing 19 changed files with 123 additions and 148 deletions.
Expand Up @@ -13,29 +13,17 @@
#
# Copyright Buildbot Team Members

import os
import pkg_resources

from twisted.web import static


def sibpath(*elts):
return os.path.join(os.path.dirname(__file__), *elts)


class Application(object):

def __init__(self):
self.description = "Buildbot UI"
# VERSION's location differs depending on whether we're installed
for f in sibpath('VERSION'), sibpath('static', 'VERSION'):
if os.path.exists(f):
self.version = open(f).read().strip()
break
else:
self.version = '<unknown>'
self.static_dir = os.path.abspath(sibpath('static'))
def __init__(self, modulename, description):
self.description = description
self.version = pkg_resources.resource_string(modulename, "/VERSION").strip()
self.static_dir = pkg_resources.resource_filename(modulename, "/static")
self.resource = static.File(self.static_dir)


# create the interface for the setuptools entry point
ep = Application()
def __repr__(self):
return "www.plugin.Application(version={}, description={}, static_dir={})".format(
self.version, self.description, self.static_dir)
20 changes: 16 additions & 4 deletions pkg/buildbot_pkg.py
Expand Up @@ -19,6 +19,7 @@
from distutils.version import LooseVersion
from setuptools import setup
from setuptools.command.egg_info import egg_info
from textwrap import dedent

import os

Expand Down Expand Up @@ -95,16 +96,26 @@ def build_js(cmd):
global js_built
if js_built:
return
package = cmd.distribution.packages[0]
if os.path.exists("gulpfile.js"):
npm_version = check_output("npm -v")
npm_bin = check_output("npm bin").strip()
assert npm_version != "", "need nodejs and npm installed in current PATH"
assert LooseVersion(npm_version) >= LooseVersion("1.4"), "npm < 1.4 (%s)" % (npm_version)
cmd.spawn(['npm', 'install'])
cmd.spawn([os.path.join(npm_bin, "gulp"), 'prod'])
cmd.copy_tree('static', os.path.join("build", "lib", "static"))
cmd.spawn([os.path.join(npm_bin, "gulp"), 'default'])
with open(os.path.join("MANIFEST.in"), "w") as f:
f.write(dedent("""
include %(package)s/VERSION
recursive-include %(package)s/static *
""" % dict(package=package)))

with open(os.path.join("build", "lib", "VERSION"), "w") as f:
cmd.copy_tree(os.path.join(package, 'static'), os.path.join("build", "lib", package, "static"))

with open(os.path.join("build", "lib", package, "VERSION"), "w") as f:
f.write(cmd.distribution.metadata.version)

with open(os.path.join(package, "VERSION"), "w") as f:
f.write(cmd.distribution.metadata.version)

js_built = True
Expand All @@ -127,4 +138,5 @@ def run(self):


def setup_www_plugin(**kw):
setup(version=getVersion("."), cmdclass=cmdclassforjs, **kw)
package = kw['packages'][0]
setup(version=getVersion(os.path.join(package, "__init__.py")), cmdclass=cmdclassforjs, **kw)
61 changes: 47 additions & 14 deletions pkg/test_buildbot_pkg.py
Expand Up @@ -19,53 +19,86 @@
from subprocess import call
from subprocess import check_call
from twisted.trial import unittest
from textwrap import dedent

class BuildbotWWWPkg(unittest.TestCase):
pkgName = "buildbot_www"
pkgPaths = ["www"]
epName = "base"

class BuildbotPkg(unittest.TestCase):
loadTestScript = dedent("""
import pkg_resources
apps = {}
for ep in pkg_resources.iter_entry_points('buildbot.www'):
apps[ep.name] = ep.load()
assert("scripts.js" in apps["%(epName)s"].resource.listNames())
assert(apps["%(epName)s"].version.startswith("0."))
assert(apps["%(epName)s"].description is not None)
print apps["%(epName)s"]
""")
@property
def www(self):
return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "www"))
def path(self):
return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", *self.pkgPaths))

def rmtree(self, d):
if os.path.isdir(d):
shutil.rmtree(d)

def setUp(self):
call("pip uninstall -y buildbot_www", shell=True)
self.rmtree(os.path.join(self.www, "build"))
self.rmtree(os.path.join(self.www, "dist"))
self.rmtree(os.path.join(self.www, "static"))
call("pip uninstall -y " + self.pkgName, shell=True)
self.rmtree(os.path.join(self.path, "build"))
self.rmtree(os.path.join(self.path, "dist"))
self.rmtree(os.path.join(self.path, "static"))

def run_setup(self, cmd):
check_call("python setup.py " + cmd, shell=True, cwd=self.www)
check_call("python setup.py " + cmd, shell=True, cwd=self.path)

def check_correct_installation(self):
# assert we can import buildbot_www
# and that it has an endpoint with resource containing file "script.js"
check_call([
'python', '-c',
'import buildbot_www;' # no comma
'assert("scripts.js" in buildbot_www.ep.resource.listNames())'])
'python', '-c', self.loadTestScript % dict(epName=self.epName)])

def test_install(self):
self.run_setup("install")
self.check_correct_installation()

def test_wheel(self):
self.run_setup("bdist_wheel")
check_call("pip install dist/*.whl", shell=True, cwd=self.www)
check_call("pip install dist/*.whl", shell=True, cwd=self.path)
self.check_correct_installation()

def test_egg(self):
self.run_setup("bdist_egg")
# egg installation is not supported by pip, so we use easy_install
check_call("easy_install dist/*.egg", shell=True, cwd=self.path)
self.check_correct_installation()

def test_develop(self):
self.run_setup("develop")
self.check_correct_installation()

def test_develop_via_pip(self):
check_call("pip install -e .", shell=True, cwd=self.www)
check_call("pip install -e .", shell=True, cwd=self.path)
self.check_correct_installation()

def test_sdist(self):
self.run_setup("sdist")
check_call("pip install dist/*.tar.gz", shell=True, cwd=self.www)
check_call("pip install dist/*.tar.gz", shell=True, cwd=self.path)
self.check_correct_installation()

class BuildbotConsolePkg(BuildbotWWWPkg):
pkgName = "buildbot-console-view"
pkgPaths = ["www", "console_view"]
epName = "console_view"

class BuildbotWaterfallPkg(BuildbotWWWPkg):
pkgName = "buildbot-waterfall-view"
pkgPaths = ["www", "waterfall_view"]
epName = "waterfall_view"

class BuildbotCodeparameterPkg(BuildbotWWWPkg):
pkgName = "buildbot-codeparameter"
pkgPaths = ["www", "codeparameter"]
epName = "codeparameter"
1 change: 1 addition & 0 deletions www/.gitignore
@@ -1,3 +1,4 @@
MANIFEST.in
build
!src/app/builders/build
dist/
Expand Down
2 changes: 0 additions & 2 deletions www/MANIFEST.in

This file was deleted.

26 changes: 2 additions & 24 deletions www/buildbot_www.py → www/buildbot_www/__init__.py
Expand Up @@ -13,29 +13,7 @@
#
# Copyright Buildbot Team Members

import os

from twisted.web import static


def sibpath(*elts):
return os.path.join(os.path.dirname(__file__), *elts)


class Application(object):

def __init__(self):
self.description = "Buildbot UI"
# VERSION's location differs depending on whether we're installed
for f in sibpath('VERSION'), sibpath('static', 'VERSION'):
if os.path.exists(f):
self.version = open(f).read().strip()
break
else:
self.version = '<unknown>'
self.static_dir = os.path.abspath(sibpath('static'))
self.resource = static.File(self.static_dir)

from buildbot.www.plugin import Application

# create the interface for the setuptools entry point
ep = Application()
ep = Application(__name__, "Buildbot UI")
2 changes: 0 additions & 2 deletions www/codeparameter/MANIFEST.in

This file was deleted.

51 changes: 0 additions & 51 deletions www/codeparameter/buildbot_codeparameter.py

This file was deleted.

Expand Up @@ -13,29 +13,7 @@
#
# Copyright Buildbot Team Members

import os

from twisted.web import static


def sibpath(*elts):
return os.path.join(os.path.dirname(__file__), *elts)


class Application(object):

def __init__(self):
self.description = "Buildbot UI"
# VERSION's location differs depending on whether we're installed
for f in sibpath('VERSION'), sibpath('static', 'VERSION'):
if os.path.exists(f):
self.version = open(f).read().strip()
break
else:
self.version = '<unknown>'
self.static_dir = os.path.abspath(sibpath('static'))
self.resource = static.File(self.static_dir)

from buildbot.www.plugin import Application

# create the interface for the setuptools entry point
ep = Application()
ep = Application(__name__, "Buildbot forcescheduler parameter using ace.js to submit code")
4 changes: 2 additions & 2 deletions www/codeparameter/guanlecoja/config.coffee
Expand Up @@ -17,14 +17,14 @@ module.exports =
# Name of the plugin
### ###########################################################################################
name: 'codeparameter'
plugin: true


### ###########################################################################################
# Directories
### ###########################################################################################
dir:
# The build folder is where the app resides once it's completely built
build: 'static'
build: 'buildbot_codeparameter/static'

### ###########################################################################################
# Bower dependancies configuration
Expand Down
2 changes: 1 addition & 1 deletion www/codeparameter/setup.py
Expand Up @@ -29,7 +29,7 @@
author_email=u'tardyp@gmail.com',
url='http://buildbot.net/',
license='GNU GPL',
py_modules=['buildbot_www'],
packages=['buildbot_codeparameter'],
entry_points="""
[buildbot.www]
codeparameter = buildbot_codeparameter:ep
Expand Down
19 changes: 19 additions & 0 deletions www/console_view/buildbot_console_view/__init__.py
@@ -0,0 +1,19 @@
# This file is part of Buildbot. Buildbot is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright Buildbot Team Members

from buildbot.www.plugin import Application

# create the interface for the setuptools entry point
ep = Application(__name__, "Buildbot Console View UI")
1 change: 1 addition & 0 deletions www/console_view/guanlecoja/config.coffee
Expand Up @@ -10,6 +10,7 @@ module.exports =
# Name of the plugin
### ###########################################################################################
name: 'console_view'
dir: build: 'buildbot_console_view/static'
bower:
testdeps:
"guanlecoja-ui":
Expand Down
2 changes: 1 addition & 1 deletion www/console_view/setup.py
Expand Up @@ -29,7 +29,7 @@
author_email=u'tardyp@gmail.com',
url='http://buildbot.net/',
license='GNU GPL',
py_modules=['buildbot_www'],
packages=['buildbot_console_view'],
entry_points="""
[buildbot.www]
console_view = buildbot_console_view:ep
Expand Down
2 changes: 1 addition & 1 deletion www/guanlecoja/config.coffee
Expand Up @@ -21,7 +21,7 @@ config =
### ###########################################################################################
dir:
# The build folder is where the app resides once it's completely built
build: 'static'
build: 'buildbot_www/static'

### ###########################################################################################
# Bower dependancies configuration
Expand Down
2 changes: 1 addition & 1 deletion www/setup.py
Expand Up @@ -29,7 +29,7 @@
author_email=u'tardyp@gmail.com',
url='http://buildbot.net/',
license='GNU GPL',
py_modules=['buildbot_www'],
packages=['buildbot_www'],
entry_points="""
[buildbot.www]
base = buildbot_www:ep
Expand Down

0 comments on commit b1c961b

Please sign in to comment.