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

Feature Request: TNS plugin create <xyz> [--template <plugin template name] #1945

Closed
NathanaelA opened this issue Jul 23, 2016 · 21 comments
Closed
Assignees
Milestone

Comments

@NathanaelA
Copy link
Contributor

I worked on a plugin template that would make making plugins a whole lot easier. Basically it would generate everything you needed for a JS or TS plugin ; including creating the package.json, .gitignore, .npmignore and basically have a plugin fully ready for publishing after it was done. (It uses a post-install script to ask questions about the type of plugin, repo, name, etc).

However, do to the issue with the #1932, we cannot use the normal tns create MY-PLUGIN-NAME --template plugin to use the template.

This is a feature request either to allow the package.json change like suggested in #1932 (i.e. something like an additional key {"cleanTemplate": "true"}
Another idea Nathan Walker suggested; was a new tns plugin create [--template ]

@tjvantoll
Copy link
Contributor

I personally sort of like the idea of tns plugin create [--template], just because I personally would expect the existing tns create to only build new projects, not plugins. Regardless of implementation details, I think this would be a hugely valuable feature to have baked into the {N} CLI, as it could help establish an “official” structure for our plugins, as well as lower the barrier to entry for new plugin authors.

@radeva
Copy link

radeva commented May 9, 2017

Hi @NathanaelA @tjvantoll

We are now working on a plugin seed repo which users will be able to clone and use as a starting point for their plugins. We plan to make it public soon. I hope this approach will also be beneficial for the plugin authors.

@dtopuzov
Copy link
Contributor

dtopuzov commented May 9, 2017

I don't think we should add extra code in CLI just to solve something that can be done with
git clone <official-plugin-seed>.

@dtopuzov dtopuzov closed this as completed May 9, 2017
@NathanaelA

This comment was marked as abuse.

@tjvantoll
Copy link
Contributor

tjvantoll commented May 10, 2017

I also disagree. Although simple, I think a tns plugin create command will really help plugin authors. Sure the command will just git clone the seed, but from a plugin author’s perspective you’re saving me from needing to find the appropriate repo (which the average user probably doesn’t even know exists), running git clone, and also dealing with folder names. (The folder name will be nativescript-plugin-seed by default, and that’ll be a hassle to change.)

I believe tns plugin create MyPluginName will make plugin developer’s lives a lot easier, and I believe we should add it.

@jlooper
Copy link

jlooper commented May 10, 2017

I am posting my vote in favor of the CLI modification in support of TJ and Nathanael. Look at it this way - we want to make it easy for people (like me) to make plugins. Right now, this job is really daunting because there's no clear path to create a plugin. We're going to fix that by creating an official seed. Great, then let's onboard people super easily to our seed repo by integrating it into the CLI. Seeing as how you really can't ship an app without at least one plugin, let's make it as easy as possible to allow people to create them to make our plugin marketplace that much stronger. More and more plugins will be created using our seed, so upgrading them will be less and less problematic. This is a long-term maintenance win for the community.

@rosen-vladimirov
Copy link
Contributor

Hey all,

Thanks for sharing your feedback. The issue will remain open and we'll try to prioritize it for a future release. There are other tasks on the board, so I cannot give an estimate when this one could do it. Of course, we'll be glad to help and review a PR that adds this functionality. It should be pretty straightforward to add the new command, so anyone can give it a try.

Thanks again and please accept our apology for the whole disruption. Your opinion is important for us!

@PeterStaev
Copy link
Contributor

I personally tend to agree with @dtopuzov comments. I do not see much benefit from a special CLI command compared to just cloning a plugin seed repo (like this one)

@NathanaelA

This comment was marked as abuse.

@PeterStaev
Copy link
Contributor

@NathanaelA , I have neither used the plugin seed nor your command, as I have my own seed 😄

Now all those steps you listed are basically down to:

  1. Clone the seed repo
  2. delete the .git folder
  3. rename the ts/js files
  4. Change package.json with names, license, TNS version, owner.

And those steps are like <1% of the dev time you spend on a plugin 😄 If needed those steps can be automated via a npm script inside the plugin seed repo. If you are concerned about visibility of the seed repo, this can simply be added as links in the plugin docs, which authors will need to read either way if they want to start a plugin.

The question here is whether or not this whole thing should be part of the CLI, and IMO it should not be. Let's take a look at the competitors (Cordova/Ionic/ReactNative) - from what I see none of them have a command to create a plugin.
And you can't really compare creating an app to creating a plugin, because creating an app is done by thousands of different users, where the creation of plugins is done by handful of people. And in most cases normal users that create apps will not need to create a new plugin as there are already quite a lot available.

@NathanaelA

This comment was marked as abuse.

@PeterStaev
Copy link
Contributor

@NathanaelA , read my previous comment very carefully. I did not say that I'm against having a seed template. I said that IMO its place is not in the CLI. So I'm all for @radeva's idea to create a unified template which others can use to create plugins. But IMO its place is not in the CLI.

As for plugin errors - your whole comment is irrelevant as adding the CLI option will neither magically sanitize existing plugins from their problems, nor will force the creation of future plugins using this option/template. This can easily be handled by adding some plugin developer portion to the plugins site where authors can check if there are any problems with any of their plugins (if it is really that important and could cause problems with usage).

@NathanaelA

This comment was marked as abuse.

@jlooper
Copy link

jlooper commented May 11, 2017

I don't think this is the place to hash over who is making money or who spends more time doing what. Let's decide, rather whether the CLI is going to have this functionality: tns create plugin my-awesome-plugin which would pick up an official seed and send the developer off to the races.

@dtopuzov you added the 'up-for-grabs' label. Does that mean you will review a PR to add this functionality?

@dtopuzov
Copy link
Contributor

