Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #1386 (closed enhancement: fixed)

Opened 10 years ago

Last modified 9 years ago

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

Reported by: chrisz Owned by: 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 Download (4.7 KB) - added by Chris Arndt 9 years ago.
Test-1.tar.bz2 Download (146.9 KB) - added by Chris Arndt 9 years ago.

Change History

comment:1 Changed 10 years ago 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',
        ],
    },

comment:2 Changed 10 years ago by Chris Arndt

  • Milestone changed from 1.0.3 to 1.0.4

Batch promoting 1.0.3 tickets to Milestone 1.0.4

comment:3 Changed 10 years ago 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.

comment:4 Changed 10 years ago by chrisz

Seems reasonable to me.

comment:5 Changed 9 years ago by faide

  • Milestone changed from 1.0.4 to 1.1

Seem really interesting for 1.1.

Changed 9 years ago by Chris Arndt

Changed 9 years ago by Chris Arndt

comment:6 Changed 9 years ago 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?).

comment:7 Changed 9 years ago 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.

Note: See TracTickets for help on using tickets.