-
-
Notifications
You must be signed in to change notification settings - Fork 878
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
Use composer for swagger ui #768
Conversation
soyuka
commented
Sep 27, 2016
Q | A |
---|---|
Bug fix? | no |
New feature? | no |
BC breaks? | no |
Deprecations? | no |
Tests pass? | yes |
Fixed tickets | |
License | MIT |
Doc PR |
Hmmm |
@@ -21,7 +21,8 @@ | |||
"symfony/http-kernel": "^2.7 || ^3.0", | |||
"symfony/property-info": "^3.1", | |||
"symfony/serializer": "^3.1", | |||
"willdurand/negotiation": "^2.0.3" | |||
"willdurand/negotiation": "^2.0.3", | |||
"swagger-api/swagger-ui": "^2.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notice that our dependencies are sorted... 😄
@@ -67,5 +68,10 @@ | |||
"branch-alias": { | |||
"dev-master": "2.0.x-dev" | |||
} | |||
}, | |||
"scripts": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scripts
is root-only: https://getcomposer.org/doc/04-schema.md#scripts
So this needs to be in the Standard Edition.
Also, not everyone can make use of symlinks, so we should probably do it in a similar fashion to https://github.com/sensiolabs/SensioDistributionBundle/blob/master/Composer/ScriptHandler.php + https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems a bit overkill but yeah might be better, we need to find and validate a neat solution before I can implement it. ping @api-platform/core-team
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw this works on both my osx and my debian without being root.
Oh ok root-only where the root is the first composer.json
. Still, I'm using directly api-platform/core
, so it is my root :p.
I'd add that copying isn't the best solution in term of space needed as vendor files are then useless and take 5.4M for nothing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless we want to use git submodules, I don't think there's any more elegant solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@soyuka It will not work for my Docker Compose set-up. I need to use copy, not symlink because of all the volumes... And then of course there's Windows. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still, I'm using directly api-platform/core, so it is my root :p
And of course it's not going to work for any actual projects using API Platform.
I'd add that copying isn't the best solution in term of space needed as vendor files are then useless and take 5.4M for nothing.
That's already the case for bundle resources. I don't think it's a concern since the user is doing it for good reasons. The default should be relative symlink, just like in Symfony.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So basically we need a Composer Script which does a cp -r vendor/swagger-api/swagger-ui/dist
in src/Bridge/Symfony/Bundle/Resources/public/swagger-ui
.
I'm not sure to understand how this script runs (is it magically hooked to composer?).
May I skip the Command
part and directly put this in the Composer
script?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No magic involved. Take a look at https://github.com/symfony/symfony-standard/blob/6832c7baae2d757b12bbd5342aea2993c21ee9eb/composer.json#L30-L45
Yes, we probably do not need a Command
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh there it is :), thanks!
@@ -5,3 +5,4 @@ phpunit.xml | |||
/vendor/ | |||
/tests/Fixtures/app/cache/* | |||
/tests/Fixtures/app/logs/* | |||
/src/Bridge/Symfony/Bundle/Resources/public |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should use the public
directory itself directly, but rather a subdirectory public/swagger-ui
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
woops my bad was in a hurry 😋
4277a42
to
0185c36
Compare
edcc5c9
to
e64bb6e
Compare
}, | ||
"scripts": { | ||
"post-autoload-dump": [ | ||
"php -r \"symlink('../../../../../../vendor/swagger-api/swagger-ui', './src/Bridge/Symfony/Bundle/Resources/public/swagger-ui');\"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you meant to symlink the dist
directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do they publish everything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do they publish everything?
Composer does not have a way to specify otherwise. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You know, when you think about it, it's perfectly understandable because Composer simply clones the repository or download the archive from GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, like bower (they still have an ignore
option in the bower.json
)... I think what npm achieves is better in term of deployments but it's another debate. For example, I never received a correct answer on this part of a recent bash deployment code of mine:
is having a tag that refers to an overridden commit a good idea?
3c934c5
to
6185867
Compare
ping @teohhanhui The composer.json update should be in the |
|
||
class ScriptHandler | ||
{ | ||
protected static $destination = '/src/Bridge/Symfony/Bundle/Resources/public/swagger-ui/dist'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not a using a const for those parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic looks bad here. Swagger UI must be installed:
- when downloading the standard edition
- when installing the bundle in an existing Symfony project
Currently, it doesn't address these use cases. IMO we should take inspiration from https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php and copy directly files in the web directory (not in the bundle).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure to follow here. It was in public
so I put it back in public
so that it works seamlessly.
From what I understand the assets
command copies content from public
to web
. So, you want files to be copied to web/
?
What are you calling standard edition? The api-platform/api-platform
package? composer create-package
will run composer install
and will run this if we have the same scripts
lines in it's composer.json
.
when installing the bundle in an existing Symfony project
How should this work? A composer event? Related to an existing symfony command?
Please give me more informations about your needs:
- Where should the
dist
directory content be copied to? - How is it supposed to be triggered (Symfony Command, Composer Event etc.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dunglas Waiting on an answer to this one, I'm not sure what should be done. Please give me strict instructions and it'll be done by the end of the week ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way I see it, we should not run the composer script in api-platform/core
. It should only be run in api-platform/api-platform
(and any Symfony project that uses API Platform).
The files should be copied to the web
directory of the Symfony project, i.e. web/swagger-ui
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, that means all asset('bundles/apiplatform/swagger-ui/
calls in the template would be changed to asset('swagger-ui/
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about people using directly api-platform/core
who would like to benefit from swagger-ui then?
I would left the script in api-platform/core
, and then I'd set the composer post-install-cmd
inside api-platform/api-platform
. This is how it's done with symfony I think. For example in my project's composer.json
I have:
"scripts": {
"post-install-cmd": [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
...
],
"post-update-cmd": [
...
]
},
Then ofc, +1 about the web
directory.
Ok, I read again what you wrote and I think we said the same thing. I'm doing just that asap.
public static function installSwaggerUi(Event $event) | ||
{ | ||
$fs = new Filesystem(); | ||
$finder = new Finder(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable is used only one time, it can be inlined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inline a constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
foreach ((new Finder())->in(...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh didn't knew about this, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we can remove update-js.sh
@@ -21,6 +21,7 @@ | |||
"symfony/http-kernel": "^2.7 || ^3.0", | |||
"symfony/property-info": "^3.1", | |||
"symfony/serializer": "^3.1", | |||
"swagger-api/swagger-ui": "^2.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sw
goes before sy
😝
class ScriptHandler | ||
{ | ||
protected static $destination = '/src/Bridge/Symfony/Bundle/Resources/public/swagger-ui/dist'; | ||
protected static $source = '/vendor/swagger-api/swagger-ui/dist'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$swaggerUiSource
?
|
||
class ScriptHandler | ||
{ | ||
protected static $destination = '/src/Bridge/Symfony/Bundle/Resources/public/swagger-ui/dist'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$swaggerUiDestination
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we do not want the extraneous dist
here.
4b462e4
to
28f68e2
Compare
|
||
class ScriptHandler | ||
{ | ||
const DESTINATION = '/src/Bridge/Symfony/Bundle/Resources/public/swagger-ui'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this ends up as ScriptHandler::DESTINATION
... The const
name is not descriptive enough.
28f68e2
to
477a98f
Compare
What is the status of this PR? |
f182602
to
6765dd1
Compare
This needs a rebase. |
6eec2fc
to
578133a
Compare
rebase broke everything \o/ (because of Fosuserbundle update?). |
@@ -17,6 +17,7 @@ | |||
|
|||
"doctrine/inflector": "^1.0", | |||
"psr/cache": "^1.0", | |||
"swagger-api/swagger-ui": "^2.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still a dependency? I think not. Can it go under suggest
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a dependency of api-platform/api-platform
then?
@@ -81,7 +84,7 @@ | |||
<body class="swagger-section"> | |||
<div id="header" style="background-color: #253032; height: 35px"> | |||
<div class="swagger-ui-wrap"> | |||
<a id="logo" href="https://api-platform.com"><img height="48" src="{{ asset('bundles/apiplatform/logo-header.svg') }}" alt="API Platform" style="position: relative; right: 10px"></a> | |||
<a id="logo" href="https://api-platform.com"><img height="48" src="{{ asset('logo-header.svg') }}" alt="API Platform" style="position: relative; right: 10px"></a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accidentally changed...
|
||
class ScriptHandler | ||
{ | ||
const SWAGGER_UI_DESTINATION = '/web/swagger-ui'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The path separator (leading slash) should not be in these constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, to me it's cleaner then adding DIRECTORY_SEPARATOR
below:
$cwd.DIRECTORY_SEPARATOR.self::SWAGGER_UI_SOURCE
$fs = new Filesystem(); | ||
$cwd = getcwd(); | ||
|
||
foreach ((new Finder())->in(implode('/', [$cwd, self::SWAGGER_UI_SOURCE])) as $file) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about something like that?
class ScriptHandler
{
protected static $symfonyWebDir = 'web';
public static function installSwaggerUi(Event $event)
{
$vendorDir = $event->getComposer()->getConfig()->get('vendor-dir');
$webDir = $event->getComposer()->getPackage()->getExtra()['symfony-web-dir'] ?? static::$symfonyWebDir;
$event->getIO()->write('Trying to install assets for Swagger-UI...');
(new Filesystem())->mirror(
$webDir.'/swagger-api/swagger-ui/dist',
$vendorDir.'/swagger-ui',
null,
['override' => true, 'delete' => true]
);
}
}
It should work, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should pass 'copyonwindows' => true
to the options.
85df583
to
5b5b3f9
Compare
Made a new commit for the throw thing, the diff is a mess otherwise. |
@@ -52,9 +54,6 @@ public function testInvoke(Request $request, ProphecyInterface $twigProphecy) | |||
|
|||
public function getInvokeParameters() | |||
{ | |||
$postRequest = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'post']); | |||
$postRequest->setMethod('POST'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was not used
@@ -50,6 +51,10 @@ public function __invoke(Request $request) | |||
{ | |||
$documentation = new Documentation($this->resourceNameCollectionFactory->create(), $this->title, $this->description, $this->version, $this->formats); | |||
|
|||
if (!file_exists($request->server->get('DOCUMENT_ROOT').'/swagger-ui')) { | |||
throw new RuntimeException('Swagger-ui was not found, either you forgot to require swagger-ui or you might be missing the composer scripts. Please refer to https://api-platform.com/docs/core/swagger-ui for instructions.'); | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think DOCUMENT_ROOT
is the safest way to get the web
path, or we might add a configuration for the swagger-ui path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be in the config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, so same goes for the Composer\ScriptHandler where we use $event->getComposer()->getPackage()->getExtra()['symfony-web-dir']
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Composer script using Symfony project config seems wrong to me... I think we should stick to the "extra" in the ScriptHandler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay that's what I've done so far.
8402c6e
to
490f84a
Compare
Okay, so I did a cleaner commit with the modifications, the other one is just deleting stuff. |
Waiting for insights on #841 (comment) and I'm adding it here. I think that this is close to be good to go (ie: we will finally be able to |
What is the problem with the current implementation?
|
I tend to agree with @GuilhemN. The only problem I see with the current implementation is that we need to upgrade the bundle when a the Swagger team releases a new version of Swagger UI. It's not a big deal IMO. |
I see several problems:
If it were only up to me I would completely move Swagger to another bundle, I personally don't use it and it bother's me when doing
Why? We can add the routes even if the ui isn't available. |
It can be automated if it's too painful.
Imo this matters less than an easy installation as it is the first thing that the user sees of the library. If we can have both it would be better but it looks like it will be hardly possible without loosing on one side.
It would be fine for me.
The point is only that there are 3 steps, the worse being adding the |
Symfony does add its own hooks to composer when using the bundle. Couldn't we do the same with |
Indeed, I forgot Api-Platform had its own edition. Then the only problem is when installing |
It needs to be properly documented. The good thing with the actual solution is that it just works, in all cases. |
@soyuka We can close this, right? And api-platform/api-platform#150. |
Sure, even though I still think swaggerui should not be in |