dtopuzov commented May 12, 2017

Removing the label, since there are different votes, for or against this feature.

@NathanaelA

This comment was marked as abuse.

@PeterStaev
Copy link
Contributor

@NathanaelA , I think you are overreacting on this one. First of all I meant the OFFICIAL plugins site not the .rocks one.
But whatever, now back on topic: Can you explain what will be the benefit of writing:

tns plugin create nativescript-myplugin --template tsc

Instead of:

git clone https://github.com/NativeScript/tsc-plugin-seed nativescript-myplugin
cd nativescript-myplugin
npm run setup

Because I really do not see any valid argument mentioned thus-far, except the visibility one, which can easily be solved if this is written in the official docs, rocks sites, your blog, etc.

@atanasovg
Copy link
Contributor

Thanks all for your valuable input. I really appreciate the passion and obsession to make {N} a better technology in both the team and the community. In this comment I will try to explain the philosophy and understanding that the team have about the CLI and how we should further develop it. Missing publicly visible documentation that describes this philosophy is something that we need to improve and we are after it as of now.

Basically we are fans of the "Keep the core minimalistic and expose flexible extension points" approach. By "minimalistic" we understand only the set of commands that are applicable to the majority (95%+) of our users. Following this approach allows us to be more focused and to do fewer things but with great quality.

If I make an analogy - that would be the core modules and all the 400+ community plugins that extend the core in some way by adding new functionality.

The team also hear community hands-on problems/issues and really understand them. So far the CLI didn't have some flexible way, except the hooks, to do some real extension in terms of new commands and/or modifying default commands' behavior. Because of this we needed to balance between our principles and solving community feature requests. Good news is that this is no longer true. We have recently introduced a new extensibility model in the CLI that allows for really great level of flexibility, including custom commands and consuming CLI internal APIs/data/variables. @rosen-vladimirov can share more details as he is the engineer that put most thought behind this implementation.

That said, having this new model will allow us to keep the CLI core minimal and in the same time will give means to the community to extend it the way they need. Plus, any other user that needs some custom functionality will be able to simply install the NPM package containing the command(s) and to take advantage of them directly within the CLI.

@NathanaelA Considering the new model (we are still to document it), do you think that creating a new command by yourself, without the need to make a PR to the core, will suffice your needs? You will be able to promote such custom commands much like plugins.

@NathanaelA

This comment was marked as abuse.

@rosen-vladimirov
Copy link
Contributor

Hey @NathanaelA ,
I'm glad to share some more details for the new Extensibility model in CLI. It's still in a very early stage, but we'll be really happy in case you give it a try and share your opinion. The main concept is described in this PR. You can create a real npm package and use NativeScript CLI to install it as extension. Whenever CLI is loaded, it automatically loads all extensions, so they can be used when resolving commands, services, etc. I'll try to give an example - you want to add tns plugin create <name> command. Create a new package (in fact there's no need to publish it in npm, you can install it from .tgz, directory, github repo, etc. In the package, you'll have to use the CLI syntax for registering command - create a new class that has:

  • canExecute method - the definition of the method is: canExecute?(args: string[]): Promise<boolean> - it is called before the real execution of command and the idea is to validate the arguments passed by user. The command will be executed only in case this method returns a Promise that's resolved with a true value.
  • execute method - execute(args: string[]): Promise<void> - it's the heart of the command - the real code execution is here. The method receives the arguments passed by user, so the code can use them.

As NativeScript CLI uses Dependency Injection in order to resolve commands and services, you have to register your class in the global $injector that CLI creates:

$injector.registerCommand("plugin|create", PluginCreateCommand);

NOTE: The pipe ('|') is required when you want command name to have spaces, so when the user writes tns plugin create myAwesomePlugin, and you have registered the command as plugin|create, the args that will be passed to canExecute and execute methods will be [ "myAwesomePlugin" ] only. In case you register your command with $injector.registerCommand("plugin", PluginCreateCommand);, and user writes the same command, you'll receive [ "create", "myAwesomePlugin" ] as args.

Now the only remaining thing is to create an entry point for your plugin. Our idea is the entry point to be just the bootstrap - the place where you tell the $injector in which file it will find the registered modules. So create a bootstrap.js file and add the following line to it:

$injector.requireCommand("plugin|create", <full path to file where the command is located>);

Here is a very simple example, that allows you to execute tns hello-world <name> command.
https://github.com/rosen-vladimirov/ns-extension-hello-world

As per the other question - you are able to access everything that is registered in CLI's bootstrap here and here (CLI uses a submodule, so some of the code is in a separate repository) and call its methods. For example in case you want to execute some http request, you can use the httpClient module registered in CLI:

  1. In your constructor you should add the $httpClient module:
class PluginCreateCommand {
    constructor($httpClient) { this.$httpClient= $httpClient; }

This way, when CLI creates an instance of your class, it will inject the $httpClient module and methods of your class will be able to call methods of the $httpClient module registered in CLI.
2. After that you are able to call the method httpRequest of the $httpClient:

this.$httpClient.httpRequest("https://nativescript.or")
				.then(response => {
					console.log("Body of response is: ", response.body);
				})
				.catch(err => {
					console.error("Err: ", err);
				});

For extraction you can use the unzip method of CLI's $fs module.

Hope this will give you basic idea how you can create an extension. We are still working on some issues (for example how to allow extensions to add help for the newly added commands, how to add new -- options via extension, etc.) and we are trying to document everything. The commands for managing extensions are already documented, you can try tns help extension in order to get some more information. Also you can find information about CLI's dependency injection mechanism here.

@rosen-vladimirov
Copy link
Contributor

Related PRs: #3800
#3836

This feature is available in CLI's next version. You can give it a try and send your feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests