Skip to content

Commit

Permalink
fixes #4 and other enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
abdumu committed Jul 24, 2020
1 parent d7721e6 commit fd71dbf
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 80 deletions.
110 changes: 58 additions & 52 deletions src/ConfigFileFixer.php
Expand Up @@ -67,14 +67,16 @@ protected function fixForVersion1_0()
//1: get options{} values and add em to root of 'module.exports' and add last value as theme: {..
preg_match('/options:\s*\{([^\}]+)\},?/', $this->searchAndReplace->get(), $match);
$options = $match[1] ?? '';
$updatedToThemeKey = "module.exports = {\n".$options."\n\ntheme: {\n";
$updatedToThemeKey = "module.exports = {\n" . $options . "\n\ntheme: {\n";

$this->searchAndReplace->perform('options:\s*\{([^\}]+)\},?', '', SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace->perform('module.exports\s*=\s*\{', $updatedToThemeKey, SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace
->shouldEscape(false)
->perform('options:\s*\{([^\}]+)\},?', '')
->perform('module.exports\s*=\s*\{', $updatedToThemeKey)

//2: add closing } before modules: {
//3: change modules: { to variants: {
$this->searchAndReplace->perform('modules\:\s*\{', "},\n\nvariants: {", SearchAndReplace::NO_ESCAPE);
//2: add closing } before modules: {
//3: change modules: { to variants: {
->perform('modules\:\s*\{', "},\n\nvariants: {");

//4: updates keys inside theme: { to new names.
//5: updates keys inside variants: { to new names.
Expand All @@ -95,69 +97,73 @@ protected function fixForVersion1_0()
'lists\:{regex_line}' => "listStylePosition:{regex_line}\nlistStyleType:{regex_line}",
'position\:{regex_line}' => "position:{regex_line}\ninset:{regex_line}",
'whitespace\:{regex_line}' => "whitespace:{regex_line}\nwordBreak:{regex_line}",
'textStyle\:{regex_line}' => "fontStyle:{regex_line}\nfontSmoothing:{regex_line}".
'textStyle\:{regex_line}' => "fontStyle:{regex_line}\nfontSmoothing:{regex_line}" .
"\ntextDecoration:{regex_line}\ntextTransform:{regex_line}",
'flexbox\:{regex_line}' => "flexDirection:{regex_line}\nflexWrap:{regex_line}".
"\nalignItems:{regex_line}\nalignSelf:{regex_line}".
"\njustifyContent:{regex_line}\nalignContent:{regex_line}".
"\nflex:{regex_line}\nflexGrow:{regex_line}".
'flexbox\:{regex_line}' => "flexDirection:{regex_line}\nflexWrap:{regex_line}" .
"\nalignItems:{regex_line}\nalignSelf:{regex_line}" .
"\njustifyContent:{regex_line}\nalignContent:{regex_line}" .
"\nflex:{regex_line}\nflexGrow:{regex_line}" .
"\nflexShrink:{regex_line}",
];

foreach ($newNames as $old => $new) {
$this->searchAndReplace->perform($old, $new, SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace->shouldEscape(false)->perform($old, $new);
}

//6: add corePlugins: { to root.
//7: remove container from plugins and add it to corePlugins
preg_match('/require\(\'tailwindcss\/plugins\/container\'\)\(\{([^\}]+)\}\)/', $this->searchAndReplace->get(), $match);
$containerOptions = $match[1] ?? '';

$this->searchAndReplace->perform('require\(\'tailwindcss\/plugins\/container\'\)\(\{([^\}]+)\}\),?', '', SearchAndReplace::NO_ESCAPE);
$corePlugins = 'corePlugins: {'.(empty($containerOptions) ? "\ncontainer: false," : '')."\n}, \nplugins: [";
$this->searchAndReplace->shouldEscape(false)->perform('require\(\'tailwindcss\/plugins\/container\'\)\(\{([^\}]+)\}\),?', '');
$corePlugins = 'corePlugins: {' . (empty($containerOptions) ? "\ncontainer: false," : '') . "\n}, \nplugins: [";

$this->searchAndReplace->perform('plugins:\s*\[', $corePlugins, SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace->perform('theme:\s*\{', "theme: \n{\ncontainer: {\n".$containerOptions."\n},\n", SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace
->shouldEscape(false)
->perform('plugins:\s*\[', $corePlugins)
->perform('theme:\s*\{', "theme: \n{\ncontainer: {\n" . $containerOptions . "\n},\n");

//8: fix colors
$colors = "\n transparent: 'transparent',\n\n black: '#000',\n white: '#fff',".
"\n gray: {\n100: '#f7fafc',\n200: '#edf2f7',\n300: '#e2e8f0',".
"\n400: '#cbd5e0',\n500: '#a0aec0',\n600: '#718096',\n700: '#4a5568',".
"\n800: '#2d3748',\n900: '#1a202c',\n},\n".
"\n red: {\n100: '#fff5f5',\n200: '#fed7d7',\n300: '#feb2b2',\n400: '#fc8181',".
"\n500: '#f56565',\n600: '#e53e3e',\n700: '#c53030',\n800: '#9b2c2c',".
"\n900: '#742a2a',\n},\n".
"\n orange: {\n100: '#fffaf0',\n200: '#feebc8',\n300: '#fbd38d',".
"\n400: '#f6ad55',\n500: '#ed8936',\n600: '#dd6b20',\n700: '#c05621',".
"\n800: '#9c4221',\n900: '#7b341e',\n},\n".
"\n yellow: {\n100: '#fffff0',\n200: '#fefcbf',\n300: '#faf089',".
"\n400: '#f6e05e',\n500: '#ecc94b',\n600: '#d69e2e',\n700: '#b7791f',".
"\n800: '#975a16',\n900: '#744210',\n},\n".
"\n green: {\n100: '#f0fff4',\n200: '#c6f6d5',\n300: '#9ae6b4',".
"\n400: '#68d391',\n500: '#48bb78',\n600: '#38a169',\n700: '#2f855a',".
"\n800: '#276749',\n900: '#22543d',\n},".
"\n teal: {\n100: '#e6fffa',\n200: '#b2f5ea',\n300: '#81e6d9',".
"\n400: '#4fd1c5',\n500: '#38b2ac',\n600: '#319795',\n700: '#2c7a7b',".
"\n800: '#285e61',\n900: '#234e52',\n},\n".
"\n blue: {\n100: '#ebf8ff',\n200: '#bee3f8',\n300: '#90cdf4',".
"\n400: '#63b3ed',\n500: '#4299e1',\n600: '#3182ce',\n700: '#2b6cb0', ".
"\n800: '#2c5282',\n900: '#2a4365',\n},".
"\n indigo: {\n100: '#ebf4ff',\n200: '#c3dafe',\n300: '#a3bffa',".
"\n400: '#7f9cf5',\n500: '#667eea',\n600: '#5a67d8',\n700: '#4c51bf',".
"\n800: '#434190',\n900: '#3c366b',\n},\n".
"\n purple: {\n100: '#faf5ff',\n200: '#e9d8fd',\n300: '#d6bcfa',".
"\n400: '#b794f4',\n500: '#9f7aea',\n600: '#805ad5',\n700: '#6b46c1',".
"\n800: '#553c9a',\n900: '#44337a',\n},\n".
"\n pink: {\n100: '#fff5f7',\n200: '#fed7e2',\n300: '#fbb6ce',".
"\n400: '#f687b3',\n500: '#ed64a6',\n600: '#d53f8c',\n700: '#b83280',".
$colors = "\n transparent: 'transparent',\n\n black: '#000',\n white: '#fff'," .
"\n gray: {\n100: '#f7fafc',\n200: '#edf2f7',\n300: '#e2e8f0'," .
"\n400: '#cbd5e0',\n500: '#a0aec0',\n600: '#718096',\n700: '#4a5568'," .
"\n800: '#2d3748',\n900: '#1a202c',\n},\n" .
"\n red: {\n100: '#fff5f5',\n200: '#fed7d7',\n300: '#feb2b2',\n400: '#fc8181'," .
"\n500: '#f56565',\n600: '#e53e3e',\n700: '#c53030',\n800: '#9b2c2c'," .
"\n900: '#742a2a',\n},\n" .
"\n orange: {\n100: '#fffaf0',\n200: '#feebc8',\n300: '#fbd38d'," .
"\n400: '#f6ad55',\n500: '#ed8936',\n600: '#dd6b20',\n700: '#c05621'," .
"\n800: '#9c4221',\n900: '#7b341e',\n},\n" .
"\n yellow: {\n100: '#fffff0',\n200: '#fefcbf',\n300: '#faf089'," .
"\n400: '#f6e05e',\n500: '#ecc94b',\n600: '#d69e2e',\n700: '#b7791f'," .
"\n800: '#975a16',\n900: '#744210',\n},\n" .
"\n green: {\n100: '#f0fff4',\n200: '#c6f6d5',\n300: '#9ae6b4'," .
"\n400: '#68d391',\n500: '#48bb78',\n600: '#38a169',\n700: '#2f855a'," .
"\n800: '#276749',\n900: '#22543d',\n}," .
"\n teal: {\n100: '#e6fffa',\n200: '#b2f5ea',\n300: '#81e6d9'," .
"\n400: '#4fd1c5',\n500: '#38b2ac',\n600: '#319795',\n700: '#2c7a7b'," .
"\n800: '#285e61',\n900: '#234e52',\n},\n" .
"\n blue: {\n100: '#ebf8ff',\n200: '#bee3f8',\n300: '#90cdf4'," .
"\n400: '#63b3ed',\n500: '#4299e1',\n600: '#3182ce',\n700: '#2b6cb0', " .
"\n800: '#2c5282',\n900: '#2a4365',\n}," .
"\n indigo: {\n100: '#ebf4ff',\n200: '#c3dafe',\n300: '#a3bffa'," .
"\n400: '#7f9cf5',\n500: '#667eea',\n600: '#5a67d8',\n700: '#4c51bf'," .
"\n800: '#434190',\n900: '#3c366b',\n},\n" .
"\n purple: {\n100: '#faf5ff',\n200: '#e9d8fd',\n300: '#d6bcfa'," .
"\n400: '#b794f4',\n500: '#9f7aea',\n600: '#805ad5',\n700: '#6b46c1'," .
"\n800: '#553c9a',\n900: '#44337a',\n},\n" .
"\n pink: {\n100: '#fff5f7',\n200: '#fed7e2',\n300: '#fbb6ce'," .
"\n400: '#f687b3',\n500: '#ed64a6',\n600: '#d53f8c',\n700: '#b83280'," .
"\n800: '#97266d',\n900: '#702459',\n},\n";

$this->searchAndReplace->perform('let colors\s*=\s*\{([^\}]+)\}', '', SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace->perform('\s+colors:\s*colors', ' colors: {'.$colors.'}', SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace->perform('backgroundColor:\s*colors', 'backgroundColor: theme => theme(\'colors\')', SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace->perform('textColor:\s*colors', 'textColor: theme => theme(\'colors\')', SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace->perform('borderColor:\s*g([^\n]+)', "borderColor: theme => {\nreturn global.Object.assign({ default: theme('colors.gray.300', 'currentColor') }, theme('colors'))\n},", SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace->perform('require\(\'tailwindcss\/defaultConfig\'\)\(\)', "require('tailwindcss/defaultConfig')", SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace
->shouldEscape(false)
->perform('let colors\s*=\s*\{([^\}]+)\}', '')
->perform('\s+colors:\s*colors', ' colors: {' . $colors . '}')
->perform('backgroundColor:\s*colors', 'backgroundColor: theme => theme(\'colors\')')
->perform('textColor:\s*colors', 'textColor: theme => theme(\'colors\')')
->perform('borderColor:\s*g([^\n]+)', "borderColor: theme => {\nreturn global.Object.assign({ default: theme('colors.gray.300', 'currentColor') }, theme('colors'))\n},")
->perform('require\(\'tailwindcss\/defaultConfig\'\)\(\)', "require('tailwindcss/defaultConfig')");

//TODO: use javascript beautifier package ...
}
Expand Down
74 changes: 60 additions & 14 deletions src/SearchAndReplace.php
Expand Up @@ -10,9 +10,11 @@ class SearchAndReplace

protected $givenContent = '';

const INSIDE_CLASSE_PROP = 1;
const NO_ESCAPE = 2;
const AFTER_APPLY_DIRECTIVE = 4;
protected $escape = true;

protected $inlineCSS = false;

protected $afterApply = false;

/**
* initiate the converter class.
Expand All @@ -28,6 +30,31 @@ public function __construct($content = null)
return $this;
}

public function shouldEscape($toggle): self
{
$this->escape = $toggle;

return $this;
}

public function isInlineCSS($toggle)
{
$this->inlineCSS = $toggle;
if ($toggle) {
$this->afterApply = false;
}
return $this;
}

public function isAfterApply($toggle)
{
$this->afterApply = $toggle;
if ($toggle) {
$this->inlineCSS = false;
}
return $this;
}

/**
* Get the converted content.
*
Expand Down Expand Up @@ -87,30 +114,47 @@ protected function isInLastSearches(string $searchFor, $limitLast = 0)
return false;
}

protected function addToLastSearches($search)
{
$this->changes++;

$search = stripslashes($search);

if ($this->isInLastSearches($search)) {
return;
}

$this->lastSearches[] = $search;

if (count($this->lastSearches) >= 50) {
array_shift($this->lastSearches);
}
}

/**
* Search the given content and replace.
*
* @param string $search
* @param string $replace
*
* @return null
*/
public function perform($search, $replace, $options = null)
public function perform($search, $replace)
{
$currentContent = $this->givenContent;

if ($options & self::INSIDE_CLASSE_PROP) {
if ($replace instanceof \Closure) {
$callableReplace = \Closure::bind($replace, $this, self::class);
$replace = $callableReplace();
}

$regexStart = $this->afterApply ? '(?<start>@apply\s*.*?)' : '(?<start>\s*)';
$regexEnd = $this->afterApply ? '(?<end>.*?[;\n])' : '(?<end>\s*)';

if($this->inlineCSS) {
$regexStart = '(?<start>class\s*=\s*(?<quotation>["\'])((?!\k<quotation>).)*)';
$regexEnd = '(?<end>((?!\k<quotation>).)*\k<quotation>)';
} elseif ($options & self::AFTER_APPLY_DIRECTIVE) {
$regexStart = '(?<start>@apply\s*.*?)';
$regexEnd = '(?<end>.*?[;\n])';
} else {
$regexStart = '(?<start>\s*)';
$regexEnd = '(?<end>\s*)';
}

if ($options ^ self::NO_ESCAPE) {
if ($this->escape) {
$search = preg_quote($search);
}

Expand Down Expand Up @@ -156,5 +200,7 @@ function ($match) use ($replace) {
$this->lastSearches = array_slice($this->lastSearches, -10, 10, true);
}
}

return $this;
}
}
27 changes: 19 additions & 8 deletions src/Updater.php
Expand Up @@ -74,7 +74,7 @@ public function get()
}

/**
* Get the number of comitted changes.
* Get the number of committed changes.
*
* @return int
*/
Expand Down Expand Up @@ -102,7 +102,10 @@ protected function convertToVersion1_0()
];

foreach ($cssChanges as $old => $new) {
$this->searchAndReplace->perform($old, $new, SearchAndReplace::NO_ESCAPE);
$this->searchAndReplace
->isInlineCSS(!$isCSSfile)
->shouldEscape(false)
->perform($old, $new);
}
}

Expand All @@ -125,6 +128,7 @@ protected function convertToVersion1_0()

//colors
'{regex_string}-grey' => '{regex_string}-gray-500',
'{regex_string}-grey-{regex_string}' => '{regex_string}-gray-{regex_string}',
'{regex_string}-red' => '{regex_string}-red-500',
'{regex_string}-orange' => '{regex_string}-orange-500',
'{regex_string}-yellow' => '{regex_string}-yellow-500',
Expand All @@ -148,22 +152,29 @@ protected function convertToVersion1_0()
];

foreach ($classes as $beforeClass => $afterClass) {
$this->searchAndReplace->perform(
$this->searchAndReplace
->isAfterApply($isCSSfile)
->perform(
($isCSSfile ? '.' : '').$beforeClass,
($isCSSfile ? '.' : '').$afterClass,
$isCSSfile ? SearchAndReplace::AFTER_APPLY_DIRECTIVE : SearchAndReplace::INSIDE_CLASSE_PROP
($isCSSfile ? '.' : '').$afterClass
);
}

//empty variant
$this->searchAndReplace->perform(($isCSSfile ? '\.' : '(?>[a-z]+:)?').'no-underline', '', SearchAndReplace::NO_ESCAPE);

$this->searchAndReplace
->shouldEscape(false)
->isInlineCSS(false)
->isAfterApply(false)
->perform(($isCSSfile ? '\.' : '(?>[a-z-]+:)?').'no-underline', '');

if ($isCSSfile) {
return;
}

foreach ($htmlTags as $beforeTag => $afterTag) {
$this->searchAndReplace->perform($beforeTag, $afterTag);
$this->searchAndReplace
->isInlineCSS(!$isCSSfile)
->perform($beforeTag, $afterTag);
}
}
}
4 changes: 2 additions & 2 deletions tailwind-shift
Expand Up @@ -14,7 +14,7 @@ if (file_exists(__DIR__ . '/vendor/autoload.php')) {
require __DIR__ . '/../../autoload.php';
}

(new Application('tailwind-shift', '1.0.8'))
(new Application('tailwind-shift', '1.0.9'))

->register('tailwind-shift')

Expand All @@ -23,7 +23,7 @@ if (file_exists(__DIR__ . '/vendor/autoload.php')) {
->addOption('replace', null, InputOption::VALUE_REQUIRED, 'This will overwrite the original file.', false)

->addOption('recursive', 'r', InputOption::VALUE_OPTIONAL, 'This will recurse through all directories under the main directory', false)
->addOption('fixconfig', 'x', InputOption::VALUE_OPTIONAL, 'This must be added if givem file is tailwind config file, to fix and update to latest version.', false)
->addOption('fixconfig', 'x', InputOption::VALUE_OPTIONAL, 'This must be added if given file is tailwind config file, to fix and update to latest version.', false)

->addOption('extensions', 'e', InputOption::VALUE_REQUIRED, 'This allows for custom extensions', 'php,html,css')

Expand Down
30 changes: 30 additions & 0 deletions tests/ConfigFileFixerTest.php
@@ -0,0 +1,30 @@
<?php

namespace Awssat\TailwindShift\Test;

use Awssat\TailwindShift\ConfigFileFixer;
use PHPUnit\Framework\TestCase;

class ConfigFileFixerTest extends TestCase
{
/** @var \Awssat\TailwindShift\ConfigFileFixer */
protected $configFixer;

protected function setUp(): void
{
//TODO: phpUnit 8 incompatibility, void error.
$this->configFixer = new ConfigFileFixer();
}

/** @test */
public function it_return_output()
{
$this->assertStringContainsString(
'theme:',
$this->configFixer->setContent("let colors = {};
module.exports = {
colors: colors,
}")->fix()->get()
);
}
}
8 changes: 4 additions & 4 deletions tests/SearchAndReplaceTest.php
Expand Up @@ -20,10 +20,10 @@ public function it_respects_repeated_regex_search_param()
{
$this->searchAndReplace
->setContent('<tag class="life-is-sad"></tag>')
->isInlineCSS(true)
->perform(
'{regex_string}-{regex_string}-sad',
'{regex_string}-{regex_string}-fun',
SearchAndReplace::INSIDE_CLASSE_PROP
'{regex_string}-{regex_string}-fun'
);

$this->assertEquals(
Expand All @@ -37,10 +37,10 @@ public function it_respects_repeated_regex_replace_param()
{
$this->searchAndReplace
->setContent('<tag class="life-is-sad"></tag>')
->isInlineCSS(true)
->perform(
'life-is-{regex_string}',
'{regex_string}-is-{regex_string}',
SearchAndReplace::INSIDE_CLASSE_PROP
'{regex_string}-is-{regex_string}'
);

$this->assertEquals(
Expand Down

0 comments on commit fd71dbf

Please sign in to comment.