40 Commits

Author SHA1 Message Date
Kenneth Reitz a484f9b693 pythons 2012-02-26 13:20:33 -05:00
Kenneth Reitz 706d8b4327 yeah 2012-02-26 13:18:08 -05:00
Kenneth Reitz 17b811865c mission statement 2012-02-26 13:17:50 -05:00
utahta ea7cb63494 v1.1 2011-08-29 18:01:31 +09:00
utahta e7943488de release 1.0 2011-08-08 03:09:42 +09:00
utahta 630d525f6a 0.10 -> 1.0 2011-08-08 03:04:42 +09:00
utahta 770715b536 release 0.10 2011-08-08 02:51:43 +09:00
utahta 0112a39aff update 2011-08-08 02:45:29 +09:00
utahta df91a87b24 update 0.10 2011-08-08 02:44:08 +09:00
utahta 212460fd6d update 2011-08-07 15:56:04 +09:00
utahta bfdccb5051 improve venv 2011-08-07 15:36:46 +09:00
utahta bc219fcebe bug fix 2011-08-07 12:58:54 +09:00
utahta 4993f466e9 add systemwide install support 2011-08-07 03:48:38 +09:00
utahta 7b2fa2f0eb Improve symlink command 2011-08-07 00:39:13 +09:00
utahta 90face7065 bug fix 2011-08-07 00:11:23 +09:00
utahta 4ef2954bd6 bug fix 2011-08-07 00:08:37 +09:00
utahta 1025529528 update readme 2011-08-06 23:58:47 +09:00
utahta 04f4cd15b3 Improve venv command, log and bashrc 2011-08-06 23:56:31 +09:00
utahta 7bdb546fa4 merge develop 2011-07-23 18:00:04 +09:00
utahta 12b392a98c fixed #34 #35 2011-07-23 16:31:37 +09:00
utahta 2eb3b7509f merge #33 2011-07-23 12:19:41 +09:00
utahta b6abb47bc3 cleanup 2011-07-23 12:12:30 +09:00
Chris Ledet 483b49984c updated README with corrected rst syntax 2011-07-22 07:35:05 -07:00
Chris Ledet 704321f040 updated README 2011-07-22 10:34:00 -04:00
utahta 07828a266d update 2011-07-22 18:38:20 +09:00
utahta 9fbc3273cf update venv command 2011-07-22 01:56:01 +09:00
utahta 4aa62201c7 update venv command 2011-07-21 02:22:00 +09:00
utahta b4a6674fba Added venv command 2011-07-21 02:14:41 +09:00
utahta ef4ff75630 update 2011-07-20 00:08:01 +09:00
utahta 219ad17459 update 2011-07-19 23:17:29 +09:00
utahta b039caf384 Merge branch 'develop' of github.com:utahta/pythonbrew into develop 2011-07-18 22:31:34 +09:00
utahta 1db87055fd Added buildout command 2011-07-18 22:31:13 +09:00
utahta aec7d769b1 bug fix 2011-07-11 19:03:37 +09:00
utahta f09e32372d update 2011-07-11 00:01:20 +09:00
utahta 2469c1a7af update 2011-07-10 21:17:05 +09:00
utahta f9bcb60638 update readme 2011-07-10 20:51:27 +09:00
utahta 6cb6cc6057 update 0.8 2011-07-10 20:49:00 +09:00
utahta f410b1d1d8 update 2011-07-08 19:25:18 +09:00
utahta 8a1032b08c #21 support ubuntu 11.04(Natty) 2011-07-07 20:39:19 +09:00
utahta 87d0d7b52f #21 support ubuntu 11.04(Natty) 2011-07-07 19:37:30 +09:00
47 changed files with 846 additions and 488 deletions
+1
View File
@@ -9,3 +9,4 @@ pythonbrew.egg-info
dist dist
__pycache__ __pycache__
*.swp *.swp
.idea
+8
View File
@@ -1,3 +1,11 @@
* 1.1
- Added --framework, --universal and --static options to install command.
* 1.0
- Added systemwide install support. (issue #31)
- Fixed issue #41 Handle venv binary with the symlink command.
- Improved `venv` command (without virtualenvwrapper)
* 0.9 * 0.9
- Added `buildout` command. - Added `buildout` command.
- Added `venv` command. - Added `venv` command.
+56 -24
View File
@@ -12,7 +12,11 @@ The recommended way to download and install pythonbrew is to run these statement
curl -kL http://xrl.us/pythonbrewinstall | bash curl -kL http://xrl.us/pythonbrewinstall | bash
After that, pythonbrew installs itself to ~/.pythonbrew, and you should follow the instruction on screen to setup your .bashrc to put it in your PATH. After that, pythonbrew installs itself to ~/.pythonbrew.
Please add the following line to the end of your ~/.bashrc::
[[ -s $HOME/.pythonbrew/etc/bashrc ]] && source $HOME/.pythonbrew/etc/bashrc
If you need to install pythonbrew into somewhere else, you can do that by setting a PYTHONBREW_ROOT environment variable:: If you need to install pythonbrew into somewhere else, you can do that by setting a PYTHONBREW_ROOT environment variable::
@@ -21,6 +25,17 @@ If you need to install pythonbrew into somewhere else, you can do that by settin
chmod +x pythonbrewinstall chmod +x pythonbrewinstall
./pythonbrewinstall ./pythonbrewinstall
For Systemwide(Multi-User) installation
---------------------------------------
If the install script is run as root, pythonbrew will automatically install into /usr/local/pythonbrew.
The pythonbrew will be automatically configured for every user on the system if you install as root.
After installation, where you would normally use `sudo`, non-root users will need to use `sudopybrew`::
sudopybrew install -n -v -j2 2.7.2
Usage Usage
===== =====
@@ -87,14 +102,16 @@ Create/Remove a symbolic link to python (in a directory on your $PATH)::
pythonbrew symlink -p 2.7.2 pythonbrew symlink -p 2.7.2
pythonbrew symlink pip # Create a symbolic link to the specified script in bin directory pythonbrew symlink pip # Create a symbolic link to the specified script in bin directory
pythonbrew symlink -r # Remove a symbolic link pythonbrew symlink -r # Remove a symbolic link
pythonbrew symlink -v foo # Create a symbolic link to the specified virtual environment python in bin directory
Runs the buildout with specified or current using python:: Runs the buildout with specified or current using python::
pythonbrew buildout pythonbrew buildout
pythonbrew buildout -p 2.6.6 pythonbrew buildout -p 2.6.6
Create isolated python environments:: Create isolated python environments (uses virtualenv)::
pythonbrew venv init
pythonbrew venv create proj pythonbrew venv create proj
pythonbrew venv list pythonbrew venv list
pythonbrew venv use proj pythonbrew venv use proj
@@ -145,35 +162,50 @@ buildout
Runs the buildout with specified or current using python. Runs the buildout with specified or current using python.
venv venv
Create isolated python environments. Create isolated python environments (uses virtualenv)
version version
Show version. Show version.
See more details below: See more details below
pythonbrew help <command> `pythonbrew help <command>`
LICENCE Changelog
======= =========
The MIT License 1.1 (2011-08-29)
----------------
Copyright (c) <2010-2011> <utahta> - Added --framework, --universal and --static options to install command.
Permission is hereby granted, free of charge, to any person obtaining a copy 1.0 (2011-08-08)
of this software and associated documentation files (the "Software"), to deal ----------------
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in - Added systemwide install support. (issue #31)
all copies or substantial portions of the Software. - Fixed issue #41 Handle venv binary with the symlink command.
- Improved `venv` command (without virtualenvwrapper)
0.9 (2011-07-21)
----------------
- Added `venv` command (uses virtualenv and virtualenvwrapper)
- Added `buildout` command.
0.8 (2011-07-10)
----------------
- Fixed issue #21 Added Ubuntu 11.04(Natty) support
- Fixed issue #24 non-framework python27 now defines environ properly. Thanks npinto.
- Fixed issue #27 Cleanup of OS X python build flags
- Fixed issue #28 Describe the 'symlink' command better. Thanks tgs.
- Fixed issue #30 py command does not accept arguments with a space
- Fixed bug: `pythonbrew off` need not have removed the symlink in bin directory
- Added --no-test option to the install command
- Added --verbose option to the install command
- `pythonbrew clean` has been removed. Added `pythonbrew cleanup` instead.
More
----
see the `pythonbrew/Changelog <https://github.com/utahta/pythonbrew/blob/master/ChangeLog>`_
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+32 -5
View File
@@ -1,6 +1,16 @@
Overview Overview
======== ========
Pythonbrew is anti-virtualenv. This isn't.
Differences:
- No `switch`. That's crazy.
- Bottles (pre-compiled Pythons)
----------------------------------
pythonbrew is a program to automate the building and installation of Python in the users $HOME. pythonbrew is a program to automate the building and installation of Python in the users $HOME.
pythonbrew is inspired by `perlbrew <http://github.com/gugod/App-perlbrew>`_ and `rvm <https://github.com/wayneeseguin/rvm>`_. pythonbrew is inspired by `perlbrew <http://github.com/gugod/App-perlbrew>`_ and `rvm <https://github.com/wayneeseguin/rvm>`_.
@@ -12,7 +22,11 @@ The recommended way to download and install pythonbrew is to run these statement
curl -kL http://xrl.us/pythonbrewinstall | bash curl -kL http://xrl.us/pythonbrewinstall | bash
After that, pythonbrew installs itself to ~/.pythonbrew, and you should follow the instruction on screen to setup your .bashrc to put it in your PATH. After that, pythonbrew installs itself to ~/.pythonbrew.
Please add the following line to the end of your ~/.bashrc::
[[ -s $HOME/.pythonbrew/etc/bashrc ]] && source $HOME/.pythonbrew/etc/bashrc
If you need to install pythonbrew into somewhere else, you can do that by setting a PYTHONBREW_ROOT environment variable:: If you need to install pythonbrew into somewhere else, you can do that by setting a PYTHONBREW_ROOT environment variable::
@@ -21,6 +35,17 @@ If you need to install pythonbrew into somewhere else, you can do that by settin
chmod +x pythonbrewinstall chmod +x pythonbrewinstall
./pythonbrewinstall ./pythonbrewinstall
For Systemwide(Multi-User) installation
---------------------------------------
If the install script is run as root, pythonbrew will automatically install into /usr/local/pythonbrew.
The pythonbrew will be automatically configured for every user on the system if you install as root.
After installation, where you would normally use `sudo`, non-root users will need to use `sudopybrew`::
sudopybrew install -n -v -j2 2.7.2
Usage Usage
===== =====
@@ -87,14 +112,16 @@ Create/Remove a symbolic link to python (in a directory on your $PATH)::
pythonbrew symlink -p 2.7.2 pythonbrew symlink -p 2.7.2
pythonbrew symlink pip # Create a symbolic link to the specified script in bin directory pythonbrew symlink pip # Create a symbolic link to the specified script in bin directory
pythonbrew symlink -r # Remove a symbolic link pythonbrew symlink -r # Remove a symbolic link
pythonbrew symlink -v foo # Create a symbolic link to the specified virtual environment python in bin directory
Runs the buildout with specified or current using python:: Runs the buildout with specified or current using python::
pythonbrew buildout pythonbrew buildout
pythonbrew buildout -p 2.6.6 pythonbrew buildout -p 2.6.6
Create isolated python environments:: Create isolated python environments (uses virtualenv)::
pythonbrew venv init
pythonbrew venv create proj pythonbrew venv create proj
pythonbrew venv list pythonbrew venv list
pythonbrew venv use proj pythonbrew venv use proj
@@ -145,13 +172,13 @@ buildout
Runs the buildout with specified or current using python. Runs the buildout with specified or current using python.
venv venv
Create isolated python environments. Create isolated python environments (uses virtualenv)
version version
Show version. Show version.
See more details below: See more details below
pythonbrew help <command> `pythonbrew help <command>`
LICENCE LICENCE
======= =======
+17 -6
View File
@@ -66,16 +66,23 @@ if [[ $PYTHON_FOUND != '1' ]] ; then
exit exit
fi fi
ROOT="$HOME/.pythonbrew" systemwide_install=0
if [[ -n $PYTHONBREW_ROOT ]] ; then if [[ -n "$PYTHONBREW_ROOT" ]] ; then
ROOT=$PYTHONBREW_ROOT ROOT="$PYTHONBREW_ROOT"
else
if (( UID == 0 )) ; then
systemwide_install=1
ROOT="/usr/local/pythonbrew"
else
ROOT="$HOME/.pythonbrew"
fi
fi fi
PATH_DISTS="$ROOT/dists" PATH_DISTS="$ROOT/dists"
STABLE_VERSION=`curl -skL https://github.com/utahta/pythonbrew/raw/master/stable-version.txt` STABLE_VERSION=`curl -skL https://github.com/utahta/pythonbrew/raw/master/stable-version.txt`
STABLE_VERSION=`trim $STABLE_VERSION` STABLE_VERSION=`trim $STABLE_VERSION`
if [[ $STABLE_VERSION = "" ]] ; then if [[ -z "$STABLE_VERSION" ]] ; then
echo 'Could not get stable-version of pythonbrew.' echo 'Can not get stable-version of pythonbrew.'
exit 1 exit 1
fi fi
TEMP_FILE="pythonbrew-$STABLE_VERSION" TEMP_FILE="pythonbrew-$STABLE_VERSION"
@@ -93,7 +100,11 @@ echo "Extracting $PATH_DISTS/$TEMP_TARBALL"
builtin cd $PATH_DISTS ; tar zxf $TEMP_TARBALL builtin cd $PATH_DISTS ; tar zxf $TEMP_TARBALL
echo "Installing pythonbrew into $ROOT" echo "Installing pythonbrew into $ROOT"
$PYTHON $PATH_DISTS/$TEMP_FILE/pythonbrew_install.py if (( systemwide_install == 1 )) ; then
PYTHONBREW_ROOT="$ROOT" $PYTHON $PATH_DISTS/$TEMP_FILE/pythonbrew_install.py --systemwide
else
$PYTHON $PATH_DISTS/$TEMP_FILE/pythonbrew_install.py
fi
if [[ $? == 1 ]] ; then if [[ $? == 1 ]] ; then
echo "Failed to install pythonbrew." echo "Failed to install pythonbrew."
exit exit
+8 -4
View File
@@ -1,7 +1,14 @@
import sys import sys
import os
from pythonbrew.basecommand import command_dict, load_all_commands from pythonbrew.basecommand import command_dict, load_all_commands
from pythonbrew.baseparser import parser from pythonbrew.baseparser import parser
from pythonbrew.log import logger from pythonbrew.log import logger
from pythonbrew.define import PATH_HOME_ETC
from pythonbrew.util import makedirs
def init_home():
if not os.path.isdir(PATH_HOME_ETC):
makedirs(PATH_HOME_ETC)
def main(): def main():
options, args = parser.parse_args(sys.argv[1:]) options, args = parser.parse_args(sys.argv[1:])
@@ -10,13 +17,10 @@ def main():
if not args: if not args:
args = ['help'] # as default args = ['help'] # as default
init_home()
load_all_commands() load_all_commands()
command = args[0].lower() command = args[0].lower()
if command not in command_dict: if command not in command_dict:
if command == 'clean':
# note: for some time
logger.info('\nDEPRECATION WARNING: `pythonbrew clean` has been renamed. Please run `pythonbrew cleanup` instead.\n')
return
parser.error("Unknown command: `%s`" % command) parser.error("Unknown command: `%s`" % command)
return return
command = command_dict[command] command = command_dict[command]
+7 -6
View File
@@ -2,7 +2,7 @@ import os
import sys import sys
import subprocess import subprocess
from pythonbrew.basecommand import Command from pythonbrew.basecommand import Command
from pythonbrew.define import PATH_PYTHONS, BOOTSTRAP_DLSITE, PATH_DISTS from pythonbrew.define import PATH_PYTHONS, BOOTSTRAP_DLSITE
from pythonbrew.util import Package, get_using_python_pkgname, Link, is_installed from pythonbrew.util import Package, get_using_python_pkgname, Link, is_installed
from pythonbrew.log import logger from pythonbrew.log import logger
from pythonbrew.downloader import Downloader from pythonbrew.downloader import Downloader
@@ -28,7 +28,7 @@ class BuildoutCommand(Command):
else: else:
pkgname = get_using_python_pkgname() pkgname = get_using_python_pkgname()
if not is_installed(pkgname): if not is_installed(pkgname):
logger.info('%s is not installed.' % pkgname) logger.error('`%s` is not installed.' % pkgname)
sys.exit(1) sys.exit(1)
logger.info('Using %s' % pkgname) logger.info('Using %s' % pkgname)
@@ -38,20 +38,21 @@ class BuildoutCommand(Command):
# Download bootstrap.py # Download bootstrap.py
download_url = BOOTSTRAP_DLSITE download_url = BOOTSTRAP_DLSITE
filename = Link(download_url).filename filename = Link(download_url).filename
bootstrap = os.path.join(PATH_DISTS, filename) bootstrap = os.path.join(os.getcwd(), filename) # fetching into current directory
try: try:
d = Downloader() d = Downloader()
d.download(filename, download_url, bootstrap) d.download(filename, download_url, bootstrap)
except: except:
logger.error("Failed to download. `%s`" % download_url) e = sys.exc_info()[1]
logger.error("%s" % (e))
sys.exit(1) sys.exit(1)
# Using bootstrap.py # call bootstrap.py
if subprocess.call([python, bootstrap, '-d']): if subprocess.call([python, bootstrap, '-d']):
logger.error('Failed to bootstrap.') logger.error('Failed to bootstrap.')
sys.exit(1) sys.exit(1)
# Using buildout # call buildout
subprocess.call(['./bin/buildout']) subprocess.call(['./bin/buildout'])
BuildoutCommand() BuildoutCommand()
+4 -4
View File
@@ -17,11 +17,11 @@ class HelpCommand(Command):
command.parser.print_help() command.parser.print_help()
return return
parser.print_help() parser.print_help()
logger.info("\nCommands available:") logger.log("\nCommands available:")
commands = [command_dict[key] for key in sorted(command_dict.keys())] commands = [command_dict[key] for key in sorted(command_dict.keys())]
for command in commands: for command in commands:
logger.info(" %s: %s" % (command.name, command.summary)) logger.log(" %s: %s" % (command.name, command.summary))
logger.info("\nFurther Instructions:") logger.log("\nFurther Instructions:")
logger.info(" https://github.com/utahta/pythonbrew") logger.log(" https://github.com/utahta/pythonbrew")
HelpCommand() HelpCommand()
+26 -11
View File
@@ -1,10 +1,8 @@
import sys
from pythonbrew.basecommand import Command from pythonbrew.basecommand import Command
from pythonbrew.log import logger
from pythonbrew.installer.pythoninstaller import PythonInstaller,\ from pythonbrew.installer.pythoninstaller import PythonInstaller,\
PythonInstallerMacOSX PythonInstallerMacOSX
from pythonbrew.util import is_macosx from pythonbrew.util import is_macosx
from pythonbrew.exceptions import UnknownVersionException,\
AlreadyInstalledException, NotSupportedVersionException
class InstallCommand(Command): class InstallCommand(Command):
name = "install" name = "install"
@@ -61,9 +59,32 @@ class InstallCommand(Command):
default=0, default=0,
help="Enable parallel make." help="Enable parallel make."
) )
self.parser.add_option(
"--framework",
dest="framework",
action="store_true",
default=False,
help="Build (MacOSX|Darwin) framework."
)
self.parser.add_option(
"--universal",
dest="universal",
action="store_true",
default=False,
help="Build for both 32 & 64 bit Intel."
)
self.parser.add_option(
"--static",
dest="static",
action="store_true",
default=False,
help="Build static libraries."
)
def run_command(self, options, args): def run_command(self, options, args):
if args: if not args:
self.parser.print_help()
sys.exit(1)
# installing python # installing python
for arg in args: for arg in args:
try: try:
@@ -72,13 +93,7 @@ class InstallCommand(Command):
else: else:
p = PythonInstaller(arg, options) p = PythonInstaller(arg, options)
p.install() p.install()
except UnknownVersionException: except:
continue continue
except AlreadyInstalledException:
continue
except NotSupportedVersionException:
continue
else:
logger.info("Unknown python version.")
InstallCommand() InstallCommand()
+8 -11
View File
@@ -3,8 +3,7 @@ import re
from pythonbrew.basecommand import Command from pythonbrew.basecommand import Command
from pythonbrew.define import PYTHON_VERSION_URL, LATEST_VERSIONS_OF_PYTHON,\ from pythonbrew.define import PYTHON_VERSION_URL, LATEST_VERSIONS_OF_PYTHON,\
PATH_PYTHONS PATH_PYTHONS
from pythonbrew.util import Package, get_using_python_pkgname,\ from pythonbrew.util import Package, get_using_python_pkgname
get_using_python_path
from pythonbrew.log import logger from pythonbrew.log import logger
class ListCommand(Command): class ListCommand(Command):
@@ -36,18 +35,16 @@ class ListCommand(Command):
self.installed(options, args) self.installed(options, args)
def installed(self, options, args): def installed(self, options, args):
logger.info('# installed pythons') logger.log("# pythonbrew pythons")
cur = get_using_python_pkgname() cur = get_using_python_pkgname()
for d in sorted(os.listdir(PATH_PYTHONS)): for d in sorted(os.listdir(PATH_PYTHONS)):
if cur and cur == d: if cur and cur == d:
logger.info('%s (*)' % d) logger.log(' %s (*)' % d)
else: else:
logger.info('%s' % d) logger.log(' %s' % d)
if not cur:
logger.info('%s (*)' % get_using_python_path())
def available_install(self, options, args): def available_install(self, options, args):
logger.info('# available install pythons') logger.log('# Pythons')
if args: if args:
pkg = Package(args[0]) pkg = Package(args[0])
_re = re.compile(r"%s" % pkg.name) _re = re.compile(r"%s" % pkg.name)
@@ -57,12 +54,12 @@ class ListCommand(Command):
pkgs.append(pkgname) pkgs.append(pkgname)
if pkgs: if pkgs:
for pkgname in pkgs: for pkgname in pkgs:
logger.info("%s" % pkgname) logger.log("%s" % pkgname)
else: else:
logger.info("Python version not found. `%s`" % pkg.name) logger.error("`%s` was not found." % pkg.name)
else: else:
for pkgname in self._get_packages_name(options): for pkgname in self._get_packages_name(options):
logger.info("%s" % pkgname) logger.log("%s" % pkgname)
def _get_packages_name(self, options): def _get_packages_name(self, options):
return ["Python-%s" % version for version in sorted(PYTHON_VERSION_URL.keys()) return ["Python-%s" % version for version in sorted(PYTHON_VERSION_URL.keys())
+3 -3
View File
@@ -32,12 +32,12 @@ class PyCommand(Command):
def run_command(self, options, args): def run_command(self, options, args):
if not args: if not args:
logger.info("Unrecognized command line argument: argument not found.") self.parser.print_help()
sys.exit(1) sys.exit(1)
pythons = self._get_pythons(options.pythons) pythons = self._get_pythons(options.pythons)
for d in pythons: for d in pythons:
if options.verbose: if options.verbose:
logger.info('*** %s ***' % d) logger.info('`%s` running...' % d)
path = os.path.join(PATH_PYTHONS, d, 'bin', args[0]) path = os.path.join(PATH_PYTHONS, d, 'bin', args[0])
if os.path.isfile(path) and os.access(path, os.X_OK): if os.path.isfile(path) and os.access(path, os.X_OK):
subprocess.call([path] + args[1:]) subprocess.call([path] + args[1:])
@@ -46,7 +46,7 @@ class PyCommand(Command):
if os.path.isfile(path) and os.access(path, os.X_OK): if os.path.isfile(path) and os.access(path, os.X_OK):
subprocess.call([path] + args) subprocess.call([path] + args)
else: else:
logger.info('%s: No such file or directory.' % path) logger.error('%s: No such file or directory.' % path)
def _get_pythons(self, _pythons): def _get_pythons(self, _pythons):
pythons = [Package(p).name for p in _pythons] pythons = [Package(p).name for p in _pythons]
+4 -4
View File
@@ -1,7 +1,7 @@
import os import os
import sys import sys
from pythonbrew.basecommand import Command from pythonbrew.basecommand import Command
from pythonbrew.define import PATH_PYTHONS, PATH_BIN from pythonbrew.define import PATH_PYTHONS
from pythonbrew.util import Package, set_current_path, is_installed from pythonbrew.util import Package, set_current_path, is_installed
from pythonbrew.log import logger from pythonbrew.log import logger
@@ -12,16 +12,16 @@ class SwitchCommand(Command):
def run_command(self, options, args): def run_command(self, options, args):
if not args: if not args:
logger.info("Unrecognized command line argument: argument not found.") self.parser.print_help()
sys.exit(1) sys.exit(1)
pkg = Package(args[0]) pkg = Package(args[0])
pkgname = pkg.name pkgname = pkg.name
if not is_installed(pkgname): if not is_installed(pkgname):
logger.info("`%s` is not installed." % pkgname) logger.error("`%s` is not installed." % pkgname)
sys.exit(1) sys.exit(1)
pkgbin = os.path.join(PATH_PYTHONS,pkgname,'bin') pkgbin = os.path.join(PATH_PYTHONS,pkgname,'bin')
set_current_path('%s:%s' % (PATH_BIN, pkgbin)) set_current_path(pkgbin)
logger.info("Switched to %s" % pkgname) logger.info("Switched to %s" % pkgname)
+33 -3
View File
@@ -1,7 +1,9 @@
import os import os
import sys
from pythonbrew.basecommand import Command from pythonbrew.basecommand import Command
from pythonbrew.define import PATH_PYTHONS, PATH_BIN from pythonbrew.define import PATH_PYTHONS, PATH_BIN, PATH_VENVS
from pythonbrew.util import Package, symlink, unlink from pythonbrew.util import Package, symlink, unlink, get_using_python_pkgname,\
is_installed
from pythonbrew.log import logger from pythonbrew.log import logger
class SymlinkCommand(Command): class SymlinkCommand(Command):
@@ -32,6 +34,12 @@ class SymlinkCommand(Command):
default=None, default=None,
help="Use as default the specified python version." help="Use as default the specified python version."
) )
self.parser.add_option(
"-v", "--venv",
dest="venv",
default=None,
help="Use the virtual environment python."
)
def run_command(self, options, args): def run_command(self, options, args):
if options.default: if options.default:
@@ -43,6 +51,28 @@ class SymlinkCommand(Command):
self._symlink(bin, bin, pkgname) self._symlink(bin, bin, pkgname)
else: else:
self._symlink('python', 'py', pkgname) self._symlink('python', 'py', pkgname)
elif options.venv:
if options.pythons:
pkgname = Package(options.pythons[0]).name
else:
pkgname = get_using_python_pkgname()
if not is_installed(pkgname):
logger.error('`%s` is not installed.')
sys.exit(1)
venv_pkgdir = os.path.join(PATH_VENVS, pkgname)
venv_dir = os.path.join(venv_pkgdir, options.venv)
if not os.path.isdir(venv_dir):
logger.error("`%s` environment was not found in %s." % (options.venv, venv_pkgdir))
sys.exit(1)
pkg = Package(pkgname)
if args:
bin = args[0]
dstbin = '%s%s-%s' % (bin, pkg.version, options.venv)
self._symlink(bin, dstbin, pkgname)
else:
dstbin = 'py%s-%s' % (pkg.version, options.venv)
self._symlink('python', dstbin, pkgname)
else: else:
pythons = self._get_pythons(options.pythons) pythons = self._get_pythons(options.pythons)
for pkgname in pythons: for pkgname in pythons:
@@ -75,7 +105,7 @@ class SymlinkCommand(Command):
if os.path.isfile(src): if os.path.isfile(src):
symlink(src, dst) symlink(src, dst)
else: else:
logger.info("%s: File not found" % src) logger.error("%s was not found in your path." % src)
def _get_pythons(self, _pythons): def _get_pythons(self, _pythons):
"""Get the installed python versions list. """Get the installed python versions list.
+1 -1
View File
@@ -19,7 +19,7 @@ class UninstallCommand(Command):
pkgpath = os.path.join(PATH_PYTHONS, pkgname) pkgpath = os.path.join(PATH_PYTHONS, pkgname)
venvpath = os.path.join(PATH_VENVS, pkgname) venvpath = os.path.join(PATH_VENVS, pkgname)
if not is_installed(pkgname): if not is_installed(pkgname):
logger.info("`%s` is not installed." % pkgname) logger.error("`%s` is not installed." % pkgname)
continue continue
if get_using_python_pkgname() == pkgname: if get_using_python_pkgname() == pkgname:
off() off()
+4 -4
View File
@@ -6,7 +6,7 @@ from pythonbrew.define import PATH_DISTS, VERSION, ROOT,\
from pythonbrew.log import logger from pythonbrew.log import logger
from pythonbrew.downloader import Downloader, get_pythonbrew_update_url,\ from pythonbrew.downloader import Downloader, get_pythonbrew_update_url,\
get_stable_version, get_headerinfo_from_url get_stable_version, get_headerinfo_from_url
from pythonbrew.util import rm_r, extract_downloadfile, Link, is_gzip, Subprocess from pythonbrew.util import rm_r, extract_downloadfile, Link, is_gzip, Subprocess, Version
class UpdateCommand(Command): class UpdateCommand(Command):
name = "update" name = "update"
@@ -65,7 +65,7 @@ class UpdateCommand(Command):
except: except:
logger.error("Failed to download. `%s`" % download_url) logger.error("Failed to download. `%s`" % download_url)
sys.exit(1) sys.exit(1)
logger.info("The config.cfg has been updated.") logger.log("The config.cfg has been updated.")
def _update_pythonbrew(self, options, args): def _update_pythonbrew(self, options, args):
if options.master: if options.master:
@@ -75,13 +75,13 @@ class UpdateCommand(Command):
else: else:
version = get_stable_version() version = get_stable_version()
# check for version # check for version
if not options.force and version <= VERSION: if not options.force and Version(version) <= VERSION:
logger.info("You are already running the installed latest version of pythonbrew.") logger.info("You are already running the installed latest version of pythonbrew.")
return return
download_url = get_pythonbrew_update_url(version) download_url = get_pythonbrew_update_url(version)
if not download_url: if not download_url:
logger.error("`%s` of pythonbrew not found." % version) logger.error("`pythonbrew-%s` was not found in pypi." % version)
sys.exit(1) sys.exit(1)
headinfo = get_headerinfo_from_url(download_url) headinfo = get_headerinfo_from_url(download_url)
content_type = headinfo['content-type'] content_type = headinfo['content-type']
+6 -7
View File
@@ -1,7 +1,7 @@
import os import os
import sys import sys
from pythonbrew.basecommand import Command from pythonbrew.basecommand import Command
from pythonbrew.define import PATH_PYTHONS, PATH_BIN, PATH_ETC_TEMP from pythonbrew.define import PATH_PYTHONS, PATH_HOME_ETC_TEMP
from pythonbrew.util import Package from pythonbrew.util import Package
from pythonbrew.log import logger from pythonbrew.log import logger
@@ -12,24 +12,23 @@ class UseCommand(Command):
def run_command(self, options, args): def run_command(self, options, args):
if not args: if not args:
logger.info("Unrecognized command line argument: argument not found.") self.parser.print_help()
sys.exit(1) sys.exit(1)
pkg = Package(args[0]) pkg = Package(args[0])
pkgname = pkg.name pkgname = pkg.name
pkgdir = os.path.join(PATH_PYTHONS, pkgname) pkgdir = os.path.join(PATH_PYTHONS, pkgname)
if not os.path.isdir(pkgdir): if not os.path.isdir(pkgdir):
logger.info("`%s` is not installed." % pkgname) logger.error("`%s` is not installed." % pkgname)
sys.exit(1) sys.exit(1)
pkgbin = os.path.join(pkgdir,'bin') pkgbin = os.path.join(pkgdir,'bin')
self._set_temp('%s:%s' % (PATH_BIN, pkgbin)) self._set_temp(pkgbin)
logger.info("Using `%s`" % pkgname) logger.info("Using `%s`" % pkgname)
def _set_temp(self, path): def _set_temp(self, path):
fp = open(PATH_ETC_TEMP, 'w') fp = open(PATH_HOME_ETC_TEMP, 'w')
fp.write('PATH_PYTHONBREW="%s"\n' % (path)) fp.write('PATH_PYTHONBREW_TEMP="%s"\n' % (path))
fp.close() fp.close()
UseCommand() UseCommand()
+88 -82
View File
@@ -1,10 +1,13 @@
import os import os
import sys import sys
from pythonbrew.basecommand import Command from pythonbrew.basecommand import Command
from pythonbrew.define import PATH_PYTHONS, PATH_VENVS, PATH_ETC_VENV from pythonbrew.define import PATH_PYTHONS, PATH_VENVS, PATH_HOME_ETC_VENV,\
from pythonbrew.util import Subprocess, Package,\ PATH_ETC, VIRTUALENV_DLSITE, PATH_DISTS
is_installed, get_installed_pythons_pkgname, get_using_python_pkgname from pythonbrew.util import Package, \
is_installed, get_installed_pythons_pkgname, get_using_python_pkgname,\
untar_file, Subprocess, rm_r
from pythonbrew.log import logger from pythonbrew.log import logger
from pythonbrew.downloader import Downloader
class VenvCommand(Command): class VenvCommand(Command):
name = "venv" name = "venv"
@@ -26,38 +29,30 @@ class VenvCommand(Command):
action='store_true', action='store_true',
default=False, default=False,
help="Show the all python environments.", help="Show the all python environments.",
metavar='VERSION'
) )
self.template_env = """export VIRTUALENVWRAPPER_PYTHON=%(venv_py)s self.parser.add_option(
export VIRTUALENVWRAPPER_VIRTUALENV=%(venv_venv)s "-n", "--no-site-packages",
export WORKON_HOME=%(workon_home)s dest="no_site_packages",
export VIRTUALENVWRAPPER_HOOK_DIR=%(workon_home)s action='store_true',
export VIRTUALENVWRAPPER_LOG_DIR=%(workon_home)s default=False,
source %(venv_sh)s help="Don't give access to the global site-packages dir to the virtual environment.",
""" )
self._venv_dir = os.path.join(PATH_ETC, 'virtualenv')
self._venv = os.path.join(self._venv_dir, 'virtualenv.py')
def run_command(self, options, args): def run_command(self, options, args):
if not args: if not args:
logger.error('Unrecognized command line argument: ( see: \'pythonbrew help venv\' )') self.parser.print_help()
sys.exit(1) sys.exit(1)
cmd = args[0] cmd = args[0]
if not cmd in ('create', 'delete', 'use', 'list'): if not cmd in ('init', 'create', 'delete', 'use', 'list'):
logger.error('Unrecognized command line argument: ( see: \'pythonbrew help venv\' )') self.parser.print_help()
sys.exit(1) sys.exit(1)
# find python2 # initialize?
venv_pkgname = None if cmd == 'init':
for pkgname in reversed(get_installed_pythons_pkgname()): self.run_command_init()
# virtualenvwrapper require Python2 return
venv_pkgver = Package(pkgname).version
if venv_pkgver >= '2.4' and venv_pkgver < '3':
venv_pkgname = pkgname
break
if not venv_pkgname:
logger.error('Can not create virtual environment before installing a python2. Try \'pythonbrew install <python2.4 - 2.7>\'.')
sys.exit(1)
venv_dir = os.path.join(PATH_PYTHONS, venv_pkgname)
venv_bin = os.path.join(venv_dir, 'bin')
# target python interpreter # target python interpreter
if options.python: if options.python:
@@ -66,92 +61,103 @@ source %(venv_sh)s
logger.error('%s is not installed.' % pkgname) logger.error('%s is not installed.' % pkgname)
sys.exit(1) sys.exit(1)
else: else:
# check using python under pythonbrew
pkgname = get_using_python_pkgname() pkgname = get_using_python_pkgname()
if not pkgname: if not pkgname:
logger.error('Can not use venv command before using a python. Try \'pythonbrew switch <some python>\'.') logger.error('Can not use venv command before switching a python. Try \'pythonbrew switch <version of python>\'.')
sys.exit(1) sys.exit(1)
self._pkgname = pkgname self._pkgname = pkgname
self._target_py = os.path.join(PATH_PYTHONS, pkgname, 'bin', 'python') self._target_py = os.path.join(PATH_PYTHONS, pkgname, 'bin', 'python')
self._workon_home = os.path.join(PATH_VENVS, pkgname) self._workon_home = os.path.join(PATH_VENVS, pkgname)
self._venv_py = os.path.join(venv_bin, 'python') self._py = os.path.join(PATH_PYTHONS, pkgname, 'bin', 'python')
self._venv_venv = os.path.join(venv_bin, 'virtualenv')
self._venv_sh = os.path.join(venv_bin, 'virtualenvwrapper.sh')
# has virtualenv & virtualenvwrapper? # is already installed virtualenv?
if not self._venv_venv or not self._venv_sh: if not os.path.exists(self._venv):
logger.info('Installing virtualenv into %s' % venv_dir) self.run_command_init()
s = Subprocess(verbose=True)
s.shell('%s %s %s' % (os.path.join(venv_bin,'pip'), 'install', 'virtualenvwrapper'))
# Create a shell script # Create a shell script
try:
self.__getattribute__('run_command_%s' % cmd)(options, args) self.__getattribute__('run_command_%s' % cmd)(options, args)
except:
logger.error('`%s` command not found.' % cmd) def run_command_init(self):
if os.path.exists(self._venv):
logger.info('venv command is already initialized.')
return
if not os.access(PATH_DISTS, os.W_OK):
logger.error("Can not initialize venv command: Permission denied.")
sys.exit(1) sys.exit(1)
d = Downloader()
download_file = os.path.join(PATH_DISTS, 'virtualenv.tar.gz')
d.download('virtualenv.tar.gz', VIRTUALENV_DLSITE, download_file)
logger.info('Extracting virtualenv into %s' % self._venv_dir)
untar_file(download_file, self._venv_dir)
def run_command_create(self, options, args): def run_command_create(self, options, args):
output = [self.template_env % {'venv_py': self._venv_py, if not os.access(PATH_VENVS, os.W_OK):
'venv_venv': self._venv_venv, logger.error("Can not create a virtuale environment in %s.\nPermission denied." % PATH_VENVS)
'workon_home': self._workon_home, sys.exit(1)
'venv_sh': self._venv_sh}]
virtualenv_options = []
if options.no_site_packages:
virtualenv_options.append('--no-site-packages')
for arg in args[1:]: for arg in args[1:]:
output.append("""echo '# Create `%(arg)s` environment into %(workon_home)s' target_dir = os.path.join(self._workon_home, arg)
mkvirtualenv -p '%(target_py)s' '%(arg)s' logger.info("Creating `%s` environment into %s" % (arg, self._workon_home))
""" % {'arg': arg, # make command
'workon_home': self._workon_home, cmd = [self._py, self._venv, '-p', self._target_py]
'target_py': self._target_py}) cmd.extend(virtualenv_options)
self._write(''.join(output)) cmd.append(target_dir)
# create environment
s = Subprocess(verbose=True)
s.call(cmd)
def run_command_delete(self, options, args): def run_command_delete(self, options, args):
output = [self.template_env % {'venv_py': self._venv_py,
'venv_venv': self._venv_venv,
'workon_home': self._workon_home,
'venv_sh': self._venv_sh}]
for arg in args[1:]: for arg in args[1:]:
output.append("""echo '# Delete `%(arg)s` environment in %(workon_home)s' target_dir = os.path.join(self._workon_home, arg)
rmvirtualenv '%(arg)s' if not os.path.isdir(target_dir):
""" % {'arg': arg, logger.error('%s already does not exist.' % target_dir)
'workon_home': self._workon_home}) else:
self._write(''.join(output)) if not os.access(target_dir, os.W_OK):
logger.error("Can not delete %s.\nPermission denied." % target_dir)
continue
logger.info('Deleting `%s` environment in %s' % (arg, self._workon_home))
# make command
rm_r(target_dir)
def run_command_use(self, options, args): def run_command_use(self, options, args):
if len(args) < 2: if len(args) < 2:
logger.error("Unrecognized command line argument: ( 'pythonbrew venv use <project>' )") logger.error("Unrecognized command line argument: ( 'pythonbrew venv use <project>' )")
sys.exit(1) sys.exit(1)
template = self.template_env + """echo '# Using `%(arg)s` environment (found in %(workon_home)s)'
activate = os.path.join(self._workon_home, args[1], 'bin', 'activate')
if not os.path.exists(activate):
logger.error('`%s` environment already does not exist. Try `pythonbrew venv create %s`.' % (args[1], args[1]))
sys.exit(1)
self._write("""\
echo '# Using `%(arg)s` environment (found in %(workon_home)s)'
echo '# To leave an environment, simply run `deactivate`' echo '# To leave an environment, simply run `deactivate`'
workon '%(arg)s' source '%(activate)s'
""" """ % {'arg': args[1], 'workon_home': self._workon_home, 'activate': activate})
self._write(template % {'venv_py': self._venv_py,
'venv_venv': self._venv_venv,
'workon_home': self._workon_home,
'venv_sh': self._venv_sh,
'arg': args[1]})
def run_command_list(self, options, args): def run_command_list(self, options, args):
template = self.template_env + """echo '# virtualenv for %(pkgname)s (found in %(workon_home)s)'
workon
"""
if options.all: if options.all:
output = []
for pkgname in get_installed_pythons_pkgname(): for pkgname in get_installed_pythons_pkgname():
workon_home = os.path.join(PATH_VENVS, pkgname) workon_home = os.path.join(PATH_VENVS, pkgname)
output.append(template % {'venv_py': self._venv_py, logger.log("# virtualenv for %(pkgname)s (found in %(workon_home)s)" % {'pkgname': pkgname, 'workon_home': workon_home})
'venv_venv': self._venv_venv, if os.path.isdir(workon_home):
'workon_home': workon_home, for d in sorted(os.listdir(workon_home)):
'venv_sh': self._venv_sh, if os.path.isdir(os.path.join(workon_home, d)):
'pkgname': pkgname}) logger.log(d)
self._write(''.join(output))
else: else:
self._write(template % {'venv_py': self._venv_py, logger.log("# virtualenv for %(pkgname)s (found in %(workon_home)s)" % {'pkgname': self._pkgname, 'workon_home': self._workon_home})
'venv_venv': self._venv_venv, if os.path.isdir(self._workon_home):
'workon_home': self._workon_home, for d in sorted(os.listdir(self._workon_home)):
'venv_sh': self._venv_sh, if os.path.isdir(os.path.join(self._workon_home, d)):
'pkgname': self._pkgname}) logger.log(d)
def _write(self, src): def _write(self, src):
fp = open(PATH_ETC_VENV, 'w') fp = open(PATH_HOME_ETC_VENV, 'w')
fp.write(src) fp.write(src)
fp.close() fp.close()
+1 -1
View File
@@ -8,6 +8,6 @@ class VersionCommand(Command):
summary = "Show version" summary = "Show version"
def run_command(self, options, args): def run_command(self, options, args):
logger.info(VERSION) logger.log(VERSION)
VersionCommand() VersionCommand()
+5 -4
View File
@@ -4,26 +4,27 @@ import subprocess
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
from pythonbrew.log import logger from pythonbrew.log import logger
from pythonbrew.util import to_str from pythonbrew.util import to_str
from pythonbrew.exceptions import CurlFetchException
class Curl(object): class Curl(object):
def __init__(self): def __init__(self):
returncode = subprocess.call("command -v curl > /dev/null", shell=True) returncode = subprocess.call("command -v curl > /dev/null", shell=True)
if returncode: if returncode:
logger.info("pythonbrew required curl. curl was not found in your path.") logger.log("pythonbrew required curl. curl was not found in your path.")
sys.exit(1) sys.exit(1)
def read(self, url): def read(self, url):
p = Popen("curl -skL %s" % url, stdout=PIPE, shell=True) p = Popen("curl -skL %s" % url, stdout=PIPE, shell=True)
p.wait() p.wait()
if p.returncode: if p.returncode:
raise raise Exception('Failed to read.')
return p.stdout.read() return p.stdout.read()
def readheader(self, url): def readheader(self, url):
p = Popen("curl --head -skL %s" % url, stdout=PIPE, shell=True) p = Popen("curl --head -skL %s" % url, stdout=PIPE, shell=True)
p.wait() p.wait()
if p.returncode: if p.returncode:
raise raise Exception('Failed to readheader.')
respinfo = {} respinfo = {}
for line in p.stdout: for line in p.stdout:
line = to_str(line.strip()) line = to_str(line.strip())
@@ -39,4 +40,4 @@ class Curl(object):
p = Popen("curl -# -kL %s -o %s" % (url, filename), shell=True) p = Popen("curl -# -kL %s -o %s" % (url, filename), shell=True)
p.wait() p.wait()
if p.returncode: if p.returncode:
raise raise CurlFetchException('Failed to fetch.')
+22 -7
View File
@@ -6,16 +6,17 @@ except:
import configparser as ConfigParser import configparser as ConfigParser
# pythonbrew version # pythonbrew version
VERSION = "0.9" VERSION = "1.1"
# pythonbrew installer root path
INSTALLER_ROOT = os.path.dirname(os.path.abspath(__file__))
# Root
# pythonbrew root path # pythonbrew root path
ROOT = os.environ.get("PYTHONBREW_ROOT") ROOT = os.environ.get("PYTHONBREW_ROOT")
if not ROOT: if not ROOT:
ROOT = os.path.join(os.environ["HOME"],".pythonbrew") ROOT = os.path.join(os.environ["HOME"],".pythonbrew")
# pythonbrew installer root path
INSTALLER_ROOT = os.path.dirname(os.path.abspath(__file__))
# directories # directories
PATH_PYTHONS = os.path.join(ROOT,"pythons") PATH_PYTHONS = os.path.join(ROOT,"pythons")
PATH_BUILD = os.path.join(ROOT,"build") PATH_BUILD = os.path.join(ROOT,"build")
@@ -38,10 +39,21 @@ PATH_PATCHES_MACOSX_PYTHON24 = os.path.join(PATH_PATCHES_MACOSX,"python24")
# files # files
PATH_BIN_PYTHONBREW = os.path.join(PATH_BIN,'pythonbrew') PATH_BIN_PYTHONBREW = os.path.join(PATH_BIN,'pythonbrew')
PATH_ETC_CURRENT = os.path.join(PATH_ETC,'current')
PATH_ETC_TEMP = os.path.join(PATH_ETC,'temp')
PATH_ETC_CONFIG = os.path.join(PATH_ETC,'config.cfg') PATH_ETC_CONFIG = os.path.join(PATH_ETC,'config.cfg')
PATH_ETC_VENV = os.path.join(PATH_ETC, 'venv.run')
# Home
# pythonbrew home path
PATH_HOME = os.environ.get('PYTHONBREW_HOME')
if not PATH_HOME:
PATH_HOME = os.path.join(os.environ["HOME"],".pythonbrew")
# directories
PATH_HOME_ETC = os.path.join(PATH_HOME, 'etc')
# files
PATH_HOME_ETC_VENV = os.path.join(PATH_HOME_ETC, 'venv.run')
PATH_HOME_ETC_CURRENT = os.path.join(PATH_HOME_ETC,'current')
PATH_HOME_ETC_TEMP = os.path.join(PATH_HOME_ETC,'temp')
# read config.cfg # read config.cfg
config = ConfigParser.SafeConfigParser() config = ConfigParser.SafeConfigParser()
@@ -58,6 +70,9 @@ DISTRIBUTE_SETUP_DLSITE = _get_or_default('distribute', 'url')
# buildout bootstrap download # buildout bootstrap download
BOOTSTRAP_DLSITE = _get_or_default('bootstrap', 'url') BOOTSTRAP_DLSITE = _get_or_default('bootstrap', 'url')
# virtualenv download
VIRTUALENV_DLSITE = _get_or_default('virtualenv', 'url')
# pythonbrew download # pythonbrew download
PYTHONBREW_UPDATE_URL_MASTER = _get_or_default('pythonbrew', 'master') PYTHONBREW_UPDATE_URL_MASTER = _get_or_default('pythonbrew', 'master')
PYTHONBREW_UPDATE_URL_DEVELOP = _get_or_default('pythonbrew', 'develop') PYTHONBREW_UPDATE_URL_DEVELOP = _get_or_default('pythonbrew', 'develop')
+43 -15
View File
@@ -1,6 +1,20 @@
PATH_ROOT="@ROOT@" # settings
PATH_ROOT="$PYTHONBREW_ROOT"
if [ -z "${PATH_ROOT}" ] ; then
PATH_ROOT="$HOME/.pythonbrew"
fi
PATH_ETC="$PATH_ROOT/etc" PATH_ETC="$PATH_ROOT/etc"
PATH_HOME="$PYTHONBREW_HOME"
if [ -z "${PATH_HOME}" ] ; then
PATH_HOME="$HOME/.pythonbrew"
fi
PATH_HOME_ETC="$PATH_HOME/etc"
# py file
PY_PYTHONBREW="$PATH_ROOT/bin/pythonbrew"
# functions
__pythonbrew_set_default() __pythonbrew_set_default()
{ {
PATH_PYTHONBREW="$PATH_ROOT/bin" PATH_PYTHONBREW="$PATH_ROOT/bin"
@@ -14,8 +28,9 @@ __pythonbrew_set_path()
__pythonbrew_set_temp_path() __pythonbrew_set_temp_path()
{ {
if [[ -s "$PATH_ETC/temp" ]] ; then if [[ -s "$PATH_HOME_ETC/temp" ]] ; then
source "$PATH_ETC/temp" source "$PATH_HOME_ETC/temp"
PATH_PYTHONBREW="$PATH_ROOT/bin:$PATH_PYTHONBREW_TEMP"
else else
__pythonbrew_set_default __pythonbrew_set_default
fi fi
@@ -24,8 +39,9 @@ __pythonbrew_set_temp_path()
__pythonbrew_set_current_path() __pythonbrew_set_current_path()
{ {
if [[ -s "$PATH_ETC/current" ]] ; then if [[ -s "$PATH_HOME_ETC/current" ]] ; then
source "$PATH_ETC/current" source "$PATH_HOME_ETC/current"
PATH_PYTHONBREW="$PATH_ROOT/bin:$PATH_PYTHONBREW_CURRENT"
else else
__pythonbrew_set_default __pythonbrew_set_default
fi fi
@@ -39,35 +55,35 @@ __pythonbrew_reload()
__pythonbrew_use() __pythonbrew_use()
{ {
command pythonbrew "$@" $pythonbrew "$@"
[[ $? == 0 ]] && __pythonbrew_set_temp_path [[ $? == 0 ]] && __pythonbrew_set_temp_path
} }
__pythonbrew_switch() __pythonbrew_switch()
{ {
command pythonbrew "$@" $pythonbrew "$@"
[[ $? == 0 ]] && __pythonbrew_set_current_path [[ $? == 0 ]] && __pythonbrew_set_current_path
} }
__pythonbrew_off() __pythonbrew_off()
{ {
command pythonbrew "$@" $pythonbrew "$@"
[[ $? == 0 ]] && __pythonbrew_set_current_path [[ $? == 0 ]] && __pythonbrew_set_current_path
} }
__pythonbrew_update() __pythonbrew_update()
{ {
command pythonbrew "$@" $pythonbrew "$@"
[[ $? == 0 ]] && __pythonbrew_reload [[ $? == 0 ]] && __pythonbrew_reload
} }
__pythonbrew_venv() __pythonbrew_venv()
{ {
command pythonbrew "$@" $pythonbrew "$@"
if [[ $? == 0 ]] ; then if [[ $? == 0 ]] ; then
if [[ -s "$PATH_ETC/venv.run" ]] ; then if [[ -s "$PATH_HOME_ETC/venv.run" ]] ; then
source "$PATH_ETC/venv.run" source "$PATH_HOME_ETC/venv.run"
cat /dev/null > "$PATH_ETC/venv.run" cat /dev/null > "$PATH_HOME_ETC/venv.run"
fi fi
fi fi
} }
@@ -87,7 +103,7 @@ __pythonbrew_find_command()
done done
} }
pythonbrew() __pythonbrew_run()
{ {
__pythonbrew_find_command "$@" __pythonbrew_find_command "$@"
case $command_name in case $command_name in
@@ -96,15 +112,27 @@ pythonbrew()
off) __pythonbrew_off "$@" ;; off) __pythonbrew_off "$@" ;;
update) __pythonbrew_update "$@" ;; update) __pythonbrew_update "$@" ;;
venv) __pythonbrew_venv "$@" ;; venv) __pythonbrew_venv "$@" ;;
*) command pythonbrew "$@" ;; *) $pythonbrew "$@" ;;
esac esac
builtin hash -r builtin hash -r
} }
pythonbrew()
{
pythonbrew=$PY_PYTHONBREW
__pythonbrew_run "$@"
}
pybrew() pybrew()
{ {
pythonbrew "$@" pythonbrew "$@"
} }
sudopybrew()
{
pythonbrew="sudo PYTHONBREW_ROOT=$PATH_ROOT PATH=$PATH_PYTHONBREW:$PATH_WITHOUT_PYTHONBREW $PY_PYTHONBREW"
__pythonbrew_run "$@"
}
# main # main
__pythonbrew_set_current_path __pythonbrew_set_current_path
+6 -1
View File
@@ -4,6 +4,9 @@ url = http://python-distribute.org/distribute_setup.py
[bootstrap] [bootstrap]
url = http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py url = http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py
[virtualenv]
url = http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.6.4.tar.gz
[pythonbrew] [pythonbrew]
master = https://github.com/utahta/pythonbrew/tarball/master master = https://github.com/utahta/pythonbrew/tarball/master
develop = https://github.com/utahta/pythonbrew/tarball/develop develop = https://github.com/utahta/pythonbrew/tarball/develop
@@ -178,5 +181,7 @@ latest = True
[Python-3.2] [Python-3.2]
url = http://www.python.org/ftp/python/3.2/Python-3.2.tgz url = http://www.python.org/ftp/python/3.2/Python-3.2.tgz
latest = True
[Python-3.2.1]
url = http://www.python.org/ftp/python/3.2.1/Python-3.2.1.tgz
latest = True
+2
View File
@@ -12,3 +12,5 @@ class AlreadyInstalledException(Exception):
class NotSupportedVersionException(Exception): class NotSupportedVersionException(Exception):
"""General exception during installing""" """General exception during installing"""
class CurlFetchException(Exception):
"""Exception curl during fetching"""
+30 -4
View File
@@ -3,10 +3,10 @@ from pythonbrew.log import logger
from pythonbrew.define import INSTALLER_ROOT, ROOT, PATH_ETC from pythonbrew.define import INSTALLER_ROOT, ROOT, PATH_ETC
def install_pythonbrew(): def install_pythonbrew():
PythonbrewInstaller().install(INSTALLER_ROOT) PythonbrewInstaller.install(INSTALLER_ROOT)
# pythonbrew is only for bash # for bash
shrc = yourshrc = "bashrc" shrc = yourshrc = "bashrc"
logger.info(""" logger.log("""
Well-done! Congratulations! Well-done! Congratulations!
The pythonbrew is installed as: The pythonbrew is installed as:
@@ -33,4 +33,30 @@ Enjoy pythonbrew at %(ROOT)s!!
""" % {'ROOT':ROOT, 'yourshrc':yourshrc, 'shrc':shrc, 'PATH_ETC':PATH_ETC}) """ % {'ROOT':ROOT, 'yourshrc':yourshrc, 'shrc':shrc, 'PATH_ETC':PATH_ETC})
def upgrade_pythonbrew(): def upgrade_pythonbrew():
PythonbrewInstaller().install(INSTALLER_ROOT) PythonbrewInstaller.install(INSTALLER_ROOT)
def systemwide_pythonbrew():
PythonbrewInstaller.install(INSTALLER_ROOT)
PythonbrewInstaller.systemwide_install()
logger.log("""
Well-done! Congratulations!
The pythonbrew is installed as:
%(ROOT)s
After that, exit this shell, start a new one, and install some fresh
pythons:
pythonbrew install 2.7.2
pythonbrew install 3.2
For further instructions, run:
pythonbrew help
The default help messages will popup and tell you what to do!
Enjoy pythonbrew at %(ROOT)s!!
""" % {'ROOT':ROOT})
+45 -8
View File
@@ -6,15 +6,17 @@ from pythonbrew.util import makedirs, rm_r
from pythonbrew.define import PATH_BUILD, PATH_BIN, PATH_DISTS, PATH_PYTHONS,\ from pythonbrew.define import PATH_BUILD, PATH_BIN, PATH_DISTS, PATH_PYTHONS,\
PATH_ETC, PATH_SCRIPTS, PATH_SCRIPTS_PYTHONBREW,\ PATH_ETC, PATH_SCRIPTS, PATH_SCRIPTS_PYTHONBREW,\
PATH_SCRIPTS_PYTHONBREW_COMMANDS, PATH_BIN_PYTHONBREW,\ PATH_SCRIPTS_PYTHONBREW_COMMANDS, PATH_BIN_PYTHONBREW,\
ROOT, PATH_LOG, PATH_PATCHES, PATH_ETC_CONFIG,\ PATH_LOG, PATH_PATCHES, PATH_ETC_CONFIG,\
PATH_SCRIPTS_PYTHONBREW_INSTALLER, PATH_VENVS PATH_SCRIPTS_PYTHONBREW_INSTALLER, PATH_VENVS, PATH_HOME_ETC, ROOT
import stat import stat
import time
class PythonbrewInstaller(object): class PythonbrewInstaller(object):
"""pythonbrew installer: """pythonbrew installer:
""" """
def install(self, installer_root): @staticmethod
def install(installer_root):
# create directories # create directories
makedirs(PATH_PYTHONS) makedirs(PATH_PYTHONS)
makedirs(PATH_BUILD) makedirs(PATH_BUILD)
@@ -23,6 +25,7 @@ class PythonbrewInstaller(object):
makedirs(PATH_BIN) makedirs(PATH_BIN)
makedirs(PATH_LOG) makedirs(PATH_LOG)
makedirs(PATH_VENVS) makedirs(PATH_VENVS)
makedirs(PATH_HOME_ETC)
# create script directories # create script directories
rm_r(PATH_SCRIPTS) rm_r(PATH_SCRIPTS)
@@ -61,12 +64,46 @@ if __name__ == "__main__":
os.chmod(PATH_BIN_PYTHONBREW, stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH) os.chmod(PATH_BIN_PYTHONBREW, stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH)
# create a bashrc for pythonbrew # create a bashrc for pythonbrew
fp = open(os.path.join(PATH_ETC,'bashrc'), 'w') shutil.copy(os.path.join(installer_root,'etc','bashrc'), os.path.join(PATH_ETC,'bashrc'))
for line in open(os.path.join(installer_root,'etc','bashrc')):
line = line.replace('@ROOT@', ROOT)
fp.write(line)
fp.close()
# copy config.cfg # copy config.cfg
shutil.copy(os.path.join(installer_root,'etc','config.cfg'), PATH_ETC_CONFIG) shutil.copy(os.path.join(installer_root,'etc','config.cfg'), PATH_ETC_CONFIG)
@staticmethod
def systemwide_install():
profile = """\
#begin-pythonbrew
if [ -n "${BASH_VERSION:-}" -o -n "${ZSH_VERSION:-}" ] ; then
export PYTHONBREW_ROOT=%(root)s
source "${PYTHONBREW_ROOT}/etc/bashrc"
fi
#end-pythonbrew
""" % {'root': ROOT}
if os.path.isdir('/etc/profile.d'):
fp = open('/etc/profile.d/pythonbrew.sh', 'w')
fp.write(profile)
fp.close()
elif os.path.isfile('/etc/profile'):
# create backup
shutil.copy('/etc/profile', '/tmp/profile.pythonbrew.%s' % int(time.time()))
output = []
is_copy = True
fp = open('/etc/profile', 'r')
for line in fp:
if line.startswith('#begin-pythonbrew'):
is_copy = False
continue
elif line.startswith('#end-pythonbrew'):
is_copy = True
continue
if is_copy:
output.append(line)
fp.close()
output.append(profile)
fp = open('/etc/profile', 'w')
fp.write(''.join(output))
fp.close()
+63 -29
View File
@@ -2,12 +2,13 @@ import os
import sys import sys
import shutil import shutil
import mimetypes import mimetypes
import re
from pythonbrew.util import makedirs, symlink, Package, is_url, Link,\ from pythonbrew.util import makedirs, symlink, Package, is_url, Link,\
unlink, is_html, Subprocess, rm_r,\ unlink, is_html, Subprocess, rm_r,\
is_python25, is_python24, is_python26, is_python27,\ is_python25, is_python24, is_python26, is_python27,\
extract_downloadfile, is_archive_file, path_to_fileurl, is_file,\ extract_downloadfile, is_archive_file, path_to_fileurl, is_file,\
fileurl_to_path, is_python30, is_python31, is_python32,\ fileurl_to_path, is_python30, is_python31, is_python32,\
get_macosx_deployment_target get_macosx_deployment_target, Version
from pythonbrew.define import PATH_BUILD, PATH_DISTS, PATH_PYTHONS,\ from pythonbrew.define import PATH_BUILD, PATH_DISTS, PATH_PYTHONS,\
ROOT, PATH_LOG, DISTRIBUTE_SETUP_DLSITE,\ ROOT, PATH_LOG, DISTRIBUTE_SETUP_DLSITE,\
PATH_PATCHES_MACOSX_PYTHON25, PATH_PATCHES_MACOSX_PYTHON24,\ PATH_PATCHES_MACOSX_PYTHON25, PATH_PATCHES_MACOSX_PYTHON24,\
@@ -16,7 +17,7 @@ from pythonbrew.downloader import get_python_version_url, Downloader,\
get_headerinfo_from_url get_headerinfo_from_url
from pythonbrew.log import logger from pythonbrew.log import logger
from pythonbrew.exceptions import UnknownVersionException,\ from pythonbrew.exceptions import UnknownVersionException,\
AlreadyInstalledException, NotSupportedVersionException NotSupportedVersionException
class PythonInstaller(object): class PythonInstaller(object):
"""Python installer """Python installer
@@ -38,7 +39,7 @@ class PythonInstaller(object):
pkg = Package(name, options.alias) pkg = Package(name, options.alias)
self.download_url = get_python_version_url(pkg.version) self.download_url = get_python_version_url(pkg.version)
if not self.download_url: if not self.download_url:
logger.info("Unknown python version: `%s`" % pkg.name) logger.error("Unknown python version: `%s`" % pkg.name)
raise UnknownVersionException raise UnknownVersionException
filename = Link(self.download_url).filename filename = Link(self.download_url).filename
self.pkg = pkg self.pkg = pkg
@@ -46,6 +47,16 @@ class PythonInstaller(object):
self.build_dir = os.path.join(PATH_BUILD, pkg.name) self.build_dir = os.path.join(PATH_BUILD, pkg.name)
self.download_file = os.path.join(PATH_DISTS, filename) self.download_file = os.path.join(PATH_DISTS, filename)
self.options = options
self.logfile = os.path.join(PATH_LOG, 'build.log')
self.patches = []
if Version(self.pkg.version) >= '3.1':
self.configure_options = ['--with-computed-gotos']
else:
self.configure_options = []
def install(self):
# cleanup # cleanup
if os.path.isdir(self.build_dir): if os.path.isdir(self.build_dir):
shutil.rmtree(self.build_dir) shutil.rmtree(self.build_dir)
@@ -62,15 +73,10 @@ class PythonInstaller(object):
logger.error("Invalid content-type: `%s`" % self.content_type) logger.error("Invalid content-type: `%s`" % self.content_type)
return return
self.options = options
self.logfile = os.path.join(PATH_LOG, 'build.log')
self.configure_options = ''
self.patches = []
def install(self):
if os.path.isdir(self.install_dir): if os.path.isdir(self.install_dir):
logger.info("You are already installed `%s`" % self.pkg.name) logger.info("You are already installed `%s`" % self.pkg.name)
raise AlreadyInstalledException return
self.download_and_extract() self.download_and_extract()
logger.info("\nThis could take a while. You can run the following command on another shell to track the status:") logger.info("\nThis could take a while. You can run the following command on another shell to track the status:")
logger.info(" tail -f %s\n" % self.logfile) logger.info(" tail -f %s\n" % self.logfile)
@@ -83,11 +89,11 @@ class PythonInstaller(object):
except: except:
rm_r(self.install_dir) rm_r(self.install_dir)
logger.error("Failed to install %s. See %s to see why." % (self.pkg.name, self.logfile)) logger.error("Failed to install %s. See %s to see why." % (self.pkg.name, self.logfile))
logger.info(" pythonbrew install --force %s" % self.pkg.version) logger.log(" pythonbrew install --force %s" % self.pkg.version)
sys.exit(1) sys.exit(1)
self.symlink() self.symlink()
self.install_setuptools() self.install_setuptools()
logger.info("Installed %(pkgname)s successfully. Run the following command to switch to %(pkgname)s." logger.info("\nInstalled %(pkgname)s successfully. Run the following command to switch to %(pkgname)s."
% {"pkgname":self.pkg.name}) % {"pkgname":self.pkg.name})
logger.info(" pythonbrew switch %s" % self.pkg.alias) logger.info(" pythonbrew switch %s" % self.pkg.alias)
@@ -107,14 +113,14 @@ class PythonInstaller(object):
dl.download(base_url, self.download_url, self.download_file) dl.download(base_url, self.download_url, self.download_file)
except: except:
unlink(self.download_file) unlink(self.download_file)
logger.info("\nInterrupt to abort. `%s`" % (self.download_url)) logger.error("Failed to download.\n%s" % (sys.exc_info()[1]))
sys.exit(1) sys.exit(1)
# extracting # extracting
if not extract_downloadfile(self.content_type, self.download_file, self.build_dir): if not extract_downloadfile(self.content_type, self.download_file, self.build_dir):
sys.exit(1) sys.exit(1)
def patch(self): def patch(self):
version = self.pkg.version version = Version(self.pkg.version)
# for ubuntu 11.04(Natty) # for ubuntu 11.04(Natty)
if is_python24(version): if is_python24(version):
patch_dir = os.path.join(PATH_PATCHES_ALL, "python24") patch_dir = os.path.join(PATH_PATCHES_ALL, "python24")
@@ -154,7 +160,7 @@ class PythonInstaller(object):
else: else:
s.shell("patch -p0 < %s" % patch) s.shell("patch -p0 < %s" % patch)
except: except:
logger.error("Failed to patch `%s`" % self.build_dir) logger.error("Failed to patch `%s`.\n%s" % (self.build_dir, sys.exc_info()[1]))
sys.exit(1) sys.exit(1)
def _add_patches_to_list(self, patch_dir, patch_files): def _add_patches_to_list(self, patch_dir, patch_files):
@@ -170,7 +176,10 @@ class PythonInstaller(object):
def configure(self): def configure(self):
s = Subprocess(log=self.logfile, cwd=self.build_dir, verbose=self.options.verbose) s = Subprocess(log=self.logfile, cwd=self.build_dir, verbose=self.options.verbose)
s.check_call("./configure --prefix=%s %s %s" % (self.install_dir, self.options.configure, self.configure_options)) cmd = "./configure --prefix=%s %s %s" % (self.install_dir, self.options.configure, ' '.join(self.configure_options))
if self.options.verbose:
logger.log(cmd)
s.check_call(cmd)
def make(self): def make(self):
jobs = self.options.jobs jobs = self.options.jobs
@@ -185,7 +194,7 @@ class PythonInstaller(object):
s.check_call("make test") s.check_call("make test")
def make_install(self): def make_install(self):
version = self.pkg.version version = Version(self.pkg.version)
if version == "1.5.2" or version == "1.6.1": if version == "1.5.2" or version == "1.6.1":
makedirs(self.install_dir) makedirs(self.install_dir)
s = Subprocess(log=self.logfile, cwd=self.build_dir, verbose=self.options.verbose) s = Subprocess(log=self.logfile, cwd=self.build_dir, verbose=self.options.verbose)
@@ -193,20 +202,33 @@ class PythonInstaller(object):
def symlink(self): def symlink(self):
install_dir = os.path.realpath(self.install_dir) install_dir = os.path.realpath(self.install_dir)
if self.options.framework:
# create symlink bin -> /path/to/Frameworks/Python.framework/Versions/?.?/bin
bin_dir = os.path.join(install_dir, 'bin')
if os.path.exists(bin_dir):
rm_r(bin_dir)
m = re.match(r'\d\.\d', self.pkg.version)
if m:
version = m.group(0)
symlink(os.path.join(install_dir,'Frameworks','Python.framework','Versions',version,'bin'),
os.path.join(bin_dir))
path_python = os.path.join(install_dir,'bin','python') path_python = os.path.join(install_dir,'bin','python')
if not os.path.isfile(path_python): if not os.path.isfile(path_python):
path_python3 = os.path.join(install_dir,'bin','python3') src = None
path_python3_0 = os.path.join(install_dir,'bin','python3.0') for d in os.listdir(os.path.join(install_dir,'bin')):
if os.path.isfile(path_python3): if re.match(r'python\d\.\d', d):
symlink(path_python3, path_python) src = d
elif os.path.isfile(path_python3_0): break
symlink(path_python3_0, path_python) if src:
path_src = os.path.join(install_dir,'bin',src)
symlink(path_src, path_python)
def install_setuptools(self): def install_setuptools(self):
options = self.options options = self.options
pkgname = self.pkg.name pkgname = self.pkg.name
if options.no_setuptools: if options.no_setuptools:
logger.info("Skip installation of setuptools.") logger.log("Skip installation of setuptools.")
return return
download_url = DISTRIBUTE_SETUP_DLSITE download_url = DISTRIBUTE_SETUP_DLSITE
filename = Link(download_url).filename filename = Link(download_url).filename
@@ -228,7 +250,7 @@ class PythonInstaller(object):
s.check_call([easy_install, 'pip']) s.check_call([easy_install, 'pip'])
except: except:
logger.error("Failed to install setuptools. See %s/build.log to see why." % (ROOT)) logger.error("Failed to install setuptools. See %s/build.log to see why." % (ROOT))
logger.info("Skip installation of setuptools.") logger.log("Skip installation of setuptools.")
class PythonInstallerMacOSX(PythonInstaller): class PythonInstallerMacOSX(PythonInstaller):
"""Python installer for MacOSX """Python installer for MacOSX
@@ -237,14 +259,26 @@ class PythonInstallerMacOSX(PythonInstaller):
super(PythonInstallerMacOSX, self).__init__(arg, options) super(PythonInstallerMacOSX, self).__init__(arg, options)
# check for version # check for version
version = self.pkg.version version = Version(self.pkg.version)
if version < '2.6' and (version != '2.4.6' and version < '2.5.5'): if version < '2.6' and (version != '2.4.6' and version < '2.5.5'):
logger.info("`%s` is not supported on MacOSX Snow Leopard" % self.pkg.name) logger.error("`%s` is not supported on MacOSX Snow Leopard" % self.pkg.name)
raise NotSupportedVersionException raise NotSupportedVersionException
# set configure options # set configure options
target = get_macosx_deployment_target() target = get_macosx_deployment_target()
if target: if target:
self.configure_options = 'MACOSX_DEPLOYMENT_TARGET=%s' % target self.configure_options.append('MACOSX_DEPLOYMENT_TARGET=%s' % target)
# set build options
if options.framework and options.static:
logger.error("Can't specify both framework and static.")
raise Exception
if options.framework:
self.configure_options.append('--enable-framework=%s' % os.path.join(self.install_dir, 'Frameworks'))
elif not options.static:
self.configure_options.append('--enable-shared')
if options.universal:
self.configure_options.append('--enable-universalsdk=/')
self.configure_options.append('--with-universal-archs=intel')
# note: skip `make test` to avoid hanging test_threading. # note: skip `make test` to avoid hanging test_threading.
if is_python25(version) or is_python24(version): if is_python25(version) or is_python24(version):
@@ -252,7 +286,7 @@ class PythonInstallerMacOSX(PythonInstaller):
def patch(self): def patch(self):
# note: want an interface to the source patching functionality. like a patchperl. # note: want an interface to the source patching functionality. like a patchperl.
version = self.pkg.version version = Version(self.pkg.version)
if is_python24(version): if is_python24(version):
patch_dir = PATH_PATCHES_MACOSX_PYTHON24 patch_dir = PATH_PATCHES_MACOSX_PYTHON24
self._add_patches_to_list(patch_dir, ['patch-configure', 'patch-Makefile.pre.in', self._add_patches_to_list(patch_dir, ['patch-configure', 'patch-Makefile.pre.in',
+32 -32
View File
@@ -1,43 +1,43 @@
import sys import sys
import logging
class LoggerInfo(object): class Color(object):
def log(self, level, msg, *arg, **keys): DEBUG = '\033[35m'
sys.stdout.write("%s\n" % msg) INFO = '\033[32m'
ERROR = '\033[31m'
ENDC = '\033[0m'
class LoggerError(object): @classmethod
def log(self, level, msg, *arg, **keys): def _deco(cls, msg, color):
sys.stderr.write("ERROR: %s\n" % msg) return '%s%s%s' % (color, msg, cls.ENDC)
@classmethod
def debug(cls, msg):
return cls._deco(msg, cls.DEBUG)
@classmethod
def info(cls, msg):
return cls._deco(msg, cls.INFO)
@classmethod
def error(cls, msg):
return cls._deco(msg, cls.ERROR)
class Logger(object): class Logger(object):
def debug(self, msg):
self._stdout(Color.debug("DEBUG: %s\n" % msg))
DEBUG = logging.DEBUG def log(self, msg):
INFO = logging.INFO self._stdout("%s\n" % (msg))
ERROR = logging.ERROR
def __init__(self): def info(self, msg):
self._consumers = [] self._stdout(Color.info('%s\n' % msg))
consumer = LoggerInfo()
self.add_consumer(Logger.INFO, consumer)
consumer = LoggerError() def error(self, msg):
self.add_consumer(Logger.ERROR, consumer) self._stderr(Color.error("ERROR: %s\n" % msg))
def debug(self, msg, *args, **keys): def _stdout(self, msg):
self._log(Logger.DEBUG, msg, *args, **keys) sys.stdout.write(msg)
sys.stdout.flush()
def info(self, msg, *args, **keys): def _stderr(self, msg):
self._log(Logger.INFO, msg, *args, **keys) sys.stderr.write(msg)
sys.stderr.flush()
def error(self, msg, *args, **keys):
self._log(Logger.ERROR, msg, *args, **keys)
def _log(self, level, msg, *args, **keys):
for (consumer_level, consumer) in self._consumers:
if level == consumer_level:
consumer.log(level, msg, *args, **keys)
def add_consumer(self, level, consumer):
self._consumers.append((level, consumer))
logger = Logger() logger = Logger()
+102 -15
View File
@@ -10,7 +10,7 @@ import urllib
import subprocess import subprocess
import shlex import shlex
import select import select
from pythonbrew.define import PATH_BIN, PATH_ETC_CURRENT, PATH_PYTHONS from pythonbrew.define import PATH_BIN, PATH_HOME_ETC_CURRENT, PATH_PYTHONS
from pythonbrew.exceptions import ShellCommandException from pythonbrew.exceptions import ShellCommandException
from pythonbrew.log import logger from pythonbrew.log import logger
@@ -72,26 +72,31 @@ def get_macosx_deployment_target():
return m.group(1) return m.group(1)
return None return None
def _py_version_cmp(v, v1, v2):
if is_str(v):
v = Version(v)
return v >= v1 and v < v2
def is_python24(version): def is_python24(version):
return version >= '2.4' and version < '2.5' return _py_version_cmp(version, '2.4', '2.5')
def is_python25(version): def is_python25(version):
return version >= '2.5' and version < '2.6' return _py_version_cmp(version, '2.5', '2.6')
def is_python26(version): def is_python26(version):
return version >= '2.6' and version < '2.7' return _py_version_cmp(version, '2.6', '2.7')
def is_python27(version): def is_python27(version):
return version >= '2.7' and version < '2.8' return _py_version_cmp(version, '2.7', '2.8')
def is_python30(version): def is_python30(version):
return version >= '3.0' and version < '3.1' return _py_version_cmp(version, '3.0', '3.1')
def is_python31(version): def is_python31(version):
return version >= '3.1' and version < '3.2' return _py_version_cmp(version, '3.1', '3.2')
def is_python32(version): def is_python32(version):
return version >= '3.2' and version < '3.3' return _py_version_cmp(version, '3.2', '3.3')
def makedirs(path): def makedirs(path):
if not os.path.exists(path): if not os.path.exists(path):
@@ -209,14 +214,19 @@ def extract_downloadfile(content_type, download_file, target_dir):
return False return False
return True return True
def get_using_python_path(): def get_command_path(command):
p = subprocess.Popen('command -v python', stdout=subprocess.PIPE, shell=True) p = subprocess.Popen('command -v %s' % command, stdout=subprocess.PIPE, shell=True)
return to_str(p.communicate()[0].strip()) return to_str(p.communicate()[0].strip())
def get_using_python_path():
return get_command_path('python')
def get_using_python_pkgname(): def get_using_python_pkgname():
"""return: Python-<VERSION> or None""" """return: Python-<VERSION> or None"""
path = get_using_python_path() path = get_using_python_path()
for d in sorted(os.listdir(PATH_PYTHONS)): for d in sorted(os.listdir(PATH_PYTHONS)):
if not os.path.exists(os.path.join(PATH_PYTHONS, d, 'bin','python')):
continue
if path and os.path.samefile(path, os.path.join(PATH_PYTHONS, d, 'bin','python')): if path and os.path.samefile(path, os.path.join(PATH_PYTHONS, d, 'bin','python')):
return d return d
return None return None
@@ -233,8 +243,8 @@ def is_installed(name):
return True return True
def set_current_path(path): def set_current_path(path):
fp = open(PATH_ETC_CURRENT, 'w') fp = open(PATH_HOME_ETC_CURRENT, 'w')
fp.write('PATH_PYTHONBREW="%s"\n' % (path)) fp.write('PATH_PYTHONBREW_CURRENT="%s"\n' % (path))
fp.close() fp.close()
def path_to_fileurl(path): def path_to_fileurl(path):
@@ -268,6 +278,11 @@ def is_str(val):
return isinstance(val, str) return isinstance(val, str)
return False return False
def is_sequence(val):
if is_str(val):
return False
return (hasattr(val, "__getitem__") or hasattr(val, "__iter__"))
def bltin_any(iter): def bltin_any(iter):
try: try:
return any(iter) return any(iter)
@@ -278,6 +293,9 @@ def bltin_any(iter):
return True return True
return False return False
#-----------------------------
# class
#-----------------------------
class Subprocess(object): class Subprocess(object):
def __init__(self, log=None, cwd=None, verbose=False, debug=False): def __init__(self, log=None, cwd=None, verbose=False, debug=False):
self._log = log self._log = log
@@ -290,7 +308,9 @@ class Subprocess(object):
def shell(self, cmd): def shell(self, cmd):
if self._debug: if self._debug:
logger.info(cmd) logger.log(cmd)
if is_sequence(cmd):
cmd = ''.join(cmd)
if self._log: if self._log:
if self._verbose: if self._verbose:
cmd = "(%s) 2>&1 | tee '%s'" % (cmd, self._log) cmd = "(%s) 2>&1 | tee '%s'" % (cmd, self._log)
@@ -304,7 +324,7 @@ class Subprocess(object):
if is_str(cmd): if is_str(cmd):
cmd = shlex.split(cmd) cmd = shlex.split(cmd)
if self._debug: if self._debug:
logger.info(cmd) logger.log(cmd)
fp = ((self._log and open(self._log, 'a')) or None) fp = ((self._log and open(self._log, 'a')) or None)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self._cwd) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self._cwd)
@@ -314,7 +334,7 @@ class Subprocess(object):
if not line: if not line:
break break
if self._verbose: if self._verbose:
logger.info(line.strip()) logger.log(line.strip())
if fp: if fp:
fp.write(line) fp.write(line)
fp.flush() fp.flush()
@@ -364,4 +384,71 @@ class Link(object):
def base_url(self): def base_url(self):
return posixpath.basename(self._url.split('#', 1)[0].split('?', 1)[0]) return posixpath.basename(self._url.split('#', 1)[0].split('?', 1)[0])
class Version(object):
"""version compare
"""
def __init__(self, v):
self._version = v
self._p = self._parse_version(v)
def __lt__(self, o):
if is_str(o):
o = self._parse_version(o)
return self._p < o
def __le__(self, o):
if is_str(o):
o = self._parse_version(o)
return self._p <= o
def __eq__(self, o):
if is_str(o):
o = self._parse_version(o)
return self._p == o
def __ne__(self, o):
if is_str(o):
o = self._parse_version(o)
return self._p != o
def __gt__(self, o):
if is_str(o):
o = self._parse_version(o)
return self._p > o
def __ge__(self, o):
if is_str(o):
o = self._parse_version(o)
return self._p >= o
def _parse_version(self, s):
"""see pkg_resouce.parse_version
"""
component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE)
replace = {'pre':'c', 'preview':'c','-':'final-','rc':'c','dev':'@'}.get
def _parse_version_parts(s):
for part in component_re.split(s):
part = replace(part,part)
if not part or part=='.':
continue
if part[:1] in '0123456789':
yield part.zfill(8) # pad for numeric comparison
else:
yield '*'+part
yield '*final' # ensure that alpha/beta/candidate are before final
parts = []
for part in _parse_version_parts(s.lower()):
if part.startswith('*'):
if part<'*final': # remove '-' before a prerelease tag
while parts and parts[-1]=='*final-': parts.pop()
# remove trailing zeros from each series of numeric parts
while parts and parts[-1]=='00000000':
parts.pop()
parts.append(part)
return tuple(parts)
def __repr__(self):
return self._version
+11 -2
View File
@@ -1,4 +1,4 @@
from pythonbrew.installer import install_pythonbrew, upgrade_pythonbrew from pythonbrew.installer import install_pythonbrew, upgrade_pythonbrew, systemwide_pythonbrew
from optparse import OptionParser from optparse import OptionParser
if __name__ == "__main__": if __name__ == "__main__":
parser = OptionParser() parser = OptionParser()
@@ -9,8 +9,17 @@ if __name__ == "__main__":
default=False, default=False,
help="Upgrade." help="Upgrade."
) )
parser.add_option(
'--systemwide',
dest="systemwide",
action="store_true",
default=False,
help="systemwide install."
)
(opt, arg) = parser.parse_args() (opt, arg) = parser.parse_args()
if opt.upgrade: if opt.systemwide:
systemwide_pythonbrew()
elif opt.upgrade:
upgrade_pythonbrew() upgrade_pythonbrew()
else: else:
install_pythonbrew() install_pythonbrew()
+4
View File
@@ -17,6 +17,10 @@ setup(name='pythonbrew',
'Programming Language :: Python :: 2.4', 'Programming Language :: Python :: 2.4',
'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.1',
'Programming Language :: Python :: 3.2',
], ],
keywords='pythonbrew pip easy_install distutils setuptools virtualenv', keywords='pythonbrew pip easy_install distutils setuptools virtualenv',
author='utahta', author='utahta',
+1 -1
View File
@@ -1 +1 @@
0.9 1.1
-17
View File
@@ -1,17 +0,0 @@
import os
import shutil
PYTHONBREW_ROOT = '/tmp/pythonbrew.test'
TESTPY_VERSION = ['2.4.6', '2.5.5', '2.6.6', '3.2']
def cleanall():
if os.path.isdir(PYTHONBREW_ROOT):
shutil.rmtree(PYTHONBREW_ROOT)
def setup():
os.environ['PYTHONBREW_ROOT'] = PYTHONBREW_ROOT
cleanall()
from pythonbrew.installer import install_pythonbrew
install_pythonbrew()
def teardown():
cleanall()
-11
View File
@@ -1,11 +0,0 @@
class UpdateOptions(object):
master = False
develop = False
config = False
force = False
def test_update():
from pythonbrew.commands.update import UpdateCommand
c = UpdateCommand()
c.run_command(UpdateOptions(), None)
-4
View File
@@ -1,4 +0,0 @@
def test_help():
from pythonbrew.commands.help import HelpCommand
c = HelpCommand()
c.run_command(None, None)
-4
View File
@@ -1,4 +0,0 @@
def test_version():
from pythonbrew.commands.version import VersionCommand
c = VersionCommand()
c.run_command(None, None)
-18
View File
@@ -1,18 +0,0 @@
from tests import TESTPY_VERSION
class InstallOptions(object):
force = True
no_test = True
verbose = False
configure = ""
no_setuptools = False
alias = None
jobs = 2
def test_install():
from pythonbrew.commands.install import InstallCommand
py_version = TESTPY_VERSION.pop(0)
c = InstallCommand()
c.run_command(InstallOptions(), [py_version]) # pybrew install -f -j2 2.4.6
c.run_command(InstallOptions(), TESTPY_VERSION) # pybrew install -f -j2 2.5.6 2.6.6 3.2
-7
View File
@@ -1,7 +0,0 @@
from tests import TESTPY_VERSION
def test_switch():
from pythonbrew.commands.switch import SwitchCommand
for py_version in TESTPY_VERSION:
c = SwitchCommand()
c.run_command(None, [py_version])
-7
View File
@@ -1,7 +0,0 @@
from tests import TESTPY_VERSION
def test_use():
from pythonbrew.commands.use import UseCommand
for py_version in TESTPY_VERSION:
c = UseCommand()
c.run_command(None, [py_version])
-4
View File
@@ -1,4 +0,0 @@
def test_off():
from pythonbrew.commands.off import OffCommand
c = OffCommand()
c.run_command(None, None)
-8
View File
@@ -1,8 +0,0 @@
class ListOptions(object):
all_versions = False
known = False
def test_list():
from pythonbrew.commands.list import ListCommand
c = ListCommand()
c.run_command(ListOptions(), None)
-22
View File
@@ -1,22 +0,0 @@
from tests import PYTHONBREW_ROOT
import os
TESTPY_FILE = os.path.join(PYTHONBREW_ROOT, 'etc', 'testfile.py')
class PyOptions(object):
pythons = []
verbose = False
bin = "python"
options = ""
def _create_pyfile():
fp = open(TESTPY_FILE, 'w')
fp.write("print('test')")
fp.close()
def test_py():
from pythonbrew.commands.py import PyCommand
_create_pyfile()
c = PyCommand()
c.run_command(PyOptions(), [TESTPY_FILE])
-31
View File
@@ -1,31 +0,0 @@
from tests import PYTHONBREW_ROOT
import os
BUILDOUT_DIR = os.path.join(PYTHONBREW_ROOT, 'etc', 'buildout')
BUILDOUT_CONF = os.path.join(BUILDOUT_DIR, 'buildout.cfg')
def _create_buildout_cfg():
if not os.path.isdir(BUILDOUT_DIR):
os.makedirs(BUILDOUT_DIR)
fp = open(BUILDOUT_CONF, 'w')
fp.write("""[buildout]
parts = test
develop =
[test]
recipe =
eggs =""")
fp.close()
class BuildoutOptions(object):
python = '2.6.6'
def test_buildout():
from pythonbrew.commands.buildout import BuildoutCommand
# Runs the buildout
_create_buildout_cfg()
os.chdir(BUILDOUT_DIR)
c = BuildoutCommand()
c.run_command(BuildoutOptions(), [])
-11
View File
@@ -1,11 +0,0 @@
class VenvOptions(object):
python = '2.6.6'
all = False
def test_venv():
from pythonbrew.commands.venv import VenvCommand
c = VenvCommand()
c.run_command(VenvOptions(), ['create', 'aaa'])
c.run_command(VenvOptions(), ['list'])
c.run_command(VenvOptions(), ['use', 'aaa'])
c.run_command(VenvOptions(), ['delete', 'aaa'])
-4
View File
@@ -1,4 +0,0 @@
def test_clean():
from pythonbrew.commands.cleanup import CleanupCommand
c = CleanupCommand()
c.run_command(None, None)
-7
View File
@@ -1,7 +0,0 @@
from tests import TESTPY_VERSION
def test_uninstall():
from pythonbrew.commands.uninstall import UninstallCommand
for py_version in TESTPY_VERSION:
c = UninstallCommand()
c.run_command(None, [py_version])
-4
View File
@@ -1,4 +0,0 @@
def test_clean():
from pythonbrew.commands.cleanup import CleanupCommand
c = CleanupCommand()
c.run_command(None, None)
+138
View File
@@ -0,0 +1,138 @@
# coding=utf-8
#---------------------------------------------------------------------------
# Copyright 2011 utahta
#---------------------------------------------------------------------------
import os
import shutil
#---------------------------------------------------------------------------
# Settings
#---------------------------------------------------------------------------
PYTHONBREW_ROOT = '/tmp/pythonbrew.test'
TESTPY_VERSION = ['2.4.6', '2.5.5', '2.6.6', '3.2']
def _cleanall():
if os.path.isdir(PYTHONBREW_ROOT):
shutil.rmtree(PYTHONBREW_ROOT)
def _install_pythonbrew():
from pythonbrew.installer import install_pythonbrew
install_pythonbrew()
def setup():
os.environ['PYTHONBREW_ROOT'] = PYTHONBREW_ROOT
_cleanall()
_install_pythonbrew()
def teardown():
_cleanall()
class Options(object):
def __init__(self, opts):
for (k,v) in opts.items():
setattr(self, k, v)
#---------------------------------------------------------------------------
# Test
#---------------------------------------------------------------------------
def test_00_update():
from pythonbrew.commands.update import UpdateCommand
c = UpdateCommand()
c.run_command(Options({'master':False, 'develop':False, 'config':False, 'force':False}),
None)
def test_01_help():
from pythonbrew.commands.help import HelpCommand
c = HelpCommand()
c.run_command(None, None)
def test_02_version():
from pythonbrew.commands.version import VersionCommand
c = VersionCommand()
c.run_command(None, None)
def test_03_install():
from pythonbrew.commands.install import InstallCommand
py_version = TESTPY_VERSION.pop(0)
o = Options({'force':True, 'no_test':True, 'verbose':False, 'configure':"",
'no_setuptools': False, 'alias':None, 'jobs':2,
'framework':False, 'universal':False, 'static':False})
c = InstallCommand()
c.run_command(o, [py_version]) # pybrew install -f -j2 2.4.6
c.run_command(o, TESTPY_VERSION) # pybrew install -f -j2 2.5.6 2.6.6 3.2
def test_04_switch():
from pythonbrew.commands.switch import SwitchCommand
for py_version in TESTPY_VERSION:
c = SwitchCommand()
c.run_command(None, [py_version])
def test_05_use():
from pythonbrew.commands.use import UseCommand
for py_version in TESTPY_VERSION:
c = UseCommand()
c.run_command(None, [py_version])
def test_06_off():
from pythonbrew.commands.off import OffCommand
c = OffCommand()
c.run_command(None, None)
def test_07_list():
from pythonbrew.commands.list import ListCommand
c = ListCommand()
c.run_command(Options({'all_versions':False, 'known':False}),
None)
def test_08_py():
from pythonbrew.commands.py import PyCommand
TESTPY_FILE = os.path.join(PYTHONBREW_ROOT, 'etc', 'testfile.py')
fp = open(TESTPY_FILE, 'w')
fp.write("print('test')")
fp.close()
# Runs the python script
c = PyCommand()
c.run_command(Options({'pythons':[], 'verbose':False, 'bin':"python", 'options':""}),
[TESTPY_FILE])
def test_09_buildout():
from pythonbrew.commands.buildout import BuildoutCommand
BUILDOUT_DIR = os.path.join(PYTHONBREW_ROOT, 'etc', 'buildout')
BUILDOUT_CONF = os.path.join(BUILDOUT_DIR, 'buildout.cfg')
if not os.path.isdir(BUILDOUT_DIR):
os.makedirs(BUILDOUT_DIR)
fp = open(BUILDOUT_CONF, 'w')
fp.write("""[buildout]
parts = test
develop =
[test]
recipe =
eggs =""")
fp.close()
# Runs the buildout
os.chdir(BUILDOUT_DIR)
c = BuildoutCommand()
c.run_command(Options({'python':'2.6.6'}), [])
def test_10_venv():
from pythonbrew.commands.venv import VenvCommand
c = VenvCommand()
o = Options({'python':'2.6.6', 'all':False, 'no_site_packages':False})
c.run_command(o, ['init'])
c.run_command(o, ['create', 'aaa'])
c.run_command(o, ['list'])
c.run_command(o, ['use', 'aaa'])
c.run_command(o, ['delete', 'aaa'])
def test_11_uninstall():
from pythonbrew.commands.uninstall import UninstallCommand
for py_version in TESTPY_VERSION:
c = UninstallCommand()
c.run_command(None, [py_version])
def test_12_clean():
from pythonbrew.commands.cleanup import CleanupCommand
c = CleanupCommand()
c.run_command(None, None)