77use WP_CLI \Path ;
88
99/**
10- * @phpstan-type ComposerConfig array{name: string, description: string, extra: array{readme: array{shields: array<string>}, commands: array<string>}, require: array<string, string>, 'require-dev': array<string, string>}
10+ * @phpstan-type ComposerConfig array{name: string, description: string, license?: string, extra: array{readme: array{shields: array<string>}, commands: array<string>}, require: array<string, string>, 'require-dev': array<string, string>}
1111 */
1212class ScaffoldPackageCommand {
1313
@@ -40,9 +40,31 @@ class ScaffoldPackageCommand {
4040 * : Specify a destination directory for the command. Defaults to WP-CLI's `packages/local/` directory.
4141 *
4242 * [--license=<license>]
43- * : License for the package.
43+ * : License for the package by SPDX code .
4444 * ---
4545 * default: MIT
46+ * options:
47+ * - MIT
48+ * - Apache-2.0
49+ * - BSD-3-Clause
50+ * - BSD-2-Clause
51+ * - GPL-2.0-only
52+ * - GPL-3.0-only
53+ * - ISC
54+ * - LGPL-3.0-only
55+ * - LGPL-2.1-only
56+ * - 0BSD
57+ * - AGPL-3.0-only
58+ * - MPL-2.0
59+ * - AFL-3.0
60+ * - MS-PL
61+ * - BSD-1-Clause
62+ * - MIT-0
63+ * - CPL-1.0
64+ * - BSL-1.0
65+ * - Unlicense
66+ * - CC0-1.0
67+ * - none
4668 * ---
4769 *
4870 * [--require_wp_cli=<version>]
@@ -84,6 +106,13 @@ public function package( $args, $assoc_args ) {
84106 $ assoc_args ['name ' ] = $ args [0 ];
85107 $ assoc_args ['year ' ] = gmdate ( 'Y ' );
86108
109+ $ license_input = Utils \get_flag_value ( $ assoc_args , 'license ' , 'MIT ' );
110+ if ( 'none ' === strtolower ( $ license_input ) ) {
111+ $ assoc_args ['license ' ] = 'proprietary ' ;
112+ } else {
113+ $ assoc_args ['license ' ] = $ license_input ;
114+ }
115+
87116 $ bits = explode ( '/ ' , $ assoc_args ['name ' ] );
88117 if ( 2 !== count ( $ bits ) || empty ( $ bits [0 ] ) || empty ( $ bits [1 ] ) ) {
89118 WP_CLI ::error ( "' {$ assoc_args ['name ' ]}' is an invalid package name. Package scaffold expects '<author>/<package>'. " );
@@ -134,7 +163,7 @@ public function package( $args, $assoc_args ) {
134163 "{$ package_dir }/.distignore " => file_get_contents ( "{$ package_root }/.distignore " ),
135164 "{$ package_dir }/phpcs.xml.dist " => Utils \mustache_render ( "{$ template_path }/phpcs.xml.dist.mustache " , $ assoc_args ),
136165 "{$ package_dir }/CONTRIBUTING.md " => file_get_contents ( "{$ package_root }/CONTRIBUTING.md " ),
137- "{ $ package_dir } /LICENSE " => Utils \mustache_render ( "{ $ template_path } /LICENSE.mustache " , $ assoc_args ),
166+
138167 "{$ package_dir }/wp-cli.yml " => $ wp_cli_yml ,
139168 "{$ package_dir }/hello-world-command.php " => Utils \mustache_render ( "{$ template_path }/hello-world-command.mustache " , $ assoc_args ),
140169 "{$ package_dir }/src/HelloWorldCommand.php " => Utils \mustache_render ( "{$ template_path }/HelloWorldCommand.mustache " , $ assoc_args ),
@@ -166,7 +195,15 @@ public function package( $args, $assoc_args ) {
166195 }
167196
168197 if ( ! Utils \get_flag_value ( $ assoc_args , 'skip-readme ' ) ) {
169- WP_CLI ::runcommand ( "scaffold package-readme {$ quoted_package_dir } {$ force_flag }" , array ( 'launch ' => false ) );
198+ WP_CLI ::runcommand ( "scaffold package-readme {$ quoted_package_dir } {$ force_flag } --license= {$ license_input }" , array ( 'launch ' => false ) );
199+ } elseif ( 'none ' !== strtolower ( $ license_input ) ) {
200+ $ license_file_path = $ this ->resolve_license_file_path ( $ license_input , $ template_path );
201+ if ( null !== $ license_file_path ) {
202+ $ this ->create_files (
203+ [ "{$ package_dir }/LICENSE " => Utils \mustache_render ( $ license_file_path , $ assoc_args ) ],
204+ $ force
205+ );
206+ }
170207 }
171208
172209 // Display next steps guidance for users.
@@ -263,9 +300,30 @@ public function package( $args, $assoc_args ) {
263300 * : Name of default branch of the underlying repository. Defaults to main.
264301 *
265302 * [--license=<license>]
266- * : License for the package.
303+ * : License for the package by SPDX code .
267304 * ---
268- * default: MIT
305+ * options:
306+ * - MIT
307+ * - Apache-2.0
308+ * - BSD-3-Clause
309+ * - BSD-2-Clause
310+ * - GPL-2.0-only
311+ * - GPL-3.0-only
312+ * - ISC
313+ * - LGPL-3.0-only
314+ * - LGPL-2.1-only
315+ * - 0BSD
316+ * - AGPL-3.0-only
317+ * - MPL-2.0
318+ * - AFL-3.0
319+ * - MS-PL
320+ * - BSD-1-Clause
321+ * - MIT-0
322+ * - CPL-1.0
323+ * - BSL-1.0
324+ * - Unlicense
325+ * - CC0-1.0
326+ * - none
269327 * ---
270328 *
271329 * @when before_wp_load
@@ -291,6 +349,12 @@ public function package_readme( $args, $assoc_args ) {
291349 $ package_root = dirname ( __DIR__ );
292350 $ template_path = $ package_root . '/templates/ ' ;
293351
352+ $ license_input = Utils \get_flag_value ( $ assoc_args , 'license ' );
353+ if ( null === $ license_input ) {
354+ $ license_input = isset ( $ composer_obj ['license ' ] ) ? $ composer_obj ['license ' ] : 'MIT ' ;
355+ }
356+ $ composer_license = 'none ' === strtolower ( $ license_input ) ? 'proprietary ' : $ license_input ;
357+
294358 $ bits = explode ( '/ ' , $ composer_obj ['name ' ] );
295359 $ readme_args = [
296360 'package_name ' => $ composer_obj ['name ' ],
@@ -303,7 +367,7 @@ public function package_readme( $args, $assoc_args ) {
303367 'has_commands ' => false ,
304368 'wp_cli_update_to_instructions ' => 'the latest stable release with `wp cli update` ' ,
305369 'show_powered_by ' => isset ( $ composer_obj ['extra ' ]['readme ' ]['show_powered_by ' ] ) ? (bool ) $ composer_obj ['extra ' ]['readme ' ]['show_powered_by ' ] : true ,
306- 'license ' => $ assoc_args [ ' license ' ] ,
370+ 'license ' => $ composer_license ,
307371 ];
308372
309373 if ( isset ( $ composer_obj ['extra ' ]['readme ' ]['shields ' ] ) ) {
@@ -538,6 +602,35 @@ public function package_readme( $args, $assoc_args ) {
538602 } else {
539603 WP_CLI ::success ( 'Created package readme. ' );
540604 }
605+
606+ // Only write to composer.json if the license has changed. This protects package_readme from
607+ // overwriting files changed by package. Only when --license changes do we need to write.
608+ $ existing_license = isset ( $ composer_obj ['license ' ] ) ? $ composer_obj ['license ' ] : '' ;
609+ $ composer_obj ['license ' ] = $ composer_license ;
610+ if ( $ composer_license !== $ existing_license ) {
611+ $ composer_json_content = json_encode ( $ composer_obj , JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "\n" ;
612+ if ( false === file_put_contents ( $ package_dir . '/composer.json ' , $ composer_json_content ) ) {
613+ WP_CLI ::error ( "Error creating file: {$ package_dir }/composer.json " );
614+ }
615+ }
616+
617+ if ( 'none ' === strtolower ( $ license_input ) ) {
618+ if ( is_file ( $ package_dir . '/LICENSE ' ) ) {
619+ unlink ( $ package_dir . '/LICENSE ' );
620+ }
621+ } else {
622+ $ license_file_path = $ this ->resolve_license_file_path ( $ license_input , $ template_path );
623+ if ( null !== $ license_file_path ) {
624+ $ license_data = [
625+ 'year ' => gmdate ( 'Y ' ),
626+ 'name ' => $ composer_obj ['name ' ],
627+ ];
628+ $ this ->create_files (
629+ [ "{$ package_dir }/LICENSE " => Utils \mustache_render ( $ license_file_path , $ license_data ) ],
630+ $ force
631+ );
632+ }
633+ }
541634 }
542635
543636 /**
@@ -835,6 +928,18 @@ public function package_tests( $args, $assoc_args ) {
835928 }
836929 }
837930
931+ private function resolve_license_file_path ( $ license , $ template_path ) {
932+ $ normalized = strtolower ( $ license );
933+ if ( basename ( $ normalized ) !== $ normalized ) {
934+ return null ;
935+ }
936+ $ license_path = $ template_path . 'licenses/ ' . $ normalized ;
937+ if ( is_file ( $ license_path ) ) {
938+ return $ license_path ;
939+ }
940+ return null ;
941+ }
942+
838943 private static function rewrap_param_desc ( $ matches ) {
839944 $ param = $ matches [1 ];
840945 $ desc = self ::indent ( "\t\t" , self ::normalize_desc_indentation ( rtrim ( $ matches [2 ] ) ) );
0 commit comments