A pynt of Python build.

Related tags

Build Tools pynt
Overview

Build Status

A pynt of Python build.

Raghunandan Rao

Features

  • Easy to learn.
  • Build tasks are just python funtions.
  • Manages dependencies between tasks.
  • Automatically generates a command line interface.
  • Rake style param passing to tasks
  • Supports python 2.7 and python 3.x

Installation

You can install pynt from the Python Package Index (PyPI) or from source.

Using pip

$ pip install pynt

Using easy_install

$ easy_install pynt

Example

The build script is written in pure Python and pynt takes care of managing any dependencies between tasks and generating a command line interface.

Writing build tasks is really simple, all you need to know is the @task decorator. Tasks are just regular Python functions marked with the @task() decorator. Dependencies are specified with @task() too. Tasks can be ignored with the @task(ignore=True). Disabling a task is an useful feature to have in situations where you have one task that a lot of other tasks depend on and you want to quickly remove it from the dependency chains of all the dependent tasks. Note that any task whose name starts with an underscore(_) will be considered private. Private tasks are not listed in with pynt -l, but they can still be run with pynt _private_task_name

build.py

#!/usr/bin/python

import sys
from pynt import task

@task()
def clean():
    '''Clean build directory.'''
    print 'Cleaning build directory...'

@task()
def _copy_resources():
    '''Copy resource files. This is a private task. "pynt -l" will not list this'''
    print('Copying resource files')

@task(clean, _copy_resources)
def html(target='.'):
    '''Generate HTML.'''
    print 'Generating HTML in directory "%s"' %  target

@task(clean, _copy_resources, ignore=True)
def images():
    '''Prepare images.'''
    print 'Preparing images...'

@task(html,images)
def start_server(server='localhost', port = '80'):
    '''Start the server'''
    print 'Starting server at %s:%s' % (server, port)

@task(start_server) #Depends on task with all optional params
def stop_server():
    print 'Stopping server....'

@task()
def copy_file(src, dest):
    print 'Copying from %s to %s' % (src, dest)

@task()
def echo(*args,**kwargs):
    print args
    print kwargs
    
# Default task (if specified) is run when no task is specified in the command line
# make sure you define the variable __DEFAULT__ after the task is defined
# A good convention is to define it at the end of the module
# __DEFAULT__ is an optional member

__DEFAULT__=start_server

Running pynt tasks

The command line interface and help is automatically generated. Task descriptions are extracted from function docstrings.

$ pynt -h
usage: pynt [-h] [-l] [-v] [-f file] [task [task ...]]

positional arguments:
  task                  perform specified task and all its dependencies

optional arguments:
  -h, --help            show this help message and exit
  -l, --list-tasks      List the tasks
  -v, --version         Display the version information
  -f file, --file file  Build file to read the tasks from. Default is
                        'build.py'
$ pynt -l
Tasks in build file ./build.py:
  clean                       Clean build directory.
  copy_file                   
  echo                        
  html                        Generate HTML.
  images           [Ignored]  Prepare images.
  start_server     [Default]  Start the server
  stop_server                 

Powered by pynt - A Lightweight Python Build Tool.

pynt takes care of dependencies between tasks. In the following case start_server depends on clean, html and image generation (image task is ignored).

$ pynt #Runs the default task start_server. It does exactly what "pynt start_server" would do.
[ example.py - Starting task "clean" ]
Cleaning build directory...
[ example.py - Completed task "clean" ]
[ example.py - Starting task "html" ]
Generating HTML in directory "."
[ example.py - Completed task "html" ]
[ example.py - Ignoring task "images" ]
[ example.py - Starting task "start_server" ]
Starting server at localhost:80
[ example.py - Completed task "start_server" ]

The first few characters of the task name is enough to execute the task, as long as the partial name is unambigious. You can specify multiple tasks to run in the commandline. Again the dependencies are taken taken care of.

