crosup_macros/
lib.rs

1#[macro_export]
2macro_rules! pipe_curl {
3    ($curl:ident) => {
4        let mut child = std::process::Command::new("bash")
5            .stdin(Stdio::from($curl.stdout.unwrap()))
6            .stdout(Stdio::piped())
7            .spawn()?;
8        let output = child.stdout.take().unwrap();
9        let output = std::io::BufReader::new(output);
10
11        for line in output.lines() {
12            println!("{}", line?);
13        }
14        child.wait()?;
15    };
16}
17
18#[macro_export]
19macro_rules! pipe_brew_curl {
20    ($curl:ident) => {
21        let mut child = std::process::Command::new("bash")
22            .env("NONINTERACTIVE", "true")
23            .stdin(Stdio::from($curl.stdout.unwrap()))
24            .stdout(Stdio::piped())
25            .stderr(Stdio::piped())
26            .spawn()?;
27
28        let stdout = child.stdout.take().unwrap();
29        let stdout = std::io::BufReader::new(stdout);
30        for line in stdout.lines() {
31            println!("   {}", line.unwrap());
32        }
33
34        child.wait()?;
35    };
36}
37
38#[macro_export]
39macro_rules! append_to_nix_conf {
40    ($echo:ident) => {
41        let mut tee = std::process::Command::new("bash")
42            .arg("-c")
43            .arg("sudo tee -a /etc/nix/nix.conf")
44            .stdin(Stdio::from($echo.stdout.unwrap()))
45            .stdout(Stdio::piped())
46            .spawn()?;
47        tee.wait()?;
48    };
49}
50
51#[macro_export]
52macro_rules! brew_install {
53    ($self:ident, $package:expr, $cask:expr, $session:expr) => {
54        let mut child = match $cask {
55            true => std::process::Command::new("brew")
56                .arg("install")
57                .arg("--cask")
58                .arg($package)
59                .stdout(Stdio::piped())
60                .stderr(Stdio::piped())
61                .spawn()?,
62            false => std::process::Command::new("brew")
63                .arg("install")
64                .arg($package)
65                .env(
66                    "PATH",
67                    "/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin",
68                )
69                .stdout(Stdio::piped())
70                .stderr(Stdio::piped())
71                .spawn()?,
72        };
73
74        let stdout = child.stdout.take().unwrap();
75        let stdout = std::io::BufReader::new(stdout);
76        for line in stdout.lines() {
77            println!("   {}", line.unwrap());
78        }
79
80        let output = child.wait_with_output()?;
81
82        if !output.status.success() {
83            println!("-> Failed to install {}", $self.name().bright_green());
84            if !output.stderr.is_empty() {
85                println!("{}", String::from_utf8_lossy(&output.stderr));
86            }
87            return Err(Error::msg(format!("Failed to install {}", $self.name())));
88        }
89    };
90}
91
92#[macro_export]
93macro_rules! check_version {
94    ($self:ident, $command:expr, $session:expr) => {
95        match $session {
96            Some(session) => {
97                let command = format!("sh -c 'PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin type {}'", $command);
98                crosup_ssh::exec(session.clone(), &command)?;
99            }
100            None => {
101                let home = std::env::var("HOME").unwrap();
102                let mut path = std::env::var("PATH").unwrap();
103                path = format!(
104                    "{}/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/home/linuxbrew/.linuxbrew/bin:{}",
105                    home,
106                    path
107                );
108                let child = std::process::Command::new("bash")
109                    .arg("-c")
110                    .arg(format!("type {}", $command))
111                    .env(
112                        "PATH",
113                        path,
114                    )
115                    .stdout(Stdio::piped())
116                    .spawn()?;
117                let output = child.wait_with_output()?;
118
119                if !output.status.success() {
120                    println!("-> Failed to check {} version", $self.name.bright_green());
121                    if !output.stderr.is_empty() {
122                        println!("{}", String::from_utf8_lossy(&output.stderr));
123                    }
124                    return Err(Error::msg(format!(
125                        "Failed to check {} version",
126                        $self.name
127                    )));
128                }
129
130                let stdout = String::from_utf8_lossy(&output.stdout);
131                for line in stdout.lines() {
132                    println!("   {}", line.cyan());
133                }
134            }
135        };
136    };
137}
138
139#[macro_export]
140macro_rules! exec_bash {
141    ($command:expr,$session:expr) => {
142        match $session {
143            Some(session) => {
144                let command = format!("bash -c '{}'", $command);
145                crosup_ssh::exec(session.clone(), &command)?;
146            }
147            None => {
148                let mut child = std::process::Command::new("bash")
149                    .arg("-c")
150                    .arg($command)
151                    .stdout(Stdio::piped())
152                    .spawn()?;
153                child.wait()?;
154            }
155        };
156    };
157}
158
159#[macro_export]
160macro_rules! exec_sh {
161    ($command:expr, $session:expr) => {
162        match $session {
163            Some(session) => {
164                let command = format!("sh -c '{}'", $command);
165                crosup_ssh::exec(session.clone(), &command)?;
166            }
167            None => {
168                let mut child = std::process::Command::new("sh")
169                    .arg("-c")
170                    .arg($command)
171                    .stdout(Stdio::piped())
172                    .spawn()?;
173                child.wait()?;
174            }
175        };
176    };
177}
178
179#[macro_export]
180macro_rules! exec_bash_with_output {
181    ($command:expr, $session:expr) => {
182        match $session {
183            Some(session) => {
184                let command = format!("bash -c '{}'", $command);
185                crosup_ssh::exec(session.clone(), &command)?;
186            }
187            None => {
188                let mut child = std::process::Command::new("bash")
189                    .arg("-c")
190                    .arg($command)
191                    .stdout(Stdio::piped())
192                    .spawn()?;
193                let output = child.stdout.take().unwrap();
194                let output = std::io::BufReader::new(output);
195
196                for line in output.lines() {
197                    println!("{}", line?);
198                }
199                child.wait()?;
200            }
201        };
202    };
203}
204
205#[macro_export]
206macro_rules! exec_sh_with_output {
207    ($command:expr, $session:expr) => {
208        match $session {
209            Some(session) => {
210                let command = format!("sh -c '{}'", $command);
211                crosup_ssh::exec(session.clone(), &command)?;
212            }
213            None => {
214                let mut child = std::process::Command::new("sh")
215                    .arg("-c")
216                    .arg($command)
217                    .stdin(Stdio::piped())
218                    .stdout(Stdio::piped())
219                    .spawn()?;
220                let output = child.stdout.take().unwrap();
221                let output = std::io::BufReader::new(output);
222
223                for line in output.lines() {
224                    println!("{}", line?);
225                }
226                child.wait()?;
227            }
228        };
229    };
230}
231
232#[macro_export]
233macro_rules! apt_install {
234    ($package:expr, $session:expr) => {
235        match $session {
236            Some(session) => {
237                let command = format!("sudo apt-get install -y {}", $package);
238                crosup_ssh::exec(session.clone(), &command)?;
239            }
240            None => {
241                let mut child = std::process::Command::new("sh")
242                    .arg("-c")
243                    .arg(format!("sudo apt-get install -y {}", $package))
244                    .stdin(Stdio::piped())
245                    .stdout(Stdio::piped())
246                    .spawn()?;
247                let output = child.stdout.take().unwrap();
248                let output = std::io::BufReader::new(output);
249
250                for line in output.lines() {
251                    println!("{}", line?);
252                }
253                let status = child.wait()?;
254                if !status.success() {
255                    return Err(Error::msg(format!("Failed to install {}", $package)));
256                }
257            }
258        };
259    };
260}
261
262#[macro_export]
263macro_rules! yum_install {
264    ($package:expr, $session:expr) => {
265        match $session {
266            Some(session) => {
267                let command = format!("sudo yum install -y {}", $package);
268                crosup_ssh::exec(session.clone(), &command)?;
269            }
270            None => {
271                let mut child = std::process::Command::new("sh")
272                    .arg("-c")
273                    .arg(format!("sudo yum install -y {}", $package))
274                    .stdin(Stdio::piped())
275                    .stdout(Stdio::piped())
276                    .spawn()?;
277                let output = child.stdout.take().unwrap();
278                let output = std::io::BufReader::new(output);
279
280                for line in output.lines() {
281                    println!("{}", line?);
282                }
283                let status = child.wait()?;
284                if !status.success() {
285                    return Err(Error::msg(format!("Failed to install {}", $package)));
286                }
287            }
288        };
289    };
290}
291
292#[macro_export]
293macro_rules! dnf_install {
294    ($package:expr, $session:expr) => {
295        match $session {
296            Some(session) => {
297                let command = format!("sudo dnf install -y {}", $package);
298                crosup_ssh::exec(session.clone(), &command)?;
299            }
300            None => {
301                let mut child = std::process::Command::new("sh")
302                    .arg("-c")
303                    .arg(format!("sudo dnf install -y {}", $package))
304                    .stdin(Stdio::piped())
305                    .stdout(Stdio::piped())
306                    .spawn()?;
307                let output = child.stdout.take().unwrap();
308                let output = std::io::BufReader::new(output);
309
310                for line in output.lines() {
311                    println!("{}", line?);
312                }
313                let status = child.wait()?;
314                if !status.success() {
315                    return Err(Error::msg(format!("Failed to install {}", $package)));
316                }
317            }
318        };
319    };
320}
321
322#[macro_export]
323macro_rules! zypper_install {
324    ($package:expr, $options:expr, $session:expr) => {
325        match $session {
326            Some(session) => {
327                let command = format!("sudo zypper install {} {}", $options, $package);
328                crosup_ssh::exec(session.clone(), &command)?;
329            }
330            None => {
331                let mut child = std::process::Command::new("sh")
332                    .arg("-c")
333                    .arg(format!("sudo zypper install {} {}", $options, $package))
334                    .stdin(Stdio::piped())
335                    .stdout(Stdio::piped())
336                    .spawn()?;
337                let output = child.stdout.take().unwrap();
338                let output = std::io::BufReader::new(output);
339
340                for line in output.lines() {
341                    println!("{}", line?);
342                }
343                let status = child.wait()?;
344                if !status.success() {
345                    return Err(Error::msg(format!("Failed to install {}", $package)));
346                }
347            }
348        };
349    };
350}
351
352#[macro_export]
353macro_rules! apk_add {
354    ($package:expr, $options:expr, $session:expr) => {
355        match $session {
356            Some(session) => {
357                let command = format!("sudo apk add {} {}", $options, $package);
358                crosup_ssh::exec(session.clone(), &command)?;
359            }
360            None => {
361                let mut child = std::process::Command::new("sh")
362                    .arg("-c")
363                    .arg(format!("sudo apk add {} {}", $options, $package))
364                    .stdin(Stdio::piped())
365                    .stdout(Stdio::piped())
366                    .spawn()?;
367                let output = child.stdout.take().unwrap();
368                let output = std::io::BufReader::new(output);
369
370                for line in output.lines() {
371                    println!("{}", line?);
372                }
373                let status = child.wait()?;
374                if !status.success() {
375                    return Err(Error::msg(format!("Failed to install {}", $package)));
376                }
377            }
378        };
379    };
380}
381
382#[macro_export]
383macro_rules! pacman_install {
384    ($package:expr, $session:expr) => {
385        match $session {
386            Some(session) => {
387                let command = format!("sudo pacman -S {}", $package);
388                crosup_ssh::exec(session.clone(), &command)?;
389            }
390            None => {
391                let mut child = std::process::Command::new("sh")
392                    .arg("-c")
393                    .arg(format!("sudo pacman -S {}", $package))
394                    .stdin(Stdio::piped())
395                    .stdout(Stdio::piped())
396                    .spawn()?;
397                let output = child.stdout.take().unwrap();
398                let output = std::io::BufReader::new(output);
399
400                for line in output.lines() {
401                    println!("{}", line?);
402                }
403                let status = child.wait()?;
404                if !status.success() {
405                    return Err(Error::msg(format!("Failed to install {}", $package)));
406                }
407            }
408        }
409    };
410}
411
412#[macro_export]
413macro_rules! emerge_install {
414    ($package:expr, $options:expr, $session:expr) => {
415        match $session {
416            Some(session) => {
417                let command = format!("sudo emerge {} {}", $options, $package);
418                crosup_ssh::exec(session.clone(), &command)?;
419            }
420            None => {
421                let mut child = std::process::Command::new("sh")
422                    .arg("-c")
423                    .arg(format!("sudo emerge {} {}", $options, $package))
424                    .stdin(Stdio::piped())
425                    .stdout(Stdio::piped())
426                    .spawn()?;
427                let output = child.stdout.take().unwrap();
428                let output = std::io::BufReader::new(output);
429
430                for line in output.lines() {
431                    println!("{}", line?);
432                }
433                let status = child.wait()?;
434                if !status.success() {
435                    return Err(Error::msg(format!("Failed to install {}", $package)));
436                }
437            }
438        };
439    };
440}
441
442#[macro_export]
443macro_rules! slackpkg_install {
444    ($package:expr, $session:expr) => {
445        match $session {
446            Some(session) => {
447                let command = format!("sudo slackpkg install {}", $package);
448                crosup_ssh::exec(session.clone(), &command)?;
449            }
450            None => {
451                let mut child = std::process::Command::new("sh")
452                    .arg("-c")
453                    .arg(format!("sudo slackpkg {}", $package))
454                    .stdin(Stdio::piped())
455                    .stdout(Stdio::piped())
456                    .spawn()?;
457                let output = child.stdout.take().unwrap();
458                let output = std::io::BufReader::new(output);
459
460                for line in output.lines() {
461                    println!("{}", line?);
462                }
463                let status = child.wait()?;
464                if !status.success() {
465                    return Err(Error::msg(format!("Failed to install {}", $package)));
466                }
467            }
468        };
469    };
470}
471
472#[macro_export]
473macro_rules! fleek_install {
474    ($package:expr, $options:expr, $session:expr) => {
475        match $session {
476            Some(session) => {
477                let command = format!("bash -c '. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix run github:ublue-os/fleek -- add {} {}'", $options, $package);
478                crosup_ssh::exec(session.clone(), &command)?;
479            }
480            None => {
481                let mut child = std::process::Command::new("bash")
482                    .arg("-c")
483                    .arg(format!(". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix run github:ublue-os/fleek -- add {} {}", $options, $package))
484                    .stdin(Stdio::piped())
485                    .stdout(Stdio::piped())
486                    .spawn()?;
487                let output = child.stdout.take().unwrap();
488                let output = std::io::BufReader::new(output);
489
490                for line in output.lines() {
491                    println!("{}", line?);
492                }
493                let status = child.wait()?;
494                if !status.success() {
495                    return Err(Error::msg(format!("Failed to install {}", $package)));
496                }
497            }
498        };
499    };
500}
501
502#[macro_export]
503macro_rules! home_manager_init {
504    ($session:expr) => {
505        match $session {
506            Some(session) => {
507                let command = format!("bash -c '. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix run home-manager/master -- init'");
508                crosup_ssh::exec(session.clone(), &command)?;
509            }
510            None => {
511                let mut child = std::process::Command::new("bash")
512                    .arg("-c")
513                    .arg(format!(". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix run home-manager/master -- init"))
514                    .stdin(Stdio::piped())
515                    .stdout(Stdio::piped())
516                    .spawn()?;
517                let output = child.stdout.take().unwrap();
518                let output = std::io::BufReader::new(output);
519
520                for line in output.lines() {
521                    println!("{}", line?);
522                }
523                let status = child.wait()?;
524                if !status.success() {
525                    return Err(Error::msg(format!("Failed to initialize home-manager")));
526                }
527            }
528        };
529    };
530}
531
532#[macro_export]
533macro_rules! home_manager_switch {
534    ($session:expr) => {
535        match $session {
536            Some(session) => {
537                let command = format!("bash -c '. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix run home-manager/master -- switch'");
538                crosup_ssh::exec(session.clone(), &command)?;
539            }
540            None => {
541                let mut child = std::process::Command::new("bash")
542                    .arg("-c")
543                    .arg(format!(". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix run home-manager/master -- switch"))
544                    .stdin(Stdio::piped())
545                    .stdout(Stdio::piped())
546                    .spawn()?;
547                let output = child.stdout.take().unwrap();
548                let output = std::io::BufReader::new(output);
549
550                for line in output.lines() {
551                    println!("{}", line?);
552                }
553                let status = child.wait()?;
554                if !status.success() {
555                    return Err(Error::msg(format!("Failed to run home-manager switch")));
556                }
557            }
558        };
559    };
560}
561
562#[macro_export]
563macro_rules! exec_sudo {
564    ($command:expr, $session:expr) => {
565        match $session {
566            Some(session) => {
567                let command = format!("sudo {}", $command);
568                crosup_ssh::exec(session.clone(), &command)?;
569            }
570            None => {
571                let mut child = std::process::Command::new("sh")
572                    .arg("-c")
573                    .arg(format!("sudo {}", $command))
574                    .stdin(Stdio::piped())
575                    .stdout(Stdio::piped())
576                    .spawn()?;
577                let output = child.stdout.take().unwrap();
578                let output = std::io::BufReader::new(output);
579
580                for line in output.lines() {
581                    println!("{}", line?);
582                }
583                let status = child.wait()?;
584                if !status.success() {
585                    return Err(Error::msg(format!("Failed to execute {}", $command)));
586                }
587            }
588        }
589    };
590}
591
592#[macro_export]
593macro_rules! exec_piped_sudo {
594    ($command:expr, $stdin:ident) => {
595        let mut child = std::process::Command::new("sh")
596            .arg("-c")
597            .arg(format!("sudo {}", $command))
598            .stdin(Stdio::from($stdin.stdout.unwrap()))
599            .stdout(Stdio::piped())
600            .spawn()?;
601        child.wait()?;
602    };
603}
604
605#[macro_export]
606macro_rules! add_vertex {
607    ($graph:ident, $installer:ident, $config:ident, $pkg_manager:ident, $pkg:ident, $session:ident) => {
608        if let Some(pkg_manager) = &$config.$pkg_manager {
609            if let Some(installer) = pkg_manager.get("install") {
610                installer.$pkg.iter().for_each(|(name, x)| {
611                    $graph.add_vertex(Vertex::from(Box::new($installer {
612                        name: name.clone(),
613                        session: $session.clone(),
614                        ..$installer::from(x.clone())
615                    }) as Box<dyn Installer>));
616                });
617            }
618        }
619    };
620}
621
622#[macro_export]
623macro_rules! add_vertex_with_condition {
624    ($graph:ident, $installer:ident, $config:ident, $pkg_manager:ident, $pkg:ident, $session:ident) => {
625        if let Some(pkg_manager) = &$config.$pkg_manager {
626            if let Some(installer) = pkg_manager.get("install") {
627                match installer.$pkg.clone() {
628                    Some(pkg) => {
629                        pkg.iter().for_each(|(name, x)| {
630                            $graph.add_vertex(Vertex::from(Box::new($installer {
631                                name: name.clone(),
632                                session: $session.clone(),
633                                ..$installer::from(x.clone())
634                            })
635                                as Box<dyn Installer>));
636                        });
637                    }
638                    None => {}
639                }
640            }
641        }
642    };
643}
644
645#[macro_export]
646macro_rules! downcast_installer {
647    ($label: expr,$installer: ident, $installer_type: ident) => {
648        match $installer.provider() {
649            $label => Some(
650                $installer
651                    .as_any()
652                    .downcast_ref::<$installer_type>()
653                    .map(|x| x.clone())
654                    .unwrap(),
655            ),
656            _ => None,
657        }
658    };
659}
660
661#[macro_export]
662macro_rules! convert_generic_installer {
663    ($config: ident, $generic_install: ident, $installer: ident) => {
664        $config.$installer = Some(
665            [("install".into(), $generic_install.clone().into())]
666                .into_iter()
667                .chain($config.clone().$installer.unwrap_or_default().into_iter())
668                .collect(),
669        );
670    };
671}