1- import { BuildOptions } from '../models/webpack-config' ;
1+ import * as denodeify from 'denodeify' ;
2+ import { BuildOptions } from '../models/build-options' ;
23import { BaseBuildCommandOptions } from './build' ;
34import { CliConfig } from '../models/config' ;
5+ import { Version } from '../upgrade/version' ;
6+ import { ServeTaskOptions } from './serve' ;
7+
8+ const SilentError = require ( 'silent-error' ) ;
49const PortFinder = require ( 'portfinder' ) ;
510const Command = require ( '../ember-cli/lib/models/command' ) ;
6- const config = CliConfig . fromProject ( ) || CliConfig . fromGlobal ( ) ;
11+ const getPort = < any > denodeify ( PortFinder . getPort ) ;
712
813PortFinder . basePort = 49152 ;
914
15+ const config = CliConfig . fromProject ( ) || CliConfig . fromGlobal ( ) ;
1016const defaultPort = process . env . PORT || config . get ( 'defaults.serve.port' ) ;
1117const defaultHost = config . get ( 'defaults.serve.host' ) ;
1218
@@ -32,16 +38,16 @@ const ServeCommand = Command.extend({
3238 aliases : [ 'server' , 's' ] ,
3339
3440 availableOptions : BaseBuildCommandOptions . concat ( [
35- { name : 'port' , type : Number , default : defaultPort , aliases : [ 'p' ] } ,
41+ { name : 'port' , type : Number , default : defaultPort , aliases : [ 'p' ] } ,
3642 {
3743 name : 'host' ,
3844 type : String ,
3945 default : defaultHost ,
4046 aliases : [ 'H' ] ,
4147 description : `Listens only on ${ defaultHost } by default`
4248 } ,
43- { name : 'proxy-config' , type : 'Path' , aliases : [ 'pc' ] } ,
44- { name : 'live-reload' , type : Boolean , default : true , aliases : [ 'lr' ] } ,
49+ { name : 'proxy-config' , type : 'Path' , aliases : [ 'pc' ] } ,
50+ { name : 'live-reload' , type : Boolean , default : true , aliases : [ 'lr' ] } ,
4551 {
4652 name : 'live-reload-host' ,
4753 type : String ,
@@ -66,9 +72,9 @@ const ServeCommand = Command.extend({
6672 default : true ,
6773 description : 'Whether to live reload CSS (default true)'
6874 } ,
69- { name : 'ssl' , type : Boolean , default : false } ,
70- { name : 'ssl-key' , type : String , default : 'ssl/server.key' } ,
71- { name : 'ssl-cert' , type : String , default : 'ssl/server.crt' } ,
75+ { name : 'ssl' , type : Boolean , default : false } ,
76+ { name : 'ssl-key' , type : String , default : 'ssl/server.key' } ,
77+ { name : 'ssl-cert' , type : String , default : 'ssl/server.crt' } ,
7278 {
7379 name : 'open' ,
7480 type : Boolean ,
@@ -84,9 +90,62 @@ const ServeCommand = Command.extend({
8490 }
8591 ] ) ,
8692
87- run : function ( commandOptions : ServeTaskOptions ) {
88- return require ( './serve.run' ) . default . call ( this , commandOptions ) ;
93+ run : function ( commandOptions : ServeTaskOptions ) {
94+ const ServeTask = require ( '../tasks/serve' ) . default ;
95+
96+ Version . assertAngularVersionIs2_3_1OrHigher ( this . project . root ) ;
97+ commandOptions . liveReloadHost = commandOptions . liveReloadHost || commandOptions . host ;
98+
99+ return checkExpressPort ( commandOptions )
100+ . then ( ( ) => autoFindLiveReloadPort ( commandOptions ) )
101+ . then ( ( opts : ServeTaskOptions ) => {
102+ const serve = new ServeTask ( {
103+ ui : this . ui ,
104+ project : this . project ,
105+ } ) ;
106+
107+ return serve . run ( opts ) ;
108+ } ) ;
89109 }
90110} ) ;
91111
112+ function checkExpressPort ( commandOptions : ServeTaskOptions ) {
113+ return getPort ( { port : commandOptions . port , host : commandOptions . host } )
114+ . then ( ( foundPort : number ) => {
115+
116+ if ( commandOptions . port !== foundPort && commandOptions . port !== 0 ) {
117+ throw new SilentError (
118+ `Port ${ commandOptions . port } is already in use. Use '--port' to specify a different port.`
119+ ) ;
120+ }
121+
122+ // otherwise, our found port is good
123+ commandOptions . port = foundPort ;
124+ return commandOptions ;
125+
126+ } ) ;
127+ }
128+
129+ function autoFindLiveReloadPort ( commandOptions : ServeTaskOptions ) {
130+ return getPort ( { port : commandOptions . liveReloadPort , host : commandOptions . liveReloadHost } )
131+ . then ( ( foundPort : number ) => {
132+
133+ // if live reload port matches express port, try one higher
134+ if ( foundPort === commandOptions . port ) {
135+ commandOptions . liveReloadPort = foundPort + 1 ;
136+ return autoFindLiveReloadPort ( commandOptions ) ;
137+ }
138+
139+ // port was already open
140+ if ( foundPort === commandOptions . liveReloadPort ) {
141+ return commandOptions ;
142+ }
143+
144+ // use found port as live reload port
145+ commandOptions . liveReloadPort = foundPort ;
146+ return commandOptions ;
147+
148+ } ) ;
149+ }
150+
92151export default ServeCommand ;
0 commit comments