$ pynt cle ht cl
[ example.py - Starting task "clean" ]
Cleaning build directory...
[ example.py - Completed task "clean" ]
[ example.py - Starting task "html" ]
Generating HTML in directory "."
[ example.py - Completed task "html" ]
[ example.py - Starting task "clean" ]
Cleaning build directory...
[ example.py - Completed task "clean" ]

The 'html' task dependency 'clean' is run only once. But clean can be explicitly run again later.

pynt tasks can accept parameters from commandline.

$ pynt "copy_file[/path/to/foo, path_to_bar]"
[ example.py - Starting task "clean" ]
Cleaning build directory...
[ example.py - Completed task "clean" ]
[ example.py - Starting task "copy_file" ]
Copying from /path/to/foo to path_to_bar
[ example.py - Completed task "copy_file" ]

pynt can also accept keyword arguments.

$ pynt start[port=8888]
[ example.py - Starting task "clean" ]
Cleaning build directory...
[ example.py - Completed task "clean" ]
[ example.py - Starting task "html" ]
Generating HTML in directory "."
[ example.py - Completed task "html" ]
[ example.py - Ignoring task "images" ]
[ example.py - Starting task "start_server" ]
Starting server at localhost:8888
[ example.py - Completed task "start_server" ]

$ pynt echo[hello,world,foo=bar,blah=123]
[ example.py - Starting task "echo" ]
('hello', 'world')
{'blah': '123', 'foo': 'bar'}
[ example.py - Completed task "echo" ]

Organizing build scripts

You can break up your build files into modules and simple import them into your main build file.

from deploy_tasks import *
from test_tasks import functional_tests, report_coverage

pynt-contrib

pynt-contrib contains a set of extra tasks/utilities. The idea is to keep this package simple and bloat-free.

Contributors/Contributing

If you want to make changes the repo is at https://github.com/rags/pynt. You will need pytest to run the tests

$ ./b t

It will be great if you can raise a pull request once you are done.

If you find any bugs or need new features please raise a ticket in the issues section of the github repo.

License

pynt is licensed under a MIT license

