Skip to content

Commit 307431c

Browse files
Merge pull request #19 from wp-cli/abstract-dedicated-class
Abstract `dist-archive` to `Dist_Archive_Command`
2 parents bf561e5 + 04d9401 commit 307431c

File tree

3 files changed

+154
-139
lines changed

3 files changed

+154
-139
lines changed

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
],
1414
"minimum-stability": "dev",
1515
"autoload": {
16+
"psr-4": {
17+
"": "src/"
18+
},
1619
"files": [ "dist-archive-command.php" ]
1720
},
1821
"require": {},

dist-archive-command.php

Lines changed: 5 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -4,143 +4,9 @@
44
return;
55
}
66

7-
/**
8-
* Create a distribution archive based on a project's .distignore file.
9-
*
10-
* For a plugin in a directory 'wp-content/plugins/hello-world', this command
11-
* creates a distribution archive 'wp-content/plugins/hello-world.zip'.
12-
*
13-
* You can specify files or directories you'd like to exclude from the archive
14-
* with a .distignore file in your project repository:
15-
*
16-
* ```
17-
* .distignore
18-
* .editorconfig
19-
* .git
20-
* .gitignore
21-
* .travis.yml
22-
* circle.yml
23-
* ```
24-
*
25-
* Use one distibution archive command for many projects, instead of a bash
26-
* script in each project.
27-
*
28-
* ## OPTIONS
29-
*
30-
* <path>
31-
* : Path to the project that includes a .distignore file.
32-
*
33-
* [<target>]
34-
* : Path and file name for the distribution archive. Defaults to project directory name plus version, if discoverable.
35-
*
36-
* [--format=<format>]
37-
* : Choose the format for the archive.
38-
* ---
39-
* default: zip
40-
* options:
41-
* - zip
42-
* - targz
43-
* ---
44-
*
45-
* @when before_wp_load
46-
*/
47-
$dist_archive_command = function( $args, $assoc_args ) {
48-
49-
list( $path ) = $args;
50-
if ( isset( $args[1] ) ) {
51-
$archive_file = $args[1];
52-
$info = pathinfo( $archive_file );
53-
if ( '.' === $info['dirname'] ) {
54-
$archive_file = getcwd() . '/' . $info['basename'];
55-
}
56-
} else {
57-
$archive_file = null;
58-
}
59-
$path = rtrim( realpath( $path ), '/' );
60-
if ( ! is_dir( $path ) ) {
61-
WP_CLI::error( 'Provided path is not a directory.' );
62-
}
63-
64-
$dist_ignore_path = $path . '/.distignore';
65-
if ( ! file_exists( $dist_ignore_path ) ) {
66-
WP_CLI::error( 'No .distignore file found.' );
67-
}
68-
69-
$maybe_ignored_files = explode( PHP_EOL, file_get_contents( $dist_ignore_path ) );
70-
$ignored_files = array();
71-
$archive_base = basename( $path );
72-
foreach( $maybe_ignored_files as $file ) {
73-
$file = trim( $file );
74-
if ( 0 === strpos( $file, '#' ) || empty( $file ) ) {
75-
continue;
76-
}
77-
if ( is_dir( $path . '/' . $file ) ) {
78-
$file = rtrim( $file, '/' ) . '/*';
79-
}
80-
$ignored_files[] = $archive_base . '/' . $file;
81-
}
82-
83-
$version = '';
84-
foreach( glob( $path . '/*.php' ) as $php_file ) {
85-
$contents = file_get_contents( $php_file, false, null, 0, 5000 );
86-
if ( preg_match( '#\* Version:(.+)#', $contents, $matches ) ) {
87-
$version = '.' . trim( $matches[1] );
88-
break;
89-
}
90-
}
91-
92-
if ( empty( $version ) && file_exists( $path . '/composer.json' ) ) {
93-
$composer_obj = json_decode( file_get_contents( $path . '/composer.json' ) );
94-
if ( ! empty( $composer_obj->version ) ) {
95-
$version = '.' . trim( $composer_obj->version );
96-
}
97-
}
98-
99-
if ( false !== stripos( $version, '-alpha' ) && is_dir( $path . '/.git' ) ) {
100-
$response = WP_CLI::launch( "cd {$path}; git log --pretty=format:'%h' -n 1", false, true );
101-
$maybe_hash = trim( $response->stdout );
102-
if ( $maybe_hash && 7 === strlen( $maybe_hash ) ) {
103-
$version .= '-' . $maybe_hash;
104-
}
105-
}
106-
107-
if ( is_null( $archive_file ) ) {
108-
$archive_file = dirname( $path ) . '/' . $archive_base . $version;
109-
if ( 'zip' === $assoc_args['format'] ) {
110-
$archive_file .= '.zip';
111-
} else if ( 'targz' === $assoc_args['format'] ) {
112-
$archive_file .= '.tar.gz';
113-
}
114-
}
115-
116-
chdir( dirname( $path ) );
117-
118-
if ( 'zip' === $assoc_args['format'] ) {
119-
$excludes = implode( ' --exclude ', $ignored_files );
120-
if ( ! empty( $excludes ) ) {
121-
$excludes = ' --exclude ' . $excludes;
122-
}
123-
$cmd = "zip -r {$archive_file} {$archive_base} {$excludes}";
124-
} else if ( 'targz' === $assoc_args['format'] ) {
125-
$excludes = array_map( function( $ignored_file ){
126-
if ( '/*' === substr( $ignored_file, -2 ) ) {
127-
$ignored_file = substr( $ignored_file, 0, ( strlen( $ignored_file ) - 2 ) );
128-
}
129-
return "--exclude='{$ignored_file}'";
130-
}, $ignored_files );
131-
$excludes = implode( ' ', $excludes );
132-
$cmd = "tar {$excludes} -zcvf {$archive_file} {$archive_base}";
133-
}
134-
135-
WP_CLI::debug( "Running: {$cmd}", 'dist-archive' );
136-
$ret = WP_CLI::launch( escapeshellcmd( $cmd ), false, true );
137-
if ( 0 === $ret->return_code ) {
138-
$filename = pathinfo( $archive_file, PATHINFO_BASENAME );
139-
WP_CLI::success( "Created {$filename}" );
140-
} else {
141-
$error = $ret->stderr ? $ret->stderr : $ret->stdout;
142-
WP_CLI::error( $error );
143-
}
7+
$autoload = dirname( __FILE__ ) . '/vendor/autoload.php';
8+
if ( file_exists( $autoload ) ) {
9+
require_once $autoload;
10+
}
14411

145-
};
146-
WP_CLI::add_command( 'dist-archive', $dist_archive_command );
12+
WP_CLI::add_command( 'dist-archive', 'Dist_Archive_Command' );

src/Dist_Archive_Command.php

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
/**
4+
* Create a distribution archive based on a project's .distignore file.
5+
*/
6+
class Dist_Archive_Command {
7+
8+
/**
9+
* Create a distribution archive based on a project's .distignore file.
10+
*
11+
* For a plugin in a directory 'wp-content/plugins/hello-world', this command
12+
* creates a distribution archive 'wp-content/plugins/hello-world.zip'.
13+
*
14+
* You can specify files or directories you'd like to exclude from the archive
15+
* with a .distignore file in your project repository:
16+
*
17+
* ```
18+
* .distignore
19+
* .editorconfig
20+
* .git
21+
* .gitignore
22+
* .travis.yml
23+
* circle.yml
24+
* ```
25+
*
26+
* Use one distibution archive command for many projects, instead of a bash
27+
* script in each project.
28+
*
29+
* ## OPTIONS
30+
*
31+
* <path>
32+
* : Path to the project that includes a .distignore file.
33+
*
34+
* [<target>]
35+
* : Path and file name for the distribution archive. Defaults to project directory name plus version, if discoverable.
36+
*
37+
* [--format=<format>]
38+
* : Choose the format for the archive.
39+
* ---
40+
* default: zip
41+
* options:
42+
* - zip
43+
* - targz
44+
* ---
45+
*
46+
* @when before_wp_load
47+
*/
48+
public function __invoke( $args, $assoc_args ) {
49+
list( $path ) = $args;
50+
if ( isset( $args[1] ) ) {
51+
$archive_file = $args[1];
52+
$info = pathinfo( $archive_file );
53+
if ( '.' === $info['dirname'] ) {
54+
$archive_file = getcwd() . '/' . $info['basename'];
55+
}
56+
} else {
57+
$archive_file = null;
58+
}
59+
$path = rtrim( realpath( $path ), '/' );
60+
if ( ! is_dir( $path ) ) {
61+
WP_CLI::error( 'Provided path is not a directory.' );
62+
}
63+
64+
$dist_ignore_path = $path . '/.distignore';
65+
if ( ! file_exists( $dist_ignore_path ) ) {
66+
WP_CLI::error( 'No .distignore file found.' );
67+
}
68+
69+
$maybe_ignored_files = explode( PHP_EOL, file_get_contents( $dist_ignore_path ) );
70+
$ignored_files = array();
71+
$archive_base = basename( $path );
72+
foreach( $maybe_ignored_files as $file ) {
73+
$file = trim( $file );
74+
if ( 0 === strpos( $file, '#' ) || empty( $file ) ) {
75+
continue;
76+
}
77+
if ( is_dir( $path . '/' . $file ) ) {
78+
$file = rtrim( $file, '/' ) . '/*';
79+
}
80+
$ignored_files[] = $archive_base . '/' . $file;
81+
}
82+
83+
$version = '';
84+
foreach( glob( $path . '/*.php' ) as $php_file ) {
85+
$contents = file_get_contents( $php_file, false, null, 0, 5000 );
86+
if ( preg_match( '#\* Version:(.+)#', $contents, $matches ) ) {
87+
$version = '.' . trim( $matches[1] );
88+
break;
89+
}
90+
}
91+
92+
if ( empty( $version ) && file_exists( $path . '/composer.json' ) ) {
93+
$composer_obj = json_decode( file_get_contents( $path . '/composer.json' ) );
94+
if ( ! empty( $composer_obj->version ) ) {
95+
$version = '.' . trim( $composer_obj->version );
96+
}
97+
}
98+
99+
if ( false !== stripos( $version, '-alpha' ) && is_dir( $path . '/.git' ) ) {
100+
$response = WP_CLI::launch( "cd {$path}; git log --pretty=format:'%h' -n 1", false, true );
101+
$maybe_hash = trim( $response->stdout );
102+
if ( $maybe_hash && 7 === strlen( $maybe_hash ) ) {
103+
$version .= '-' . $maybe_hash;
104+
}
105+
}
106+
107+
if ( is_null( $archive_file ) ) {
108+
$archive_file = dirname( $path ) . '/' . $archive_base . $version;
109+
if ( 'zip' === $assoc_args['format'] ) {
110+
$archive_file .= '.zip';
111+
} else if ( 'targz' === $assoc_args['format'] ) {
112+
$archive_file .= '.tar.gz';
113+
}
114+
}
115+
116+
chdir( dirname( $path ) );
117+
118+
if ( 'zip' === $assoc_args['format'] ) {
119+
$excludes = implode( ' --exclude ', $ignored_files );
120+
if ( ! empty( $excludes ) ) {
121+
$excludes = ' --exclude ' . $excludes;
122+
}
123+
$cmd = "zip -r {$archive_file} {$archive_base} {$excludes}";
124+
} else if ( 'targz' === $assoc_args['format'] ) {
125+
$excludes = array_map( function( $ignored_file ){
126+
if ( '/*' === substr( $ignored_file, -2 ) ) {
127+
$ignored_file = substr( $ignored_file, 0, ( strlen( $ignored_file ) - 2 ) );
128+
}
129+
return "--exclude='{$ignored_file}'";
130+
}, $ignored_files );
131+
$excludes = implode( ' ', $excludes );
132+
$cmd = "tar {$excludes} -zcvf {$archive_file} {$archive_base}";
133+
}
134+
135+
WP_CLI::debug( "Running: {$cmd}", 'dist-archive' );
136+
$ret = WP_CLI::launch( escapeshellcmd( $cmd ), false, true );
137+
if ( 0 === $ret->return_code ) {
138+
$filename = pathinfo( $archive_file, PATHINFO_BASENAME );
139+
WP_CLI::success( "Created {$filename}" );
140+
} else {
141+
$error = $ret->stderr ? $ret->stderr : $ret->stdout;
142+
WP_CLI::error( $error );
143+
}
144+
}
145+
146+
}

0 commit comments

Comments
 (0)