Ticket #1386 (closed enhancement: fixed)

Opened 1 year ago

Last modified 6 months ago

[PATCH] Use an entry point scripts for project start scripts

Reported by: chrisz Assigned to: anonymous
Priority: normal Milestone: 1.0.4
Component: TurboGears Version: 1.0.2
Severity: normal Keywords:
Cc:

Description

When you package a TG project with python setup.py bdist_egg und Windows and then install the resulting egg with easy_install under Linux, then the start script will be installed under /usr/bin, but its "shebang" line will point to a non-existing Python executable under Windows. When I install the egg on another Windows machine, then the start script will be installed under C:\Python\Scripts\ where it cannot be easily executed. Both problems can be solved by using an "entry point script" for the start script. Since they involve some moving of files, I'll describe the necessary changes in the following instead of uploading a patch file.

Attachments

start-script.patch (4.7 kB) - added by Chris Arndt on 11/27/07 13:06:22.
Test-1.tar.bz2 (146.9 kB) - added by Chris Arndt on 11/27/07 13:09:11.

Change History

05/13/07 00:37:35 changed by chrisz

  • type changed from defect to enhancement.

* copy qstemplates/quickstart/start-+package+.py_tmpl to qstemplates\quickstart\+package+.start.py_tmpl

* in +package+.start.py_tmpl, replace the last line

start_server(Root())

with the following lines:

from controllers import Root
    
def start():
    start_server(Root())

if __name__ == "__main__":
   start()

and replace the following lines

if len(sys.argv) > 1:
    update_config(configfile=sys.argv[1],
        modulename="${package}.config")
elif exists(join(dirname(__file__), "setup.py")):
    update_config(configfile="dev.cfg",modulename="${package}.config")
else:
    update_config(configfile="prod.cfg",modulename="${package}.config")

with these lines:

setupdir = dirname(dirname(__file__))
if len(sys.argv) > 1:
    update_config(configfile=sys.argv[1],
        modulename="${package}.config")
elif exists(join(setupdir, "setup.py")):
    update_config(configfile=join(setupdir, "dev.cfg"), modulename="${package}.config")
else:
    update_config(configfile="prod.cfg",modulename="${package}.config")

* replace the content of qstemplates\quickstart\start-+package+.py_tmpl with the following:

#!${sys_executable}
    
from ${package}.start import start
    
if __name__ == "__main__":
   start()

* in qstemplates\quickstart\setup.py_tmpl, remove the line

    scripts = ["start-${package}.py"],

and replace it with the following:

    entry_points = {
        'console_scripts': [
            'start-${package} = ${package}.start:start',
        ],
    },

07/23/07 13:26:46 changed by Chris Arndt

  • milestone changed from 1.0.3 to 1.0.4.

Batch promoting 1.0.3 tickets to Milestone 1.0.4

07/23/07 13:33:02 changed by Chris Arndt

I suggest putting the start script as a module in a 'commands' sub-package in new projects.

Since this will effect the documented behaviour, I suggest targetting this for release 1.1.

07/23/07 16:02:56 changed by chrisz

Seems reasonable to me.

11/25/07 18:14:12 changed by faide

  • milestone changed from 1.0.4 to 1.1.

Seem really interesting for 1.1.

11/27/07 13:06:22 changed by Chris Arndt

  • attachment start-script.patch added.

11/27/07 13:09:11 changed by Chris Arndt

  • attachment Test-1.tar.bz2 added.

11/27/07 13:13:46 changed by Chris Arndt

I have attached a patch against branch 1.1 r3774. I also attached a test project created with the patch applied that demonstrates the new project structure. This should work with a current 1.1 checkout. The tar/bz2 also contains an egg file, so you can test the automatic dependency installation.

Unfortunately you still have to install TG 1.1 manually first, since there is no released package yet. You also have to install tgmochikit from SVN and TurboKid?>=1.0.4 (bug?).

11/27/07 17:49:02 changed by Chris Arndt

  • status changed from new to closed.
  • resolution set to fixed.
  • milestone changed from 1.1 to 1.0.4.

Fixed in r3776 and r3778.

These changesets introduce the following changes:

1) For a quickstarted project, the code from the start-<project>.py script is moved into <package>/commands.py.

2) start-<project>.py is replaced with a tiny script for running the project from the project directory during development.

3) setup.py declares a console script entry point for the start() function in <package>/commands.py, so that easy_install creates a start script.

4) the start() function in <package>/commands.py behaves a bit different from the old start script:

First look on the command line for a desired config file, if it's not on the command line, then look for 'setup.py' in the parent directory. If it's there, load configuration from a file called 'dev.cfg'. If it's not there, the project is probably installed and we'll look first for a file called 'prod.cfg' in the current directory and then for a default config file called 'default.cfg' packaged in a 'config' sub directory of the egg (see 5).

If all above fails, raise a ConfigurationError.

Previously, the start script would only look for 'dev.cfg' and 'prod.cfg' in the directory containing the start script or on the command line. With the new strategy the 'dev.cfg' file will be found if you run the start script (2) in the project directory (the current directory does not have to be the project directory, though other configuration settings, like the database URI or log file paths may rely on this).

If you want to run in production mode, you can either give the config file on the command line or just have a 'prod.cfg' file in the current directory. This will work regardless of whether this is your project directory or somewhere else.

The exiting new feature is, that if you have a default config file packaged in your egg, you don't need to install a configuration file at all, the egg will be self-contained (you might still need to create a database, though).

5) setup.py has a line "data_files = [('config', ['default.cfg'])]" (commented out by default) and an explanatory comment that allows you to package a default configuration in your egg in a way that it can be found by the start() function.

6) Minor changes: encoding declaration in start script, commands.py and setup.py, code refactoring, import cleanup / re-ordering, doc strings for start script and commands.py.

As a further enhancement I would propose turning the "commands" module into a subpackage for the "quickstartbig" template.