-
Notifications
You must be signed in to change notification settings - Fork 510
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
Major Providers Refactoring #69
Comments
This sounds like a good evolution of providers to me; my gut says that this work belongs with the providers. |
Cool. So init could be cut down to: init() ->
[{name, ?PROVIDER},
{module, ?MODULE},
{bare, false},
{deps, ?DEPS},
{example, "rebar erlydtl <subtask>"},
{short_desc, ""},
{desc, ""},
{subproviders, [rebar_prv_erlydtl_compiler]},
{opts, []}]. or we could move the definition of the provider record to |
And could get rid of the need for modifying State in the |
Here's an alternative approach. Providers can define an optional namespace they operate in. You have a single provider that behaves like Default rebar stuff would put in nothing (and would be wrapped by So when I call This requires little to no change in provider support (just new options), and allows a nearly unlimited amount of namespaces for custom projects and languages without requiring central coordination from us. What do you think? |
Oh and a sweet thing this could enable is a python-like 'future' namespace. Want to try a new compile option for default rebar3 in Erlang? |
That could work. Will need a way of defining namespaces such that someone can include the plugin |
To be more precise, (and I'll try to build a demo test thing ASAP):
https://github.com/tsloughter/providers/blob/master/src/providers.erl#L29 would probably need a namespace option there With this stuff in place, we could probably extend the current If I have time tomorrow, I'll try to get a proof of concept going. |
Oh, wow. This is the most idiomatic Erlang suggestion I've heard so far. Questions:
Also: bonus points for minimizing the changes :-) |
In my own view, a provider is registered to a single namespace, but namespace creation is dynamic. As soon as a provider declares it belongs to a given namespace, that namespace is created. I think trying to reuse the same provider for multiple namespaces makes madness lie this way because dependency chains and sequences of calls will not be the same, and debugging it will probably be a nightmare. I don't think this is flexibility that is needed nearly as much as initial laziness (I'll just reuse this pile of code blindly). If code needs to be shared, extract it to a third-party library and then declare independent providers that depend on it. Again, this is my view so far. With that simple mapping, your second, third, and fourth questions are now a non-issue. If you don't want a provider, don't install it as a plugin. Problem solved. |
There's also gonna be the tricky way of how to declare dependencies on steps that ran in a different or local namespace. Currently we use |
Actually, we can get rid of |
So it would be just |
Cool, that's even nicer then. |
Definitely agree with the therein-lies-madness. I started having flashbacks On Sat, Dec 20, 2014 at 9:44 PM, Fred Hebert notifications@github.com
|
what about the currently valid also what does just |
I think by default a command with subcommands should register the default command to run when none given, just like make does. one question, how to specify commands with subcommands inside "meta commands" something like
or
|
@talentdeficit this is currently supported by do and would remain so. @marianoguerra my proposal would make |
It is The commas are necessary because each task has its own arguments. Which does need a fix because right now it simply uses |
Demo ready in #70 |
what about a mix like syntax for subproviders? then the following would all be valid: $ rebar clean compile eunit
$ rebar compile ct --suite rebar_state_SUITE, rebar_core_SUITE, rebar_prv_common_test_SUITE clean
$ rebar lfe.compile lfe.test
$ rebar lfe
$ rebar ex.compile --jobs 10 ex.test --seed "entropy" hex.publish |
why do you want to compile before running eunit? You don't and shouldn't need to anymore, ever. This was always a terribly shitty experience of rebar IMO. Commands know their dependencies. Not sure what the current format for the second command is, but this should be supported with 'do'. For the fourth one, this would be 'rebar3 lfe compile test' under my proposal. The fifth form (mixing namespaces in a single run) wouldn't be supported under my proposal, but would be |
@talentdeficit the issue is it doesn't make clear what args go with what command if you don't use commas between the commands. You could say that any args for As for use of |
i'm ok with either syntax, i was just offering an alternate that would not be a breaking change |
@ferd it would be |
i did a github search and there's way less instances of |
@tsloughter right. @talentdeficit thanks for the search, that's good to know. |
Namespaces have been merged in and updated the erlydtl provider for it https://github.com/rebar/rebar3/blob/master/src/rebar_prv_erlydtl_compiler.erl I think now we need a good way to include a multiple providers via a plugin. Right now it is 1:1 for plugins and providers. We'll want the user to be able to specify the |
Ah yeah. I'm guessing that's different from a multi-provider like having them submit their own |
Yea, it may just be a function each plugin has to export so rebar3 can saying |
I'm saying the problem would be on the plugin download itself, not the rebar3 download. I added a config file by hand before applying the template and used the https:// version of the plugin URL and it worked first try for me. |
Weird, changing the config does not work for me with the downloaded rebar3. Only works with my local rebar3 built from master. |
yes, I'm downloading rebar3 with: wget https://s3.amazonaws.com/rebar3/rebar3 should I try building it from source? |
yep, building from sources work. maybe the nightly's job isn't running or something like that? |
hi, now I'm at it again trying to make a efene ct plugin whose only task is to compile efene code on test/ and then delegate to rebar3's own ct task. is there a way to call another task explicitly from a plugin at a point that is not before? (that would be solved by putting the other task in the dependencies of this task). |
We'll need tests to make sure this is still working and doesn't break, but there is an element of |
should I namespace it with default in my case that I'm using another namespace? |
Yea |
I think you should "resolve" tuples to provider records in this line for it to work? https://github.com/tsloughter/providers/blob/master/src/providers.erl#L86 given how it's called here: https://github.com/tsloughter/providers/blob/master/src/providers.erl#L93 |
yep, getting the provider like this on my plugin and adding DefaultCTProvider to the post hooks works
but I think that should be done on the link provided above (or on rebar3 since providers are in state and afaik providers module doesn't know about rebar_state) |
Ah yup, I'll patch that soon. |
@marianoguerra I've also got a patch I'll get out today that replaces |
Can see the profiles change #96 |
@tsloughter you mean I shoud do
instead of
on my code or that should be done on rebar's side? |
Oh, it isn't resolving them but instead expects the hook list to be of the actual Provider record? That should change if that is the case. I look at that. |
@tsloughter yes, I think that's happening, see the links here #69 (comment) |
So... this turned out to be a pain. To get a So neither Not sure how to handle this yet... |
Couldn't rebar_hooks take care of expanding that stuff? I'm guessing ideally you wanted to resolve them whenever the provider is loaded in memory or something? The best option would be to internally expand them when calling This is not particularly different from being able to define deps of a provider by its (edited to change the reference for a function) |
rebar_hooks doesn't use providers. We can only use |
I thought Say after process_deps is being called. get_target_providers(Target, Providers, Namespace) ->
TargetProviders = lists:filter(fun(#provider{name=T, namespace=NS})
when T =:= Target, NS =:= Namespace ->
true;
(_) ->
false
end, Providers),
expand_hooks(process_deps(TargetProviders, Providers), Providers). I'm not exactly sure what can't work there? |
Oh, that will work. It does mean that a provider that has only been |
Ok, mostly got this working. But a new question. Resolving the deps of the hook provider? Example: We have provider Thoughts? |
I'd probably go for |
I find that weird because it is basically saying that using a provider as a hook is only supported if the provider doesn't rely on any deps. |
Yes. I'm assuming the provider in the hook would have similar requirements to the currently running one, otherwise why call for the hook? Do we expect some kind of I'm thinking that if you're writing a pre-processor of some kind, you may depend on I'm just trying hard to think of a good use case where someone goes "I have this here plugin that does something and then calls |
Does this issue need to stay open? |
I need to update my plugin to the latest version and check if everything works ok, you can close it and I can reopen it or open a new one if you want. |
I want to get all the current stakeholders involved in this discussion. @ferd @omarkj @talentdeficit @oubiwann @marianoguerra
In working on supporting subcommands for
lfe
and usingerlydtl
as my basis for it I'm thinking it is best supported by pushing more of the command and task handling into the providers app.This would basically gut
rebar_core
, movingprocess_command
anddo
to the providers module. It'll also require making aproviders_state
behaviour forrebar_state
because functions to set state likecommand_args
,command_parsed_args
andapply_profiles
are needed inprocess_command
.The main change to providers themselves would be
init
no longer returning{ok, State}
but instead either{ok, providers:t() | list(), State}
or{ok, providers:t() | list()}
. Depending on ifinit
should be able to update the state and if it should return a created provider or just the proplist that is used to create the provider.The text was updated successfully, but these errors were encountered: