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

Composer project importer #2785

Closed
wants to merge 17 commits into from
Closed

Conversation

kaloyan-raev
Copy link
Contributor

@kaloyan-raev kaloyan-raev commented Oct 14, 2016

What does this PR do?

Composer is a popular PHP dependency manager (similar to Bower for
Javascript). A natural way to create a new project in PHP is by materializing it from a Composer package like this:

composer create-project laravel/laravel /projects/laravel

The above command fetches the laravel/laravel Composer package from a central repository (https://packagist.org/) and installs it at the /project/laravel folder on the local file system. The advantage against cloning a git repository is that composer create-project will install all required
dependencies.

This PR contributes a new Composer plugin that:

  • Defines a Composer project importer that can import the project source from a Composer package.
  • Defines an Import Project Registrar that registers the Composer importer into the import project wizard.

composer-importer

The Composer project importer uses the 'location' property of the
SourceStorage model for the package name. As result the "source" of
project templates can be defined like this:

"source": {
  "type": "composer",
  "location": "zendframework/zend-expressive-skeleton",
  "parameters": {}
}

The new project importer requires the composer executable to be installed in the stack and available in the PATH. This is the usual case for all PHP stacks.

Additional changes:

  • The 'Archive' importer category is renamed to 'Package'. See this comment.
  • New project samples using the 'composer' source type:
    • Zend Framework Skeleton Application
    • Zend Expressive Skeleton Application

What issues does this PR fix or reference?

New behavior

(Explain the PR as it should appear in the release notes)

  • New "composer" source type is available for Project Templates. The "location" property provides the package name of the composer package. The Templates must be updated
  • New "composer" project importer is available for the Import Project wizard. It allows users to create new PHP projects from the specified Composer package.
  • The existing "astro-splash" project sample is updated to use the new "composer" source type.
  • New project samples:
    • Zend Framework Skeleton Application
    • Zend Expressive Skeleton Application

Signed-off-by: Kaloyan Raev kaloyan.r@zend.com

Composer is a popular PHP dependency manager (similar to Bower for
Javascript). A natural way to create a new project in PHP is by
materializing it from a Composer package like this:

  composer create-project laravel/laravel /projects/laravel

The above command fetches the 'laravel/laravel' Composer package from a
central repository (https://packagist.org/) and installs it at the
/project/laravel folder. The advantage against cloning a git repository
is that `composer create-project` will install all required
dependencies.

This patch contributes a new Composer plugin that:
- Defines a Composer project importer that can import the project source
from a Composer package.
- Defines an Import Project Registrar that registers the Composer
importer into the import project wizard.

The Composer project importer uses the 'location' property of the
SourceStorage model for the package name. As result the "source" of
project templates can be defined like this:

  "source": {
    "type": "composer",
    "location": "zendframework/zend-expressive-skeleton",
    "parameters": {}
  }

Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>
@codenvy-ci
Copy link

Can one of the admins verify this patch?

@TylerJewell TylerJewell added kind/enhancement A feature request - must adhere to the feature request template. status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. labels Oct 14, 2016
@TylerJewell
Copy link

At this rate of improements, Kaloyan is going to be a Che committer before CheConf. @bmicklea @vparfonov - please schedule code review / QA into the current sprint.

Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>
@kaloyan-raev
Copy link
Contributor Author

The second commit renames the 'Archive' importer category to 'Package'. We used to have only the Zip importer in the Archive category, but this PR also adds the Composer one. Renaming the category to 'Package' fits both Zip and Composer importers, whereas 'Archive' is not good for the Composer importer.

I kept the ARCHIVE enum class as deprecated for backward compatibility.

This commit can be easily reverted if this change is not accepted.

@kaloyan-raev kaloyan-raev mentioned this pull request Oct 14, 2016
34 tasks
@bmicklea
Copy link

Very cool @kaloyan-raev!

- Zend Framework Skeleton Application
- Zend Expressive Skeleton Application

Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>
@bmicklea bmicklea assigned vparfonov and unassigned gazarenkov Oct 18, 2016
@bmicklea
Copy link

@kaloyan-raev - is this PR ready for review? Or are you still working on this?

@kaloyan-raev
Copy link
Contributor Author

@bmicklea The PR is ready for review.

@bmicklea
Copy link

@vparfonov - please review for M7

@gazarenkov
Copy link
Contributor

gazarenkov commented Oct 19, 2016

Hi @kaloyan-raev

Good things and good case, congrats
But it seems importer is not really an abstraction to use for this purpose since Composer bound to PHP (unlike neutral source code storages) and it seems it has more explicit behavioural nature than just source import.

It seems PHP - Composer relationship looks exactly like Java - Maven one.
The way I propose will also allow you to use all the other functionality offered by Composer, not only project bootstrapping with "create_project" option.
So, I propose to organize it this way:

  • Make Composer PT which extends PHP PT,
    see Maven PT .
    Include it into "PHP" group so in the Project Wizard it will be listed along with "bare PHP" PT see Maven wizard.
  • To make it possible to bootstrap project make default Composer generator use your code with "create_project" option. Or you can make it even more advanced (maybe later) making 2 different generators (from scratch and bootstrapping, see how it is done on Maven PT for Simple/Archetype generators, see Maven generator ).

@kaloyan-raev
Copy link
Contributor Author

@gazarenkov Thanks for the review and the advice.

Indeed, the PHP - Composer relationship is similar to the Java - Maven. I will look at the Maven plugin as you have suggested and try to rework this PR.

@gazarenkov
Copy link
Contributor

Cool, feel free to ask me or @vparfonov if you need some help with that, good luck.

@kaloyan-raev
Copy link
Contributor Author

@gazarenkov I looked at the Maven plugin. I agree that from a design point of view it would be better to move the creation of a Composer project from the Import Project wizard to the Create Project wizard.

However, the main motivation for this PR was to make it possible to have project templates that are created directly from a composer package. I would still need the project importer to achieve this, right?

@kaloyan-raev
Copy link
Contributor Author

@gazarenkov @vparfonov Could you look at my last question?

@vparfonov
Copy link
Contributor

@kaloyan-raev Hi, I don't know how composer work but look like we don't need it as importer. Importer means that you have some remote, for example VCS. If composer just generate some files like maven archetype plugin it's org.eclipse.che.api.project.server.handlers.CreateProjectHandler in our Project API.

@kaloyan-raev
Copy link
Contributor Author

@vparfonov Quote from the composer create-project command documentation:

You can use Composer to create new projects from an existing package. This is the equivalent of doing a git clone/svn checkout followed by a "composer install" of the vendors.

So it does fetch source code. And it also installs the required dependencies. It is the preferred way in the PHP world to start coding on a project template.

My main goal is to have Che project templates created from Composer packages. I still need the project importer to achieve this, don't I? Let me know if I can achieve it in another way.

I can still refactor the GUI part and plug into the Create Project wizard, instead of to the Import Project wizard.

@kaloyan-raev
Copy link
Contributor Author

I removed the IDE plugin that extends the Import Project wizard from this PR, so we can focus entirely on the ability to create project templates from a Composer package, i.e. with source.type = composer.

I will prepare a new PR with IDE plugin extending that Create Project wizard after we merge this PR.

@vparfonov
Copy link
Contributor

@kaloyan-raev we have fixed Maven Archetype Project generator here 9951639

i think you can do the same with composer

@kaloyan-raev
Copy link
Contributor Author

@vparfonov Can you give me an example how I can use the Maven Archetype Project generator in a project template?

@kaloyan-raev
Copy link
Contributor Author

Conflicts resolved.

@vparfonov
Copy link
Contributor

Hi @kaloyan-raev. We added new method in Project API ProjectService.java#L211 it accepts NewProjectConfigDto.java, so you can set in Map<String, String> options all parameters that you need for project generation. Also you need to register
CreateProjectHandler for your project type and move logic from your ComposerProjectImporter.java to it.

@kaloyan-raev
Copy link
Contributor Author

@vparfonov I am trying to rework the PR as you suggest. Now I have a Composer project type extending the PHP project type. I also have a CreateProjectHandler.

But I am failing to pass any options or attributes from the project template definition in the samples.json to the CreateProjectHandler. The onCreateProject() method is called, but both attributes and options are empty.

Here is my definition in sampled.json:

{
    "name": "zend-expressive",
    "displayName": "zend-expressive",
    "path": "/zend-expressive",
    "description": "A skeleton application using the Zend Exressive framework. Expressive is a minimalist PSR-7 middleware framework for PHP with routing, DI container, optional templating, and optional error handling capabilities.",
    "projectType": "composer",
    "mixins": [],
    "attributes": {
      "language": [
        "php"
      ],
      "package": [
        "zendframework/zend-expressive-skeleton"
      ]
    },
    "options": {
      "package": "zendframework/zend-expressive-skeleton"
    },
    "modules": [],
    "problems": [],
    "source": {},
    "commands": [
      {
        "name": "configure",
        "type": "custom",
        "commandLine": "chmod 777 ${current.project.path}/data/cache; echo \"<VirtualHost *:80>\n    DocumentRoot ${current.project.path}/public\n    SetEnv APPLICATION_ENV 'development'\n    <Directory ${current.project.path}/public>\n        DirectoryIndex index.php\n        AllowOverride All\n        Require all granted\n    </Directory>\n</VirtualHost>\" | sudo tee /etc/apache2/sites-available/000-default.conf",
        "attributes": {
          "previewUrl": ""
        }
      }
    ],
    "links": [],
    "category": "Samples",
    "tags": [
      "Zend"
    ]
  }

Note that I am specifying the "package" value in both options and attributes just for the tests. I am fine using any of them. And I am not really sure what is the difference between them.

@vparfonov
Copy link
Contributor

@kaloyan-raev Can you push your changes to your branch i will check it, thx?

Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>
@kaloyan-raev
Copy link
Contributor Author

@vparfonov Meanwhile I was able to debug the problem. I created PR #3375 with a potential fix.

Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>
Conflicts:
	dashboard/src/components/typings/che.d.ts
	plugins/pom.xml
Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>
Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>
@kaloyan-raev
Copy link
Contributor Author

@vparfonov I reworked the PR. I take advantage of both the CreateProjectHandler and ProjectInitHandler. In the CreateProjectHandler.onCreateProject() method I create the project from the Composer package, but without installing the dependencies. The dependencies are installed in the ProjectInitHandler.onProjectInitialized(). This way I also cover the use case where the project is imported from a source location (Git, SVN, ZIP) and then configured as a Composer project.

The output of the executed Composer commands are displayed in a Composer console output in the IDE.

The plugin also contributes a page to the Create Project wizard where the user can specify a Composer package, which the create the project from.

All of the above works pretty nice, but I face some issues that should be addressed separately:

  1. The dashboard does not report any progress as console output during the "Creating project" phase. This is due to a limitation of the API. The ProjectImporter.importSources() has a LineConsumerFactory parameter, which is not available in the CreateProjectHandler.onCreateProject() and ProjectInitHandler.onProjectInitialized() methods.
  2. The dashboard waits for both onCreateProject() and onProjectInitialized() to finish before showing the Web IDE. Installing the Composer dependencies may take long minutes as they are downloaded from the Internet. It's not a nice user experience to just sit and wait in the "Creating project" status of the dashboard. It would be much better if the dashboard switches to the Web IDE after onCreateProject() finishes and executes onProjectInitialized() in the background. The user will see the progress of installing the dependencies in the console and can do other tasks in the mean time.
  3. Same for the Web IDE's Create Project wizard. The wizard stays modal until both onCreateProject() and onProjectInitialized() finish. It would be better if the wizard executes onProjectInitialized() in the background.
  4. The onProjectInitialized() is executed twice when a new project is created from a built-in sample with the Web IDE's Create Project wizard. The second call comes from updating the project after it is created. I am not sure if this update call is really necessary. This double call to onProjectInitialized() causes issues to some Composer projects and returns with error.
  5. There is some strange flickering of the Composer console output. When a new line is added the view is scrolled to the top and then back to the bottom. It's very annoying.

@bmicklea
Copy link

@kaloyan-raev I am going to move this to 5.1 - we are trying to finalize M9 which will be the 5.0 GA release and it seems there are more changes needed before this is ready to merge.

@bmicklea bmicklea modified the milestones: 5.1.0, 5.0.0-M9 Dec 20, 2016
@bmicklea bmicklea removed this from the 5.1.0 milestone Jan 10, 2017
@bmicklea bmicklea added the severity/P1 Has a major impact to usage or development of the system. label Jan 10, 2017
@vparfonov
Copy link
Contributor

will be merged in #3726

@vparfonov vparfonov closed this Jan 13, 2017
@vparfonov vparfonov added this to the 5.1.0 milestone Jan 13, 2017
@benoitf benoitf removed the status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. label Nov 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement A feature request - must adhere to the feature request template. severity/P1 Has a major impact to usage or development of the system. sprint/current
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants