WordPress.org

Making WordPress.org

Ticket #5207: 5207-assets.diff

File 5207-assets.diff, 6.1 KB (added by coreymckrill, 12 months ago)

First stab at refactoring block and asset detection

  • cli/class-import.php

     
    443443                        );
    444444                }
    445445
    446                 // Find blocks
     446                if ( 'trunk' === $stable_tag ) {
     447                        $stable_path = $stable_tag;
     448                } else {
     449                        $stable_path  = 'tags/';
     450                        $stable_path .= $_stable_tag ?? $stable_tag;
     451                }
     452
     453                // Find registered blocks and their files.
    447454                $blocks = array();
    448                 $files_with_blocks = array();
    449                 foreach ( Filesystem::list_files( "$tmp_dir/export/", true /* recursive */, '!\.(?:php|js|jsx|json)$!i' ) as $filename ) {
    450                         $file_blocks = $this->find_blocks_in_file( $filename );
    451                         if ( $file_blocks ) {
    452                                 $files_with_blocks[] = str_replace( "$tmp_dir/export/", '', $filename );
    453                                 foreach ( $file_blocks as $block ) {
    454                                         // If the info came from a block.json file with more metadata (like description) then we want it to override less detailed info scraped from php/js.
    455                                         if ( empty( $blocks[ $block->name ]->title ) || isset( $block->description ) ) {
     455                $block_files = array();
     456                $potential_block_directories = array();
     457                $base_dir = "$tmp_dir/export";
     458
     459                $block_json_files = Filesystem::list_files( $base_dir, true, '!^block\.json$!i' );
     460                if ( ! empty( $block_json_files ) ) {
     461                        foreach ( $block_json_files as $filename ) {
     462                                $blocks_in_file = $this->find_blocks_in_file( $filename );
     463                                $relative_filename = str_replace( "$base_dir/", '', $filename );
     464                                $potential_block_directories[] = dirname( $relative_filename );
     465                                foreach ( $blocks_in_file as $block ) {
     466                                        $blocks[ $block->name ] = $block;
     467
     468                                        $extracted_files = $this->extract_file_paths_from_block_json( $block, dirname( $relative_filename ) );
     469                                        if ( ! empty( $extracted_files ) ) {
     470                                                $block_files = array_merge(
     471                                                        $block_files,
     472                                                        array_map(
     473                                                                function( $file ) use ( $stable_path ) {
     474                                                                        return "/$stable_path/" . ltrim( $file, '\\' );
     475                                                                },
     476                                                                $extracted_files
     477                                                        )
     478                                                );
     479                                        }
     480                                }
     481                        }
     482                } else {
     483                        foreach ( Filesystem::list_files( $base_dir, true, '!\.(?:php|js|jsx)$!i' ) as $filename ) {
     484                                $blocks_in_file = $this->find_blocks_in_file( $filename );
     485                                if ( ! empty( $blocks_in_file ) ) {
     486                                        $relative_filename = str_replace( "$base_dir/", '', $filename );
     487                                        $potential_block_directories[] = dirname( $relative_filename );
     488                                        foreach ( $blocks_in_file as $block ) {
    456489                                                $blocks[ $block->name ] = $block;
    457490                                        }
    458491                                }
     
    460493                }
    461494
    462495                foreach ( $blocks as $block_name => $block ) {
    463                         if ( empty( $block->title ) )
     496                        if ( empty( $block->title ) ) {
    464497                                $blocks[ $block_name ]->title = $trunk_readme->name;
     498                        }
    465499                }
    466500
    467                 // Find blocks dist/build JS files
    468                 $block_files = array();
    469                 $dist_files = SVN::ls( 'https://plugins.svn.wordpress.org' . "/{$plugin_slug}/{$stable_tag}/dist" ) ?: array();
    470                 $build_files = SVN::ls( 'https://plugins.svn.wordpress.org' . "/{$plugin_slug}/{$stable_tag}/build" ) ?: array();
     501                // Only search for block files if none were found in a block.json.
     502                if ( empty( $block_files ) ) {
     503                        $build_files = array();
    471504
    472                 foreach ( $dist_files as $file ) {
    473                         $block_files[] = "/{$stable_tag}/dist/" . $file;
    474                 }
     505                        if ( ! empty( $potential_block_directories ) ) {
     506                                $potential_block_directories = array_unique( $potential_block_directories );
    475507
    476                 foreach ( $build_files as $file ) {
    477                         $block_files[] = "/{$stable_tag}/build/" . $file;
    478                 }
     508                                foreach ( $potential_block_directories as $block_dir ) {
     509                                        // dirname() returns . when there is no directory separator present.
     510                                        if ( '.' === $block_dir ) {
     511                                                $block_dir = '';
     512                                        }
    479513
    480                 if ( empty( $block_files ) ) {
    481                         foreach ( $files_with_blocks as $file ) {
    482                                 $block_files[] = "/{$stable_tag}/" . $file;
     514                                        // First look for a dedicated "build" or "dist" directory.
     515                                        foreach ( array( 'build', 'dist' ) as $dirname ) {
     516                                                if ( is_dir( "$base_dir/$block_dir/$dirname" ) ) {
     517                                                        $build_files += Filesystem::list_files( "$base_dir/$block_dir/$dirname", true, '!\.(?:js|jsx|css)$!i' );
     518                                                }
     519                                        }
     520
     521                                        // There must be at least on JS file, so if only css was found, keep looking.
     522                                        if ( empty( preg_grep( '!\.(?:js|jsx)$!i', $build_files ) ) ) {
     523                                                // Then check for files in the current directory with "build" or "min" in the filename.
     524                                                $build_files += Filesystem::list_files( "$base_dir/$block_dir", false, '![_\-\.]+(?:build|dist|min)[_\-\.]+!i' );
     525                                        }
     526
     527                                        if ( empty( preg_grep( '!\.(?:js|jsx)$!i', $build_files ) ) ) {
     528                                                // Finally, just grab whatever js/css files there are in the current directory.
     529                                                $build_files += Filesystem::list_files( "$base_dir/$block_dir", false, '!\.(?:js|jsx|css)$!i' );
     530                                        }
     531                                }
    483532                        }
     533
     534                        if ( empty( preg_grep( '!\.(?:js|jsx)$!i', $build_files ) ) ) {
     535                                // Nothing in the potential block directories. Check if we somehow missed build/dist directories in the root.
     536                                foreach ( array( 'build', 'dist' ) as $dirname ) {
     537                                        if ( is_dir( "$base_dir/$dirname" ) ) {
     538                                                $build_files += Filesystem::list_files( "$base_dir/$dirname", true, '!\.(?:js|jsx|css)$!i' );
     539                                        }
     540                                }
     541                        }
     542
     543                        if ( empty( preg_grep( '!\.(?:js|jsx)$!i', $build_files ) ) ) {
     544                                // Still nothing. Take on last wild swing.
     545                                $build_files += Filesystem::list_files( $base_dir, false, '!\.(?:js|jsx|css)$!i' );
     546                        }
     547
     548                        foreach ( $build_files as $file ) {
     549                                $block_files[] = "/$stable_path/" . str_replace( "$base_dir/", '', $file );
     550                        }
    484551                }
    485552
    486553                // Only allow js or css files
     
    600667
    601668                return $blocks;
    602669        }
     670
     671        /**
     672         * Get script and style file paths from an imported block.json.
     673         *
     674         * @param object $parsed_json
     675         * @param string $block_json_path
     676         *
     677         * @return array
     678         */
     679        protected function extract_file_paths_from_block_json( $parsed_json, $block_json_path = '' ) {
     680                $files = array();
     681
     682                $props = array( 'editorScript', 'script', 'editorStyle', 'style' );
     683
     684                foreach ( $props as $prop ) {
     685                        if ( isset( $parsed_json->$prop ) ) {
     686                                $files[] = trailingslashit( $block_json_path ) . $parsed_json->$prop;
     687                        }
     688                }
     689
     690                return $files;
     691        }
    603692}