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

Tool to increment the version number of a plugin #169

Open
BrianHenryIE opened this issue Oct 21, 2022 · 5 comments
Open

Tool to increment the version number of a plugin #169

BrianHenryIE opened this issue Oct 21, 2022 · 5 comments

Comments

@BrianHenryIE
Copy link
Member

When developing plugins and releasing new versions, I need to increment the version in three locations:

  • the plugin file header
  • defined as a const in the plugin file PHP body
  • in a getter in my settings.php.

I'm thinking ~ wp increment-plugin-version plugin.php /list/of/paths/to/other/files.php --major where it pulls the current version from plugin.php, increments the major/minor/patch version as requested, and does a find and replace for the past version -> new version in the files listed, and prints out the changes.

I see a comment by @schlessera referencing WP_CLI\Utils\get_file_header(), but that doesn't seem to exist. I see the function seems to be I18n's FileDataExtractor.

  • Is there an existing command this should be a sub-command to?
  • Was get_file_header() ever in WP_CLI\Utils, i.e. was it moved out for any reason/is there any reason it cannot be moved there?
  • Any other suggestions on the name or parameters?
@BrianHenryIE
Copy link
Member Author

Here's the gist, outside of WP CLI:

<?php

$positional_args = array();
$named_args      = array();

// The path of this PHP file is $argv[0].
unset( $argv[0] );
foreach ( $argv as $arg ) {
	if ( 0 === strpos( $arg, '--' ) ) {
		$split                   = explode( '=', substr( $arg, 2 ) );
		$named_args[ $split[0] ] = $split[1];
	} else {
		$positional_args[] = $arg;
	}
}

$version_to_increment = isset( $named_args['version'] ) ? $named_args['version'] : 'patch';

$plugin_file = isset( $positional_args[0] ) ? $positional_args[0] : basename( getcwd() ) . '.php';

$plugin_file_path = getcwd() . '/' . $plugin_file;

$file_contents = file_get_contents( $plugin_file_path );

if ( false !== preg_match_all( '/(\s*\*\s*Version:\s*)(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/', $file_contents, $matches ) ) {

	$version_major = $matches['major'][0];
	$version_minor = $matches['minor'][0];
	$version_patch = $matches['patch'][0];

	$old_version = "$version_major.$version_minor.$version_patch";

	switch ( $version_to_increment ) {
		case 'major':
			++$version_major;
			$version_minor = 0;
			$version_patch = 0;
			break;
		case 'minor':
			++$version_minor;
			$version_patch = 0;
			break;
		default:
			++$version_patch;
	}

	$new_version = "$version_major.$version_minor.$version_patch";

	error_log( "Incrementing version from $old_version to $new_version." );

	$file_content_updated_header = str_replace( $matches[0][0], $matches[1][0] . $new_version, $file_contents );

	$file_content_updated_throughout = preg_replace( '/(["\'])' . $old_version . '(["\'])/', "'$new_version'", $file_content_updated_header );

	file_put_contents( $plugin_file_path, $file_content_updated_throughout );

	error_log( "Version incremented in $plugin_file_path" );

	foreach ( $positional_args as $file_path ) {
		if ( 0 !== strpos( $file_path, '/' ) ) {
			$file_path = getcwd() . '/' . $file_path;
		}
		if ( $file_path === $plugin_file_path ) {
			continue;
		}
		if ( ! file_exists( $file_path ) ) {
			error_log( 'File not found: ' . $file_path );
			continue;
		}
		$file_contents         = file_get_contents( $file_path );
		$file_contents_updated = preg_replace( '/(["\'])' . $old_version . '(["\'])/', "'$new_version'", $file_contents );
		if ( $file_contents_updated !== $file_contents ) {
			file_put_contents( $file_path, $file_contents_updated );
			error_log( "Version incremented in $file_path" );
		} else {
			error_log( "Failed to find old version $old_version in $file_path" );
		}
	}
} else {
	echo 'Failed to get plugin version from file';
}

@schlessera
Copy link
Member

@BrianHenryIE First of all, I'm not sure it makes sense to have this be a WP-CLI command, as there's no benefit to be had from executing WordPress or using WordPress-specific contextual knowledge to make this work. It is basically just a smart sed command.

That being said, I still want to answer your questions above:

  1. In case we'd agree that this should be a WP-CLI command, then the most fitting would be the plugin command, using something like wp plugin increment-version.
  2. No, this has never existed so far, and the comment you're referring to suggested that we should copy the WP version of this into a WP-CLI\Utils\get_file_header() version to internalize it and decouple it from a WP installation. This has not happened yet, but would be the suggested way to go about this.
  3. As shown as an example in 1., this should follow the wp <noun> <verb> structure, like wp plugin increment-version.

@BrianHenryIE
Copy link
Member Author

Tagging #193 as related.

And while I'm here, to note wppm.io as a SaaS that addresses this problem.

I agree WordPress does not need to be loaded, and that it is just a fancy sed, but it is a problem whose solution has been reinvented by hundreds if not thousands of developers. I don't want to close this yet, I'll leave it open with the hope I can perfectly, succinctly address it eventually.

I'm imagining a step in a GitHub Actions release workflow ~ if version != tag, wp plugin increment-version $tag.

@swissspidy
Copy link
Member

I'm definitely guilty of reinventing such a fancy sed myself. Like in the original issue description, in my projects I usually need to bump the version in multiple places:

  • Main plugin file header (
  • A constant in the main plugin file (sometimes contains a git hash)
  • readme.txt Stable Tag (if doing a stable release and not a nightly)

In other projects there are also some more complex scripts where the version number is just a placeholder (even in @since docblocks) and then before the release it is updated with the new version number.

So far these projects have all had their differences, so I am not sure if there is a one-size-fits-all solution for this kind of task. And if so, it might not necessarily be WP-CLI.

@ernilambar
Copy link
Member

I also needed similar tool so that I dont miss updating plugin version. So I created node package for the purpose. https://github.com/ernilambar/easy-replace-in-files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants