Git Product home page Git Product logo

py-make's Introduction

py-make

PyPI-Status PyPI-Versions

Build-Status Coverage-Status Branch-Coverage-Status Codacy-Grade Libraries-Rank

DOI-URI LICENCE OpenHub-Status

Bring basic Makefile support to any system with Python.

Inspired by work in tqdm.

Simply install then execute pymake in a directory containing a Makefile.

pymake works on any platform (Linux, Windows, Mac, FreeBSD, Solaris/SunOS).

pymake does not require any library to run, just a vanilla Python interpreter will do.


PyPI-Status PyPI-Downloads Libraries-Dependents

pip install py-make

GitHub-Status GitHub-Stars GitHub-Commits GitHub-Forks GitHub-Updated

Pull and install in the current directory:

pip install -e git+https://github.com/tqdm/py-make.git@master#egg=py-make

The list of all changes is available either on GitHub's Releases: GitHub-Status or on crawlers such as allmychanges.com.

Simply install then execute pymake -p to list commands and pymake <command> to use a command, in a directory containing a Makefile.

For compatibility, ensure:

  1. Every alias is preceded by @[+]make (eg: @make alias)
  2. A maximum of one @make alias or command per line

A full list of what is and is not supported is on the issue tracker.

Sample makefile compatible with pymake:

PY=python -m py_compile
.PHONY:
    all
    test
    install
    compile
all:
    @+make test
    @make install
test:
    pytest
install:
    python -m pip install
compile:
    $(PY) test.py
circle:
    # of life
    circle
empty:
    # this is a comment

If you get a "Permission Denied" error, please check if maybe your antivirus may be preventing the launch of compiled python scripts, if the Scripts subdirectory is in the PATH, or other issues with the Python install.

PyPI-Versions README-Hits (Since 28 Oct 2016)

pymake --help

GitHub-Commits GitHub-Issues GitHub-PRs OpenHub-Status

All source code is hosted on GitHub. Contributions are welcome.

See the CONTRIBUTING.md file for more information.

Open Source (OSI approved): LICENCE

Citation information: DOI-URI

The main developers, ranked by surviving lines of code (git fame -wMC), are:

  • Stephen Larroque (lrq3000, core logic)
  • Casper da Costa-Luis (casperdcl, modularization & maintenance)

We are grateful for all GitHub-Contributions.

README-Hits (Since 28 Oct 2016)

py-make's People

Contributors

casperdcl avatar lrq3000 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

py-make's Issues

pip install issue

I'm trying to get this package installed with pip install py-make.
But it errors out with:

Collecting py-make
  Downloading py_make-0.1.1-py2.py3-none-any.whl (9.4 kB)
Collecting docopt>=0.6.0
  Downloading docopt-0.6.2.tar.gz (25 kB)
  Preparing metadata (setup.py) ... done
Using legacy 'setup.py install' for docopt, since package 'wheel' is not installed.
Installing collected packages: docopt, py-make
  Running setup.py install for docopt ... done
