1414use Symfony \Component \Console \Input \InputInterface ;
1515use Symfony \Component \Console \Output \OutputInterface ;
1616use Symfony \Component \Console \Style \SymfonyStyle ;
17+ use Symfony \Component \Yaml \Yaml ;
1718use Symfonycasts \TailwindBundle \TailwindBuilder ;
19+ use Symfonycasts \TailwindBundle \TailwindVersionFinder ;
1820
1921#[AsCommand(
2022 name: 'tailwind:init ' ,
2325class TailwindInitCommand extends Command
2426{
2527 public function __construct (
26- private TailwindBuilder $ tailwindBuilder ,
28+ private TailwindVersionFinder $ versionFinder ,
29+ private array $ inputCss ,
30+ private string $ rootDir ,
2731 ) {
2832 parent ::__construct ();
2933 }
3034
31- protected function configure (): void
32- {
33- }
34-
3535 protected function execute (InputInterface $ input , OutputInterface $ output ): int
3636 {
3737 $ io = new SymfonyStyle ($ input , $ output );
38- if (!$ this ->createTailwindConfig ($ io )) {
38+
39+ if (!$ input ->isInteractive ()) {
40+ throw new \RuntimeException ('tailwind:init command must be run interactively. ' );
41+ }
42+
43+ $ bundleConfig = $ this ->bundleConfig ();
44+
45+ if ($ io ->confirm ('Are you managing your own Taildind CSS binary? ' , false )) {
46+ $ binaryPath = $ io ->ask ('Enter the path to your Tailwind CSS binary: ' , 'node_modules/.bin/tailwindcss ' );
47+ $ bundleConfig ['symfonycasts_tailwind ' ]['binary ' ] = $ binaryPath ;
48+ } else {
49+ $ majorVersion = $ io ->ask ('Which major version do you wish to use? ' , '4 ' );
50+ $ latestVersion = $ this ->versionFinder ->latestVersionFor ($ majorVersion );
51+ $ bundleConfig ['symfonycasts_tailwind ' ]['binary_version ' ] = $ latestVersion ;
52+ }
53+
54+ file_put_contents ($ this ->bundleConfigFile (), Yaml::dump ($ bundleConfig ));
55+
56+ $ builder = new TailwindBuilder (
57+ $ this ->rootDir ,
58+ $ this ->inputCss ,
59+ $ this ->rootDir .'/var/tailwind ' ,
60+ binaryPath: $ bundleConfig ['symfonycasts_tailwind ' ]['binary ' ] ?? null ,
61+ binaryVersion: $ bundleConfig ['symfonycasts_tailwind ' ]['binary_version ' ] ?? null ,
62+ );
63+
64+ if (!$ this ->createTailwindConfig ($ io , $ builder )) {
3965 return self ::FAILURE ;
4066 }
4167
42- $ this ->addTailwindDirectives ($ io );
68+ $ this ->addTailwindDirectives ($ io, $ builder );
4369
4470 $ io ->success ('Tailwind CSS is ready to use! ' );
4571
4672 return self ::SUCCESS ;
4773 }
4874
49- private function createTailwindConfig (SymfonyStyle $ io ): bool
75+ private function createTailwindConfig (SymfonyStyle $ io, TailwindBuilder $ builder ): bool
5076 {
51- if ($ this -> tailwindBuilder ->createBinary ()->isV4 ()) {
77+ if ($ builder ->createBinary ()->isV4 ()) {
5278 $ io ->note ('Tailwind v4 detected: skipping config file creation. ' );
5379
5480 return true ;
5581 }
5682
57- $ configFile = $ this ->tailwindBuilder ->getConfigFilePath ();
83+ $ configFile = $ builder ->getConfigFilePath ();
84+
5885 if (file_exists ($ configFile )) {
5986 $ io ->note (\sprintf ('Tailwind config file already exists in "%s" ' , $ configFile ));
6087
6188 return true ;
6289 }
6390
64- $ this -> tailwindBuilder ->setOutput ($ io );
91+ $ builder ->setOutput ($ io );
6592
66- $ process = $ this -> tailwindBuilder ->runInit ();
93+ $ process = $ builder ->runInit ();
6794 $ process ->wait (function ($ type , $ buffer ) use ($ io ) {
6895 $ io ->write ($ buffer );
6996 });
@@ -96,9 +123,9 @@ private function createTailwindConfig(SymfonyStyle $io): bool
96123 return true ;
97124 }
98125
99- private function addTailwindDirectives (SymfonyStyle $ io ): void
126+ private function addTailwindDirectives (SymfonyStyle $ io, TailwindBuilder $ builder ): void
100127 {
101- $ inputFile = $ this -> tailwindBuilder ->getInputCssPaths ()[0 ];
128+ $ inputFile = $ builder ->getInputCssPaths ()[0 ];
102129 $ contents = is_file ($ inputFile ) ? file_get_contents ($ inputFile ) : '' ;
103130 if (str_contains ($ contents , '@tailwind base ' ) || str_contains ($ contents , '@import "tailwindcss" ' )) {
104131 $ io ->note (\sprintf ('Tailwind directives already exist in "%s" ' , $ inputFile ));
@@ -113,12 +140,30 @@ private function addTailwindDirectives(SymfonyStyle $io): void
113140 @tailwind utilities;
114141 EOF ;
115142
116- if ($ this -> tailwindBuilder ->createBinary ()->isV4 ()) {
143+ if ($ builder ->createBinary ()->isV4 ()) {
117144 $ tailwindDirectives = <<<EOF
118145 @import "tailwindcss";
119146 EOF ;
120147 }
121148
122149 file_put_contents ($ inputFile , $ tailwindDirectives ."\n\n" .$ contents );
123150 }
151+
152+ private function bundleConfigFile (): string
153+ {
154+ return $ this ->rootDir .'/config/packages/symfonycasts_tailwind.yaml ' ;
155+ }
156+
157+ private function bundleConfig (): array
158+ {
159+ if (!class_exists (Yaml::class)) {
160+ throw new \RuntimeException ('You are using a non-standard Symfony setup. You will need to initialize this bundle manually. ' );
161+ }
162+
163+ if (!file_exists ($ this ->bundleConfigFile ())) {
164+ return [];
165+ }
166+
167+ return Yaml::parseFile ($ this ->bundleConfigFile ());
168+ }
124169}
0 commit comments