Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove dependency on make #1

Closed
casey opened this issue Sep 29, 2016 · 5 comments
Closed

Remove dependency on make #1

casey opened this issue Sep 29, 2016 · 5 comments

Comments

@casey
Copy link
Owner

casey commented Sep 29, 2016

Currently, j relies on a make or gmake command being available. This causes some problems:

  • Only trivial justfiles are likely to be portable across flavors of make
  • Running j on windows is difficult
  • Since it is a j "feature" that flags are passed to make, it can't have flags of its own
  • Makefile syntax only allows leading tabs
  • Make won't run a recipe if there is a file with same name as the recipe. The current workaround is to add a .PHONY directive to the justfile
  • Exported variables on one line of a make recipe are not available on subsequent lines

It may be desirable to stop depending on make and move to a j-specific custom file format. This would mean that make's features would no longer be available, but a workaround to this would be to write a Makefile and call make from j.

Possible improvements this would allow:

  • Add a --list flag that lists the available recipes
  • Work on windows
  • Relax the rule on tabs vs spaces, and just enforce that the same number of tabs and spaces precede each line of recipe
  • Figure out a sane way of allowing justfiles in subdirectories

The exact syntax is up in the air, but I personally very much like the current syntax, and would like to do something similar.

@casey
Copy link
Owner Author

casey commented Sep 29, 2016

I was thinking about just starting with something like:

# single line comments are allowed
# for now, the '#' must be the first non-whitespace character on a line

# simple recipes work as before:
foo:
  cd baz
  touch bar
  echo galf

# tabs and spaces can be mixed, but there must be an equal
# number of tabs and spaces (in whatever order) before
# every line in a recipe, so that a user's tab-width setting
# doesn't matter
#
# using . for space and - for tab:

# this is okay, every line starts with one space:
a:
.echo hello
.echo hello

# this is okay, every line starts with the same whitespace:
b:
.-echo hello
.-echo hello

# this is not okay, inconsistent whitespace:
c:
.-echo hello
--echo hello

# this is okay, because it is still unambiguous:
d:
.-echo hello
-.echo hello
# (we could disallow this)

# recipes may call other recipes
bar: foo a b
  echo "I'm bar!"

# as in make, a leading @ suppresses printing the command
qux:
  @echo "Pinging the server..."
  @ping 237.1.4.5

Constructing a DAG of recipes and detecting loops doesn't seem that hard.

@aoeu, thoughts?

@casey
Copy link
Owner Author

casey commented Sep 29, 2016

Also, some kind of variable assignment is likely to be necessary. Makefiles allow setting the shell using SHELL := bash and it would be nice if justfiles still supported this.

@casey
Copy link
Owner Author

casey commented Sep 29, 2016

Would it be too crazy to use a full scripting language outside of the recipes? Imagine if everything that wasn't a recipe was parsed and run as python, with a special syntax for exporting variables as environment variables to recipes?

If there were a good python implementation in rust, I think I would seriously consider it.

@casey
Copy link
Owner Author

casey commented Sep 29, 2016

Okay, I just thought of a killer feature that we can provide if we move away from makefiles... If you add a shebang as the first line of a recipe, we run that recipe as a script instead:

stuff:
  #!/usr/bin/env python3
  def foo(a, b):
    print(a + b):
  for i in range(100):
    foo(i + i * i)

j will then extract the contents of the recipe, less the leading whitespace, and execute it as a script.

You could also use a shell shebang, if you use a lot of variables or want to continue in the case of command failure:

stuff:
  #!/bin/sh
  # variables will work as expected:
  A=hello
  echo getting $A...
  # the next line can fail and we'll still continue:
  curl http://example.com/$A > hello.html
  echo "We tried!"

@casey
Copy link
Owner Author

casey commented Oct 9, 2016

Make is gone! Support for #! recipes is also in

@casey casey closed this as completed Oct 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant