{ "info": { "author": "Teriks", "author_email": "Teriks@users.noreply.github.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Build Tools", "Topic :: Utilities" ], "description": "About pake\n==========\n\n|Master Documentation Status| |codecov|\n\npake is a make-like python build utility where tasks, dependencies and\nbuild commands can be expressed entirely in python, similar to ruby\nrake.\n\npake supports automatic file/directory change detection when dealing with\ntask inputs and outputs, and also parallel builds.\n\npake requires python3.5+\n\n\nThis readme contains only a little information about how to use pake, please\ncheckout the latest documentation at the links above for an expansive\noverview on how pake works and how pakefiles should be written.\n\nInstalling\n==========\n\nNote: pake is Alpha and likely to change some.\n\n\nTo install the latest release use:\n\n``sudo pip3 install python-pake --upgrade``\n\n\nIf you want to install the development branch you can use:\n\n``sudo pip3 install git+git://github.com/Teriks/pake@develop``\n\n\nExample project using pake\n==========================\n\nI am using libasm\\_io to help test pake and have included a pakefile\nbuild along side the makefiles in that project.\n\nhttps://github.com/Teriks/libasm\\_io\n\n\nSee the build with pake section of **libasm\\_io/build-readme.md** here_.\n\n.. _here: https://github.com/Teriks/libasm_io/blob/develop/build-readme.md#build-with-pake\n\nWriting Basic Tasks\n===================\n\nHere's a contrived pake demo:\n\n.. code-block:: python\n\n import pake\n\n # Tasks are registered the the pake.Pake object\n # returned by pake's initialization call, using the task decorator.\n\n pk = pake.init()\n\n # Try to grab a command line define.\n # In particular the value of -D CC=..\n # CC will default to 'gcc' in this case if\n # it was not specified.\n\n CC = pk.get_define('CC', 'gcc')\n\n # you can also use the syntax: pk[\"CC\"] to\n # attempt to get the defines value, if it is not\n # defined then it will return None.\n\n # ===\n\n # If you just have a single input/output, there is no\n # need to pass a list to the tasks inputs/outputs\n\n @pk.task(i='foo/foo.c', o='foo/foo.o')\n def foo(ctx):\n # Execute a program (gcc) and print its stdout/stderr to the tasks output.\n\n # ctx.call can be passed a command line as variadic arguments, an iterable, or\n # as a string. It will automatically flatten out non string iterables in your variadic\n # arguments or iterable object, so you can pass an iterable such as ctx.inputs\n # as part of your full command line invocation instead of trying to create the command\n # line by concatenating lists or using the indexer on ctx.inputs/ctx.outputs\n\n ctx.call(CC, '-c', ctx.inputs, '-o', ctx.outputs)\n\n\n # Pake can handle file change detection with multiple inputs\n # and outputs. If the amount of inputs is different from\n # the amount of outputs, the task is considered to be out\n # of date if any input file is newer than any output file.\n\n # When the amount of inputs is equal to the amount of outputs,\n # pake will compare each input to its corresponding output\n # and collect out of date input/outputs into ctx.outdated_inputs\n # and ctx.outdated_outputs respectively. ctx.outdated_pairs\n # can be used to get a generator over (input, output) pairs,\n # it is shorthand for zip(ctx.outdated_inputs, ctx.outdated_outputs)\n\n @pk.task(i=pake.glob('bar/*.c'), o=pake.pattern('bar/%.o'))\n def bar(ctx):\n\n # zip together the outdated inputs and outputs, since they\n # correspond to each other, this iterates of a sequence of python\n # tuple objects in the form (input, output)\n\n for i, o in ctx.outdated_pairs:\n ctx.call(CC, '-c', i, '-o', o)\n\n\n # This task depends on the 'foo' and 'bar' tasks, as\n # specified with the decorators leading parameters.\n # It outputs 'bin/baz' by taking the input 'main.c'\n # and linking it to the object files produced in the other tasks.\n\n @pk.task(foo, bar, o='bin/baz', i='main.c')\n def baz(ctx):\n \"\"\"Use this to build baz\"\"\"\n\n # Documentation strings can be viewed by running 'pake -ti' in\n # the directory the pakefile exists in, it will list all documented\n # tasks with their python doc strings.\n\n # The pake.FileHelper class can be used to preform basic file\n # system operations while printing information about the operations\n # it has completed to the tasks output.\n\n file_helper = pake.FileHelper(ctx)\n\n # Create a bin directory, this won't complain if it exists already\n file_helper.makedirs('bin')\n\n # ctx.dependency_outputs contains a list of all outputs that this\n # tasks immediate dependencies produce\n\n ctx.call(CC, '-o', ctx.outputs, ctx.inputs, ctx.dependency_outputs)\n\n\n @pk.task\n def clean(ctx):\n \"\"\"Clean binaries\"\"\"\n\n file_helper = pake.FileHelper(ctx)\n\n # Clean up using the FileHelper object.\n # Remove the bin directory, this wont complain if 'bin'\n # does not exist.\n\n file_helper.rmtree('bin')\n\n # Glob remove object files from the foo and bar directories\n\n file_helper.glob_remove('foo/*.o')\n file_helper.glob_remove('bar/*.o')\n\n\n # Run pake; The default task that will be executed when\n # none are specified on the command line will be 'baz' in\n # this case.\n\n # The tasks parameter is optional, but if it is not specified\n # here, you will be required to specify a task or tasks on the\n # command line.\n\n pake.run(pk, tasks=baz)\n\n\nOutput from command ``pake``:\n\n.. code-block:: bash\n\n ===== Executing task: \"bar\"\n gcc -c bar/bar.c -o bar/bar.o\n ===== Executing task: \"foo\"\n gcc -c foo/foo.c -o foo/foo.o\n ===== Executing task: \"baz\"\n Created Directory(s): \"bin\"\n gcc -o bin/baz main.c foo/foo.o bar/bar.o\n\n\nOutput from command ``pake clean``:\n\n.. code-block:: bash\n\n ===== Executing task: \"clean\"\n Removed Directory(s): \"bin\"\n Glob Removed Files: \"foo/*.o\"\n Glob Removed Files: \"bar/*.o\"\n\n\nConcurrency Inside Tasks\n========================\n\nWork can be submitted to the threadpool pake is running its tasks on to achieve a\npredictable level of concurrency for sub tasks that is limited by the **--jobs** command line argument,\nor the **jobs** parameter of **pake.run** and **pake.Pake.run**.\n\nExample:\n\n.. code-block:: python\n\n import pake\n\n # functools.partial is used for binding argument values to functions\n\n from functools import partial\n\n\n pk = pake.init()\n\n\n @pk.task(i=pake.glob('src/*.c'), o=pake.pattern('obj/%.o'))\n def build_c(ctx)\n\n file_helper = pake.FileHelper(ctx)\n\n # Make 'obj' directory if it does not exist.\n # This does not complain if it is already there.\n\n file_helper.makedirs('obj')\n\n # Start multitasking\n\n with ctx.multitask() as mt:\n for i, o in ctx.outdated_pairs:\n\n # Read the section 'Output synchronization with ctx.call & ctx.subpake'\n # in the 'Concurrency Inside Tasks` page on http://pake.readthedocs.io\n # for an explanation of 'sync_call' below, and how output\n # synchronization is achieved for ctx.call and ctx.subpake\n\n sync_call = partial(ctx.call,\n collect_output=pk.max_jobs > 1)\n\n # Submit a work function with arguments to the threadpool\n mt.submit(sync_call, ['gcc', '-c', i, '-o', o])\n\n\n @pk.task(build_c, i=pake.glob('obj/*.o'), o='main')\n def build(ctx):\n\n # Utilizing the automatic non string iterable\n # flattening here to pass ctx.inputs and ctx.outputs\n\n ctx.call('gcc', ctx.inputs, '-o', ctx.outputs)\n\n\n pake.run(pk, tasks=build)\n\n\nRunning Sub Pakefiles\n=====================\n\nPake is able to run itself through the use of **pake.TaskContext.subpake**\nand **pake.subpake**.\n\n**pake.subpake** is meant to be used outside of tasks, and can even be\ncalled before pake is initialized.\n\n**pake.TaskContext.subpake** is preferred for use inside of tasks because\nit handles writing to the task's output queue for you, without having to specify\nextra parameters to **pake.subpake** to get it working correctly.\n\n**pake.TaskContext** instance is passed into the single argument of each task function,\nwhich you can in turn call **subpake** from.\n\nDefines can be exported to pakefiles ran with the **subpake** functions using **pake.export**.\n\n**pake.subpake** and **pake.TaskContext.subpake** use the **--stdin-defines** option of\npake to pass exported define values into the new process instance, which means you can overwrite your\nexported define values with **-D/--define** in the subpake command arguments if you need to.\n\nExport / Subpake Example:\n\n.. code-block:: python\n\n import pake\n\n pk = pake.init()\n\n # Try to get the CC define from the command line,\n # default to 'gcc'.\n\n CC = pk.get_define('CC', 'gcc')\n\n # Export the CC variable's value to all invocations\n # of pake.subpake or ctx.subpake as a define that can be\n # retrieved with pk.get_define()\n\n pake.export('CC', CC)\n\n\n # You can also export lists, dictionaries sets and tuples,\n # as long as they only contain literal values.\n # Literal values being: strings, integers, floats; and\n # other lists, dicts, sets and tuples. Collections must only\n # contain literals, or objects that repr() into a parsable literal.\n\n pake.export('CC_FLAGS', ['-Wextra', '-Wall'])\n\n\n # Nesting works with composite literals,\n # as long as everything is a pure literal or something\n # that str()'s into a literal.\n\n pake.export('STUFF',\n ['you',\n ['might',\n ('be',\n ['a',\n {'bad' :\n ['person', ['if', {'you', 'do'}, ('this',) ]]\n }])]])\n\n\n # This export will be overrode in the next call\n pake.export('OVERRIDE_ME', False)\n\n\n # Execute outside of a task, by default the stdout/stderr\n # of the subscript goes to this scripts stdout. The file\n # object to which stdout gets written to can be specified\n # with pake.subpake(..., stdout=(file))\n\n # This command also demonstrates that you can override\n # your exports using the -D/--define option\n\n pake.subpake('sometasks/pakefile.py', 'dotasks', '-D', 'OVERRIDE_ME=True')\n\n\n # This task does not depend on anything or have any inputs/outputs\n # it will basically only run if you explicitly specify it as a default\n # task in pake.run, or specify it on the command line\n\n @pk.task\n def my_phony_task(ctx):\n # Arguments are passed in a variadic parameter...\n\n # Specify that the \"foo\" task is to be ran.\n # The scripts output is written to this tasks output queue\n\n ctx.subpake('library/pakefile.py', 'foo')\n\n\n\n # Run this pake script, with a default task of 'my_phony_task'\n\n pake.run(pk, tasks=my_phony_task)\n\n\nOutput from the example above:\n\n.. code-block:: bash\n\n *** enter subpake[1]:\n pake[1]: Entering Directory \"(REST OF PATH...)/paketest/sometasks\"\n ===== Executing Task: \"dotasks\"\n Do Tasks\n pake[1]: Exiting Directory \"(REST OF PATH...)/paketest/sometasks\"\n *** exit subpake[1]:\n ===== Executing Task: \"my_phony_task\"\n *** enter subpake[1]:\n pake[1]: Entering Directory \"(REST OF PATH...)/paketest/library\"\n ===== Executing Task: \"foo\"\n Foo!\n pake[1]: Exiting Directory \"(REST OF PATH...)/paketest/library\"\n *** exit subpake[1]:\n\n\nRunning pake\n============\n\n.. code-block:: bash\n\n cd your_pakefile_directory\n\n # Run pake with up to 10 tasks running in parallel\n\n pake -j 10\n\npake will look for \"pakefile.py\" or \"pakefile\" in the current directory\nand run it.\n\nOr you can specify one or more files to run with **-f/--file**. The\nswitch does not have multiple arguments, but it can be used more than\nonce to specify multiple files.\n\nFor example:\n\n``pake -f pakefile.py foo``\n\n``pake -f your_pakefile_1.py -f your_pakefile_2.py foo``\n\nYou can also specify multiple tasks, but do not rely on unrelated tasks\nbeing executed in any specific order because they won't be. If there is\na specific order you need your tasks to execute in, the one that comes\nfirst should be declared a dependency of the one that comes second, then\nthe second task should be specified to run.\n\nWhen running parallel builds, leaf dependencies will start executing\npretty much simultaneously, and non related tasks that have a dependency\nchain may execute in parallel.\n\n``pake task unrelated_task order_independent_phony``\n\nCommand Line Options\n--------------------\n\n::\n\n usage: pake [-h] [-v] [-D DEFINE] [--stdin-defines] [-j JOBS] [-n]\n [-C DIRECTORY] [-t] [-ti] [--sync-output {True, False, 1, 0}]\n [-f FILE]\n [tasks [tasks ...]]\n\n positional arguments:\n tasks Build tasks.\n\n optional arguments:\n -h, --help show this help message and exit\n -v, --version show program's version number and exit\n -D DEFINE, --define DEFINE\n Add defined value.\n --stdin-defines Read defines from a Python Dictionary piped into\n stdin. Defines read with this option can be\n overwritten by defines specified on the command line\n with -D/--define.\n -j JOBS, --jobs JOBS Max number of parallel jobs. Using this option enables\n unrelated tasks to run in parallel with a max of N\n tasks running at a time.\n -n, --dry-run Use to preform a dry run, lists all tasks that will be\n executed in the next actual invocation.\n -C DIRECTORY, --directory DIRECTORY\n Change directory before executing.\n -t, --show-tasks List all task names.\n -ti, --show-task-info\n List all tasks along side their doc string. Only tasks\n with doc strings present will be shown.\n --sync-output {True, False, 1, 0}\n Tell pake whether it should synchronize task output\n when running with multiple jobs. Console output can\n get scrambled under the right circumstances with this\n turned off, but pake will run slightly faster. This\n option will override any value in the PAKE_SYNC_OUTPUT\n environmental variable, and is inherited by subpake\n invocations unless the argument is re-passed with a\n different value or overridden in pake.init.\n -f FILE, --file FILE Pakefile path(s). This switch can be used more than\n once, all specified pakefiles will be executed in\n order with the current directory as the working\n directory (unless -C is specified).\n\n\n.. |Master Documentation Status| image:: https://readthedocs.org/projects/pake/badge/?version=latest\n :target: http://pake.readthedocs.io/en/latest/?badge=latest\n.. |codecov| image:: https://codecov.io/gh/Teriks/pake/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/Teriks/pake", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Teriks/pake", "keywords": "", "license": "BSD 3-Clause", "maintainer": "", "maintainer_email": "", "name": "python-pake", "package_url": "https://pypi.org/project/python-pake/", "platform": "", "project_url": "https://pypi.org/project/python-pake/", "project_urls": { "Homepage": "https://github.com/Teriks/pake" }, "release_url": "https://pypi.org/project/python-pake/0.17.0.3a1/", "requires_dist": null, "requires_python": "", "summary": "A make-like build utility entirely in python.", "version": "0.17.0.3a1" }, "last_serial": 5719680, "releases": { "0.17.0.3a1": [ { "comment_text": "", "digests": { "md5": "8a2f77f8553c4faf406c7a2dc28c550d", "sha256": "37759e5ca5a55d5bc7a2edae842f9ff52b9aeb5653cf62234e0ccaa27fd9248a" }, "downloads": -1, "filename": "python-pake-0.17.0.3a1.tar.gz", "has_sig": false, "md5_digest": "8a2f77f8553c4faf406c7a2dc28c550d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 72449, "upload_time": "2019-08-23T09:07:07", "url": "https://files.pythonhosted.org/packages/e8/7b/b2102872ac02e154e719a39060abd2e23977390cbed59faaa65d81166eb9/python-pake-0.17.0.3a1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "8a2f77f8553c4faf406c7a2dc28c550d", "sha256": "37759e5ca5a55d5bc7a2edae842f9ff52b9aeb5653cf62234e0ccaa27fd9248a" }, "downloads": -1, "filename": "python-pake-0.17.0.3a1.tar.gz", "has_sig": false, "md5_digest": "8a2f77f8553c4faf406c7a2dc28c550d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 72449, "upload_time": "2019-08-23T09:07:07", "url": "https://files.pythonhosted.org/packages/e8/7b/b2102872ac02e154e719a39060abd2e23977390cbed59faaa65d81166eb9/python-pake-0.17.0.3a1.tar.gz" } ] }