ERROR: Exception:
Traceback (most recent call last):
  File "F:\gv\Python310\lib\site-packages\pip\_internal\cli\base_command.py", line 167, in exc_logging_wrapper
    status = run_func(*args)
  File "F:\gv\Python310\lib\site-packages\pip\_internal\cli\req_command.py", line 247, in wrapper
    return func(self, options, args)
  File "F:\gv\Python310\lib\site-packages\pip\_internal\commands\install.py", line 461, in run
    installed = install_given_reqs(
  File "F:\gv\Python310\lib\site-packages\pip\_internal\req\__init__.py", line 73, in install_given_reqs
    requirement.install(
  File "F:\gv\Python310\lib\site-packages\pip\_internal\req\req_install.py", line 814, in install
    success = install_legacy(
  File "F:\gv\Python310\lib\site-packages\pip\_internal\operations\install\legacy.py", line 119, in install
    write_installed_files_from_setuptools_record(record_lines, root, req_description)
  File "F:\gv\Python310\lib\site-packages\pip\_internal\operations\install\legacy.py", line 49, in write_installed_files_from_setuptools_record
    new_lines.append(os.path.relpath(prepend_root(filename), egg_info_dir))
  File "F:\gv\Python310\lib\ntpath.py", line 718, in relpath
    raise ValueError("path is on mount %r, start on mount %r" % (
ValueError: path is on mount 'c:', start on mount 'F:'

Not sure if it's a issue with my Python/pip or the setup.py script of this package.

But, if I do pip3 install --user py-make, it works fine. Producing a %APPDATA%\Python\Python310\Scripts\pymake.exe .
So what's this all about?

I'm on Win-10 with Python 3.10 (x64).

Support basic Makefile syntax

  • fix py26 unit test
  • Monkey-patch setuptools or distutils to support python setup.py make
  • add basic support for substitution macros $(...)
  • add basic support for complex commands echo hello | world.exe
  • add basic support for inline dependencies target.o: source.cpp
  • add basic support for checking timestamps of targets against dependencies
  • add basic support for wildcards %.o: %.cpp, $^, $<

More readable errors

I tried a simple makefile with an echo command on windows

.PHONY: say_hello
.DEFAULT_GOAL := say_hello

say_hello:
	@echo "hello"

And got this error:

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.3\helpers\pydev\pydevd.py", line 1758, in <module>
    main()
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.3\helpers\pydev\pydevd.py", line 1752, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.3\helpers\pydev\pydevd.py", line 1147, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.3\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/_dev/python_ws/_Libs_OpenSource/py-make/examples/simple_examples.py", line 21, in <module>
    main()
  File "C:/_dev/python_ws/_Libs_OpenSource/py-make/examples/simple_examples.py", line 17, in main
    pymake.main()
  File "C:\_dev\python_ws\_Libs_OpenSource\py-make\pymake\_main.py", line 63, in main
    ignore_errors=opts['--ignore-errors'])
  File "C:\_dev\python_ws\_Libs_OpenSource\py-make\pymake\_pymake.py", line 143, in execute_makefile_commands
    check_call(parsed_cmd)
  File "C:\Miniconda3\envs\tools_py37\lib\subprocess.py", line 342, in check_call
    retcode = call(*popenargs, **kwargs)
  File "C:\Miniconda3\envs\tools_py37\lib\subprocess.py", line 323, in call
    with Popen(*popenargs, **kwargs) as p:
  File "C:\Miniconda3\envs\tools_py37\lib\subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "C:\Miniconda3\envs\tools_py37\lib\subprocess.py", line 1178, in _execute_child
    startupinfo)
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.3\helpers\pydev\_pydev_bundle\pydev_monkey.py", line 513, in new_CreateProcess
    return getattr(_subprocess, original_name)(app_name, patch_arg_str_win(cmd_line), *args)
FileNotFoundError: [WinError 2] Le fichier spécifié est introuvable

It seems that the stacktrace could definitely be improved. I'll propose a PR for this.

Support all of Make CLI arguments

  • -b, -m Ignored for compatibility.
  • -B, --always-make Unconditionally make all targets.
  • -C DIRECTORY, --directory=DIRECTORY
    Change to DIRECTORY before doing anything.
  • -d Print lots of debugging information.
  • --debug[=FLAGS] Print various types of debugging information.
  • -e, --environment-overrides
    Environment variables override makefiles.
  • -f FILE, --file=FILE, --makefile=FILE
    Read FILE as a makefile.
  • -h, --help Print this message and exit.
  • -i, --ignore-errors Ignore errors from commands.
  • -I DIRECTORY, --include-dir=DIRECTORY
    Search DIRECTORY for included makefiles.
  • -j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg.
  • -k, --keep-going Keep going when some targets can't be made.
  • -l [N], --load-average[=N], --max-load[=N]
    Don't start multiple jobs unless load is below N.
  • -L, --check-symlink-times Use the latest mtime between symlinks and target.
  • -n, --just-print, --dry-run, --recon
    Don't actually run any commands; just print them.
  • -o FILE, --old-file=FILE, --assume-old=FILE
    Consider FILE to be very old and don't remake it.
  • -p, --print-data-base Print make's internal database.
  • -q, --question Run no commands; exit status says if up to date.
  • -r, --no-builtin-rules Disable the built-in implicit rules.
  • -R, --no-builtin-variables Disable the built-in variable settings.
  • -s, --silent, --quiet Don't echo commands.
  • -S, --no-keep-going, --stop
    Turns off -k.
  • -t, --touch Touch targets instead of remaking them.
  • -v, --version Print the version number of make and exit.
  • -w, --print-directory Print the current directory.
  • --no-print-directory Turn off -w, even if it was turned on implicitly.
  • -W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE
    Consider FILE to be infinitely new.
  • --warn-undefined-variables Warn when an undefined variable is referenced.

Dependent rules issues

I have encountered two issues with rule dependencies

The first is with comment after a dependency

depa:
	@python -c "print('A')"

all: depa # comment after dependency
	@python -c "print('TEST-PASS')"

The above will fail when running pymake all with

(venv) C:\Dev\idmtools\test_makefile>pymake all
depa # comment after dependency
Traceback (most recent call last):
  File "C:\Python\Python38\lib\runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Python\Python38\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Dev\idmtools\venv\Scripts\pymake.exe\__main__.py", line 7, in <module>
  File "c:\dev\idmtools\venv\lib\site-packages\pymake\_main.py", line 60, in main
    execute_makefile_commands(commands, target,
  File "c:\dev\idmtools\venv\lib\site-packages\pymake\_pymake.py", line 143, in execute_makefile_commands
    check_call(parsed_cmd)
  File "C:\Python\Python38\lib\subprocess.py", line 359, in check_call
    retcode = call(*popenargs, **kwargs)
  File "C:\Python\Python38\lib\subprocess.py", line 340, in call
    with Popen(*popenargs, **kwargs) as p:
  File "C:\Python\Python38\lib\subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Python\Python38\lib\subprocess.py", line 1307, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified

You can observe it is attempting to run the command depa # comment after dependency

The other related issue(I think) it multiple dependencies

depb:
	@python -c "print('A')"

depa:
	@python -c "print('A')"

all: depa depb
	@python -c "print('TEST-PASS')"

which fails with

(venv) C:\Dev\idmtools\test_makefile>pymake all
depa depb
Traceback (most recent call last):
  File "C:\Python\Python38\lib\runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Python\Python38\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Dev\idmtools\venv\Scripts\pymake.exe\__main__.py", line 7, in <module>
  File "c:\dev\idmtools\venv\lib\site-packages\pymake\_main.py", line 60, in main
    execute_makefile_commands(commands, target,
  File "c:\dev\idmtools\venv\lib\site-packages\pymake\_pymake.py", line 143, in execute_makefile_commands
    check_call(parsed_cmd)
  File "C:\Python\Python38\lib\subprocess.py", line 359, in check_call
    retcode = call(*popenargs, **kwargs)
  File "C:\Python\Python38\lib\subprocess.py", line 340, in call
    with Popen(*popenargs, **kwargs) as p:
  File "C:\Python\Python38\lib\subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Python\Python38\lib\subprocess.py", line 1307, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified

I suspect there needs to be some parsing happening on the dependencies portion of rules before execution

Project status and activity / PR review policy

I was glad to find this project :) as we encountered an issue with the make available in conda on windows, where debugging and contributing would be far more complicated (cygwin).

Is it actively maintained ? If so, at which pace would PRs be reviewed and released into PyPi ? (some rough estimation is enough: yearly, monthly, weekly, daily... or never ;) ).

Sorry for asking this in such a straightforward way, but this is just in case we eventually decide to use it in our projects, to decide if I should rather fork it into an independent package, or contribute to it.

Thanks !

Makefiles with source files in different directories

I have Makefiles in several subdirectories but I would like to create a Makefile in the root directory of the project which builds all the Makefiles in my subdirectories. Is this possible and if it is, how so? Thanks !

Command runner, not a build system

Hey, I just stumbled upon this project today. It might be worth mentioning that unlike make this is a command runner using the Makefile syntax. Make's primary purpose is/was to build files from other files, e.g. myprog.o from myprog.c or foo.class from foo.java. The dependencies can be other targets by coincidence, but their primary purpose is looking for files that need rebuilding. This project seems to assume users want to use the PHONY mode for all targets. The README doesn't seem to mention this.

Cheers and keep up the interesting work

Examples of acceptable commands

Hello,
could you share some examples how should I write commands like deleting pycache folder in Makefile that are recognizable by pymake?
I tried with :
rmdir -r __pycache__
and a lot of different variations but it failed.

I am using Window 10, py3.8, pymake v0.1.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.