Comments
  • Ability to hide a task from doc output

    Ability to hide a task from doc output

    I have a complex chain of tasks that I don't want to be all exposed/available when using pynt.

    I can use internal python functions instead, but I really like the simplicity of chaining tasks and having consistent logs etc...

    Adding @task(hide=True) might be a nice addition

    So it looks something like that: @task(hide=True) def build(): '''Build for distribution'''

    @task(hide=True) def upload(): '''Upload build'''

    @task(hide=True) def install(): '''Install new build distribution'''

    @task() def restart_server: ''Restart the server'''

    @task(build, upload, install, restart_server) def deploy_prod(): '''Build & deploy app to production server. Then restart server.''' print("Deployment Complete!")

    At the moment, they are all exposed as tasks, and can appear in pynt output: Tasks in build file build.py: build Build for distribution clean Clean build directory. deploy_prod Build & deploy app to production server. Then restarts server. install Install new build distribution'' restart_server Restart pserve on remote upload Upload the latest build to server

    enhancement 
    opened by bachirelkhoury 17
  • Utility functions

    Utility functions

    Would you like any of these functions? If so, I can submit them as a pull request (with tests).

    https://github.com/WimpyAnalytics/pynt-of-django/blob/master/pyntofdjango/utils.py

    opened by ivanvenosdel 7
  • [question] How to get the parameters of a task? Is it possible?

    [question] How to get the parameters of a task? Is it possible?

    I would like to use pynt for a Java project. The caller task looks like this:

    @task()
    def run():
        cmd = "java -cp build/classes/java/main adder.Adder"
        print(cmd)
        os.system(cmd)
    

    Let's suppose that we can pass command-line arguments to the Java program:

    bash$ java -cp build/classes/java/main adder.Adder 5 6
    11
    

    and it adds them together. Would it be possible to pass these arguments to a task and then forward them to the Java program? I want a call like this:

    bash$ pynt run 5 6
    11
    

    At the moment pynt thinks that "5" is another task and drops an error that it doesn't exist.

    opened by jabbalaci 3
  • @task(hide=True) support

    @task(hide=True) support

    If @task(hide=True) is set, the given task won't appear in the auto-generated docs. It's useful if you want to hide sub-tasks and you only want to see the main tasks in the generated list.

    opened by jabbalaci 3
  • add it to a Wikipedia article

    add it to a Wikipedia article

    It would be a good idea to add your build tool to this list: https://en.wikipedia.org/wiki/List_of_build_automation_software . SCons is there, another build tool written in Python.

    I also want to say thanks for this project! It's perfect for my needs.

    opened by jabbalaci 2
  • Spelling errors for

    Spelling errors for "pynt -h"

    pynt -h produces: C:\Users\Bruce>pynt -h usage: pynt-script.py [-h] [-l] [-f file] [task [task ...]]

    positional arguments: task perform specified task and all it's dependancies ...

    On the last line shown above, the "it's" should be "its" and "dependancies" should be "dependencies"

    bug 
    opened by BruceEckel 2
  • Documentation

    Documentation

    I can't tell if I'm missing where the documentation is, or if the page (http://rags.github.io/pynt/) is supposed to be the documentation. If the latter, there's a line:

    "Tasks can be ignored with the task(ignore=True)"

    I can't figure out what this means.

    I like the design, BTW. Very clean.

    opened by BruceEckel 2
  • Use of

    Use of "its" vs. "it's"

    Several places in the help you say "it's" which means "it is" when you actually want to use a possessive "its"

    The easiest way to test this is when you see an "it's", say it out loud "it is," and see if that makes sense. If it doesn't, remove the apostrophe.

    opened by BruceEckel 2
  • _taskname means a hidden task

    _taskname means a hidden task

    Instead of @task(hide=True), simply rename your task. If the name of the task starts with an underscore, then it's a hidden task, thus it won't appear in the auto-generated docs.

    opened by jabbalaci 1
  • Using pynt on build server

    Using pynt on build server

    Hi, I really like pynt and would like to use it as a build tool for some of my python projects. My builds are already using docker to allow me to create a container, install my dependencies and then run the tests. To use pynt as a build system I need to install it outside the container on the build server. Do you have any ideas on the easiest way to do that (assuming I can't just pip install things on the build server)?

    opened by barakschiller 1
  • Added ability to enforce strict task name argument matching

    Added ability to enforce strict task name argument matching

    Hi,

    Sometimes the task name matching feature can be a dangerous thing and one might only want to allow exactly matching task names as arguments.

    This merge request introduces the ability to add the statement __TASK_NAME_RESOLVER__ = 'strict' to the build file to tell pynt to only accept fully matching task names.

    Unit tests have been updated.

    Thanks, Torben

    opened by tgiesselmann-ep 0
  • Enhancement:  Markdown output from docstrings

    Enhancement: Markdown output from docstrings

    Is there any interest in the community for a Markdown output from the @task() docstrings? If so, I can submit a PR.

    In my project, I adopted the standard of:

    @task()
    def start_server(server='localhost', port = '80'):
        """Start the server
    
        This task starts the HTTP server on localhost:80 (by default)
    
        - Args:
            - `server` (`str`, optional): The server IP address. Defaults to 'localhost'.
            - `port` (`str`, optional): The port number. Defaults to '80'.
        """
    
        print('Starting server at %s:%s' % (server, port))
    
    @task(start_server) #Depends on task with all optional params
    def stop_server():
        """Stop the server
    
        This task stops the running server
        """
        print('Stopping server....')
    

    This would create the following output:

    $ pynt -l -m

    Raw

    ---
    ## start_server
    
    `Start the server`
    
    This task starts the HTTP server on localhost:80 (by default)
    
    - Args:
        - `server` (`str`, optional): The server IP address. Defaults to 'localhost'.
        - `port` (`str`, optional): The port number. Defaults to '80'.
    
    ---
    ## stop_server
    
    `Stop the server`
    
    This task stops the running server
    
    

    Formatted:


    start_server

    Start the server

    This task starts the HTTP server on localhost:80 (by default)

    • Args:
      • server (str, optional): The server IP address. Defaults to 'localhost'.
      • port (str, optional): The port number. Defaults to '80'.

    stop_server

    Stop the server

    This task stops the running server

    opened by drmikecrowe 2
  • Tests fail because names of pytest executable are hardcoded

    Tests fail because names of pytest executable are hardcoded

    It happens because of this:

    https://github.com/rags/pynt/blob/c0fbbc4c0c6c1ccbbf11a744fb62d33c78ac0ae0/build.py#L18

    In my system, I have both Python 2 and 3 (maybe it's worth dropping Python 2 support already?). Executables are named py.test and py.test3.

    To maintain backwards compatibility, it's probably worth wrapping those subprocess calls and if they fail - try generic names.

    opened by ghost 1
  • Feature request: better logging for nested tasks

    Feature request: better logging for nested tasks

    Use case: I have a main task that performs actions on items of an iterable, so instead of specifying the one-item task as dependency, I call it directly. Here's my code:

    #!/usr/bin/env python3
    
    from pynt import task
    
    ITEMS = ["foo", "bar"]
    
    
    @task()
    def item_task(item):
        print(item)
    
    
    @task()
    def main_task():
        for item in ITEMS:
            item_task(item)
    
    
    __DEFAULT__ = main_task
    

    This is the output I'm getting:

    [ build.py - Starting task "main_task" ]
    foo
    bar
    [ build.py - Completed task "main_task" ]
    

    Since item_task() is a task too, I'd prefer the following output:

    [ build.py - Starting task "main_task" ]
    [ build.py - Starting task "item_task" with argument "foo"]
    foo
    [ build.py - Completed task "item_task" ]
    [ build.py - Starting task "item_task" with argument "bar"]
    bar
    [ build.py - Completed task "item_task" ]
    [ build.py - Completed task "main_task" ]
    

    Maybe even with nested tasks indented:

    [ build.py - Starting task "main_task" ]
        [ build.py - Starting task "item_task" with argument "foo"]
        foo
        [ build.py - Completed task "item_task" ]
        [ build.py - Starting task "item_task" with argument "bar"]
        bar
        [ build.py - Completed task "item_task" ]
    [ build.py - Completed task "main_task" ]
    
    opened by ghost 9
  • Allow moving code out of the build script towards separate python files.

    Allow moving code out of the build script towards separate python files.

    The directory of the build script is not part of Python's import path inside the pynt process, hence it is not possible to import modules which reside beneath the same directory as the module.

    It can be solved by amending the Path with the directory of the build script.

    opened by THeinemann 0
🔨🐍Make-like build automation tool for Python projects with extensive DSL features.

Pyke (WIP, Beta Release) Make-like build automation tool for Python projects with extensive DSL features. Features: Users can specify tasks, subtasks,

Ire 17 Jul 5, 2022
A Star Trek Online build tool in Python

SETS - STO Equipment and Trait Selector A Star Trek Online build tool in Python Description Pre-alpha version of build tool for STO Getting Started De

Star Trek Online Community Developers 7 Nov 12, 2022
Clang-based cross platform build system written in Python

Clang-build Find the full documentation at https://clang-build.readthedocs.io First steps Customisations Multiple targets Multiple projects Defaults M

Trick 17 9 Jun 29, 2022
Official project repository for the Setuptools build system

See the Installation Instructions in the Python Packaging User's Guide for instructions on installing, upgrading, and uninstalling Setuptools. Questio

Python Packaging Authority 1.9k Jan 8, 2023
The Meson Build System

Meson® is a project to create the best possible next-generation build system. Status Dependencies Python (version 3.6 or newer) Ninja (version 1.8.2 o

The Meson Build System 4.4k Jan 2, 2023
The Pants Build System

Pants Build System Pants is a scalable build system for monorepos: codebases containing multiple projects, often using multiple programming languages

Pants Build 2.5k Jan 7, 2023
The official binary distribution format for Python

wheel This library is the reference implementation of the Python wheel packaging standard, as defined in PEP 427. It has two different roles: A setupt

Python Packaging Authority 368 Dec 23, 2022
Python-based continuous integration testing framework; your pull requests are more than welcome!

Buildbot The Continuous Integration Framework Buildbot is based on original work from Brian Warner, and currently maintained by the Botherders. Visit

Buildbot 5k Jan 5, 2023
Simplified packaging of Python modules

Flit is a simple way to put Python packages and modules on PyPI. It tries to require less thought about packaging and help you avoid common mistakes.

Thomas Kluyver 1.9k Jan 5, 2023
Python-based project scripting.

Paver - Easy Scripting for Software Projects Web: https://pythonhosted.org/Paver/ Download: https://pypi.python.org/pypi/Paver/ Source: https://github

Paver community 452 Dec 9, 2022
Buildout is a deployment automation tool written in and extended with Python

Buildout Buildout is a project designed to solve 2 problems: Application-centric assembly and deployment Assembly runs the gamut from stitching togeth

buildout 552 Nov 26, 2022
Python program for installing many tools automatically

Tool Installer is a script made with python which help user in installing tools automatically

Spider Anongreyhat 6 Mar 13, 2022
PyPacker: a dumb little script for turning Python apps into standalone executable packages on Windows

PyPacker: a dumb little script for turning Python apps into standalone executable packages on Windows PyPacker is my attempt at creating a way to make

Serdar Yegulalp 9 Mar 15, 2022
This is a python helper package for Telebirr H5 Web payment integration helper.

Telebirr This is a python helper package for Telebirr H5 Web payment integration helper. The use case for this interface is payment via web. Third par

null 24 Dec 13, 2022
Python package used on Hardfight projects to make building, testing and deploying easy.

Hardfight Devtools Build, test and deploy Hardfight projects easly ?? What is it Devtools is a Python tool to make building, testing and deploying int

Hardfight 1 Dec 5, 2021
Ubuntu env build; Nginx build; DB build;

Deploy 介绍 Deploy related scripts bitnami Dependencies Ubuntu openssl envsubst docker v18.06.3 docker-compose init base env upload https://gitlab-runn

Colin(liuji) 10 Dec 1, 2021
:package: :fire: Python project management. Manage packages: convert between formats, lock, install, resolve, isolate, test, build graph, show outdated, audit. Manage venvs, build package, bump version.

THE PROJECT IS ARCHIVED Forks: https://github.com/orsinium/forks DepHell -- project management for Python. Why it is better than all other tools: Form

DepHell 1.7k Dec 30, 2022
An easy way to build PyTorch datasets. Modularly build datasets and automatically cache processed results

EasyDatas An easy way to build PyTorch datasets. Modularly build datasets and automatically cache processed results Installation pip install git+https

Ximing Yang 4 Dec 14, 2021
Official Python client for the MonkeyLearn API. Build and consume machine learning models for language processing from your Python apps.

MonkeyLearn API for Python Official Python client for the MonkeyLearn API. Build and run machine learning models for language processing from your Pyt

MonkeyLearn 157 Nov 22, 2022
Learn to build a Python Desktop GUI app using pywebview, Python, JavaScript, HTML, & CSS.

Python Desktop App Learn how to make a desktop GUI application using Python, JavaScript, HTML, & CSS all thanks to pywebview. pywebview is essentially

Coding For Entrepreneurs 55 Jan 5, 2023