Compare commits
No commits in common. "0a844c42ee7c6953d28cbf9442eb5f14609ea661" and "7828d7c7036c804cb92d485d8dfe00dc1287b71e" have entirely different histories.
0a844c42ee
...
7828d7c703
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -541,7 +541,6 @@ name = "query-docker-tags"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"lazy_static",
|
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -14,7 +14,6 @@ chrono = "0.4.19"
|
|||||||
tui = "0.16"
|
tui = "0.16"
|
||||||
termion = "1.5"
|
termion = "1.5"
|
||||||
regex = "1.5.4"
|
regex = "1.5.4"
|
||||||
lazy_static = "1.4.0"
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = "yes"
|
lto = "yes"
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
mod repo;
|
|
||||||
mod tags;
|
mod tags;
|
||||||
mod ui;
|
mod ui;
|
||||||
mod widget;
|
mod widget;
|
||||||
|
164
src/repo.rs
164
src/repo.rs
@ -1,164 +0,0 @@
|
|||||||
use std::fmt;
|
|
||||||
|
|
||||||
use regex::Regex;
|
|
||||||
|
|
||||||
// use crate::common;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum Error {
|
|
||||||
// Conversion,
|
|
||||||
// Empty,
|
|
||||||
NoTagFound,
|
|
||||||
// InvalidChar,
|
|
||||||
MisformedInput,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
// Error::Conversion => write!(f, "Conversion error"),
|
|
||||||
// Error::Empty => write!(f, "Input is empty"),
|
|
||||||
Error::NoTagFound => write!(f, "Expected a tag"),
|
|
||||||
// Error::InvalidChar => write!(f, "Invalid character found"),
|
|
||||||
Error::MisformedInput => write!(f, "Unexpected input"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum Repo {
|
|
||||||
WithServer(String, String, String),
|
|
||||||
WithOrga(String, String),
|
|
||||||
Project(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// check if yaml line matches and returns the split of repo string and rest
|
|
||||||
pub fn match_yaml_image(input: &str) -> Result<(&str, &str), Error> {
|
|
||||||
lazy_static::lazy_static! {
|
|
||||||
static ref REGEX: Regex = Regex::new(r"^( +image *: *)([a-z0-9\./:]+)").unwrap();
|
|
||||||
}
|
|
||||||
let caps = match REGEX.captures(input) {
|
|
||||||
Some(caps) => caps,
|
|
||||||
None => return Err(Error::NoTagFound),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((caps.get(1).unwrap().as_str(), caps.get(2).unwrap().as_str()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn split_tag_from_repo(input: &str) -> Result<(&str, &str), Error> {
|
|
||||||
lazy_static::lazy_static! {
|
|
||||||
static ref REGEX: Regex = Regex::new(r"^([a-z0-9\./[^:]]*):?([a-z0-9._\-]*)").unwrap();
|
|
||||||
}
|
|
||||||
let (front, back) = match REGEX.captures(input) {
|
|
||||||
None => return Err(Error::MisformedInput),
|
|
||||||
Some(caps) => {
|
|
||||||
let front = match caps.get(1) {
|
|
||||||
None => return Err(Error::MisformedInput),
|
|
||||||
Some(cap) => cap.as_str(),
|
|
||||||
};
|
|
||||||
let back = match caps.get(2) {
|
|
||||||
None => "",
|
|
||||||
Some(cap) => cap.as_str(),
|
|
||||||
};
|
|
||||||
(front, back)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((front, back))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn split_repo_without_tag(repo: &str) -> Result<Repo, Error> {
|
|
||||||
let repo = repo.trim();
|
|
||||||
let split_repo: Vec<&str> = repo.split("/").collect();
|
|
||||||
match split_repo.len() {
|
|
||||||
1 => {
|
|
||||||
let regex = regex::Regex::new(r"[a-z0-9]+").unwrap();
|
|
||||||
match regex.is_match(repo) {
|
|
||||||
false => Err(Error::MisformedInput),
|
|
||||||
true => Ok(Repo::Project(split_repo[0].into())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2 => {
|
|
||||||
let regex = regex::Regex::new(r"[a-z0-9]+/[a-z0-9]+").unwrap();
|
|
||||||
match regex.is_match(repo) {
|
|
||||||
false => Err(Error::MisformedInput),
|
|
||||||
true => Ok(Repo::WithOrga(split_repo[0].into(), split_repo[1].into())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
3 => {
|
|
||||||
let regex = regex::Regex::new(r"[a-z0-9\.]+/[a-z0-9]+/[a-z0-9]+").unwrap();
|
|
||||||
match regex.is_match(repo) {
|
|
||||||
false => Err(Error::MisformedInput),
|
|
||||||
true => Ok(Repo::WithServer(
|
|
||||||
split_repo[0].into(),
|
|
||||||
split_repo[1].into(),
|
|
||||||
split_repo[2].into(),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => Err(Error::MisformedInput),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::repo;
|
|
||||||
use crate::repo::{Error, Repo};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_split_repo_without_tag() {
|
|
||||||
use crate::repo::split_repo_without_tag as test_fn;
|
|
||||||
assert_eq!(test_fn(""), Err(Error::MisformedInput));
|
|
||||||
assert_eq!(test_fn("NGINX"), Err(Error::MisformedInput));
|
|
||||||
assert_eq!(test_fn("nginx"), Ok(Repo::Project("nginx".into())));
|
|
||||||
assert_eq!(
|
|
||||||
test_fn("library/nginx"),
|
|
||||||
Ok(Repo::WithOrga("library".into(), "nginx".into()))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
test_fn("ghcr.io/library/nginx"),
|
|
||||||
Ok(Repo::WithServer(
|
|
||||||
"ghcr.io".into(),
|
|
||||||
"library".into(),
|
|
||||||
"nginx".into(),
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_match_yaml_image() {
|
|
||||||
use crate::repo::match_yaml_image as test_fn;
|
|
||||||
assert_eq!(test_fn(""), None);
|
|
||||||
assert_eq!(test_fn("version: '2'"), None);
|
|
||||||
assert_eq!(test_fn("image: "), None);
|
|
||||||
assert_eq!(test_fn(" image: "), None);
|
|
||||||
assert_eq!(test_fn(" image: nginx"), Some((" image: ", "nginx")));
|
|
||||||
assert_eq!(
|
|
||||||
test_fn(" image: library/nginx"),
|
|
||||||
Some((" image: ", "library/nginx"))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
test_fn(" image: ghcr.io/library/nginx"),
|
|
||||||
Some((" image: ", "ghcr.io/library/nginx"))
|
|
||||||
);
|
|
||||||
assert_eq!(test_fn("# image: nginx"), None);
|
|
||||||
assert_eq!(
|
|
||||||
test_fn(" image: nginx #comment"),
|
|
||||||
Some((" image: ", "nginx"))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_split_tag_from_repo() {
|
|
||||||
use crate::repo::split_tag_from_repo as test_fn;
|
|
||||||
assert_eq!(test_fn("nginx"), Ok(("nginx", "")));
|
|
||||||
assert_eq!(test_fn("library/nginx"), Ok(("library/nginx", "")));
|
|
||||||
assert_eq!(
|
|
||||||
test_fn("ghcr.io/library/nginx"),
|
|
||||||
Ok(("ghcr.io/library/nginx", ""))
|
|
||||||
);
|
|
||||||
assert_eq!(test_fn("nginx:"), Ok(("nginx", "")));
|
|
||||||
assert_eq!(test_fn("nginx:1"), Ok(("nginx", "1")));
|
|
||||||
assert_eq!(test_fn("nginx:latest"), Ok(("nginx", "latest")));
|
|
||||||
}
|
|
||||||
}
|
|
53
src/tags.rs
53
src/tags.rs
@ -1,6 +1,5 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::repo;
|
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@ -35,8 +34,10 @@ pub struct Tags {
|
|||||||
pub results: Vec<Images>,
|
pub results: Vec<Images>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
/// repo string contains an illegal character
|
||||||
|
InvalidCharacter(char),
|
||||||
/// couldn't fetch json with reqwest
|
/// couldn't fetch json with reqwest
|
||||||
Fetching(String),
|
Fetching(String),
|
||||||
/// a serde error
|
/// a serde error
|
||||||
@ -50,6 +51,7 @@ pub enum Error {
|
|||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
Error::InvalidCharacter(c) => write!(f, "Invalid Character: {}", c),
|
||||||
Error::Fetching(s) => write!(f, "Fetching error: {}", s),
|
Error::Fetching(s) => write!(f, "Fetching error: {}", s),
|
||||||
Error::Converting(s) => write!(f, "Converting error: {}", s),
|
Error::Converting(s) => write!(f, "Converting error: {}", s),
|
||||||
Error::NoNextPage => write!(f, "No next page available"),
|
Error::NoNextPage => write!(f, "No next page available"),
|
||||||
@ -88,17 +90,18 @@ impl Tags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// checks the repo name and may add a prefix for official images
|
/// checks the repo name and may add a prefix for official images
|
||||||
pub fn check_repo(name: &str) -> Result<String, Error> {
|
pub fn check_repo(mut name: String) -> Result<String, Error> {
|
||||||
let repo = match repo::split_tag_from_repo(name) {
|
//check for right set of characters
|
||||||
Err(e) => return Err(Error::Converting(format!("{}", e))),
|
if name.bytes().any(|c| !c.is_ascii()) {
|
||||||
Ok((name, _)) => name,
|
return Err(Error::InvalidCharacter('a'));
|
||||||
};
|
|
||||||
|
|
||||||
match repo::split_repo_without_tag(name) {
|
|
||||||
Ok(repo::Repo::Project(s)) => Ok(format!("library/{}", s)),
|
|
||||||
Ok(_) => Ok(repo.to_string()),
|
|
||||||
Err(e) => Err(Error::Converting(format!("{}", e))),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check if need to inject "library" of given repo
|
||||||
|
let regex = regex::Regex::new(r".*/.*").unwrap();
|
||||||
|
if !regex.is_match(&name) {
|
||||||
|
name.insert_str(0, "library/");
|
||||||
|
}
|
||||||
|
Ok(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns tags of next page
|
/// returns tags of next page
|
||||||
@ -164,14 +167,26 @@ fn format_time_nice(time: chrono::Duration) -> String {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::tags::{Error, Tags};
|
use crate::tags;
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check_repo() {
|
fn test_check_repo() {
|
||||||
assert_eq!(Tags::check_repo("nginx").unwrap(), "library/nginx");
|
let check_eq = |s, s2| {
|
||||||
assert_eq!(Tags::check_repo("library/nginx").unwrap(), "library/nginx");
|
assert_eq!(&tags::Tags::check_repo(String::from(s)).unwrap(), s2);
|
||||||
assert_eq!(
|
};
|
||||||
Tags::check_repo("rocketchat/rocket.chat").unwrap(),
|
let check_neq = |s, s2| {
|
||||||
"rocketchat/rocket.chat"
|
assert_ne!(&tags::Tags::check_repo(String::from(s)).unwrap(), s2);
|
||||||
);
|
};
|
||||||
|
let check_err = |s: &str| {
|
||||||
|
assert_eq!(tags::Tags::check_repo(String::from(s)).is_err(), true);
|
||||||
|
};
|
||||||
|
|
||||||
|
check_eq("nginx", "library/nginx");
|
||||||
|
check_neq("nginx", "nginx");
|
||||||
|
check_eq("rocketchat/rocket.chat", "rocketchat/rocket.chat");
|
||||||
|
check_eq("mysql", "library/mysql");
|
||||||
|
check_neq("mysql", "mysql");
|
||||||
|
check_err("nginxä");
|
||||||
|
check_err("nginx²");
|
||||||
|
check_eq("selim13/automysqlbackup", "selim13/automysqlbackup");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
src/ui.rs
14
src/ui.rs
@ -13,11 +13,11 @@ use crate::widget::repo_entry;
|
|||||||
use crate::widget::service_switcher;
|
use crate::widget::service_switcher;
|
||||||
use crate::widget::tag_list;
|
use crate::widget::tag_list;
|
||||||
|
|
||||||
pub struct Ui<'a> {
|
pub struct Ui {
|
||||||
state: State,
|
state: State,
|
||||||
repo: crate::widget::repo_entry::RepoEntry,
|
repo: crate::widget::repo_entry::RepoEntry,
|
||||||
tags: crate::widget::tag_list::TagList,
|
tags: crate::widget::tag_list::TagList,
|
||||||
services: crate::widget::service_switcher::ServiceSwitcher<'a>,
|
services: crate::widget::service_switcher::ServiceSwitcher,
|
||||||
info: crate::widget::info::Info,
|
info: crate::widget::info::Info,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ impl std::iter::Iterator for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ui<'_> {
|
impl Ui {
|
||||||
pub fn run(repo_id: &str) {
|
pub fn run(repo_id: &str) {
|
||||||
let mut ui = Ui {
|
let mut ui = Ui {
|
||||||
state: State::SelectService,
|
state: State::SelectService,
|
||||||
@ -151,14 +151,14 @@ impl Ui<'_> {
|
|||||||
match ui.services.extract_repo() {
|
match ui.services.extract_repo() {
|
||||||
Err(e) => ui.info.set_info(&format!("{}", e)),
|
Err(e) => ui.info.set_info(&format!("{}", e)),
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
let repo = match crate::tags::Tags::check_repo(&s) {
|
let repo = match crate::tags::Tags::check_repo(s) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
ui.info.set_info(&format!("{}", e));
|
ui.info.set_info(&format!("{}", e));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
};
|
};
|
||||||
ui.repo.set(repo.to_string());
|
ui.repo.set(repo);
|
||||||
ui.tags = tag_list::TagList::with_repo(ui.repo.get());
|
ui.tags = tag_list::TagList::with_repo(ui.repo.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,14 +171,14 @@ impl Ui<'_> {
|
|||||||
match ui.services.extract_repo() {
|
match ui.services.extract_repo() {
|
||||||
Err(e) => ui.info.set_info(&format!("{}", e)),
|
Err(e) => ui.info.set_info(&format!("{}", e)),
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
let repo = match crate::tags::Tags::check_repo(&s) {
|
let repo = match crate::tags::Tags::check_repo(s) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
ui.info.set_info(&format!("{}", e));
|
ui.info.set_info(&format!("{}", e));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
};
|
};
|
||||||
ui.repo.set(repo.to_string());
|
ui.repo.set(repo);
|
||||||
ui.tags = tag_list::TagList::with_repo(ui.repo.get());
|
ui.tags = tag_list::TagList::with_repo(ui.repo.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ use std::io::BufRead;
|
|||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
|
use regex::Regex;
|
||||||
use tui::style::{Color, Style};
|
use tui::style::{Color, Style};
|
||||||
use tui::widgets::{Block, Borders, List, ListState};
|
use tui::widgets::{Block, Borders, List, ListState};
|
||||||
|
|
||||||
use crate::repo;
|
|
||||||
use crate::ui::State;
|
use crate::ui::State;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -25,42 +25,30 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ServiceSwitcher<'a> {
|
pub struct ServiceSwitcher {
|
||||||
list: Vec<String>,
|
list: Vec<String>,
|
||||||
state: ListState,
|
state: ListState,
|
||||||
|
regex: Regex,
|
||||||
changed: bool,
|
changed: bool,
|
||||||
opened_file: &'a str,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceSwitcher<'_> {
|
impl ServiceSwitcher {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let file_list = vec!["docker-compose.yml", "docker-compose.yaml"];
|
let list = match File::open("docker-compose.yml") {
|
||||||
|
Err(e) => vec![format!("No docker-compose.yml found: {}", e)],
|
||||||
|
Ok(file) => {
|
||||||
|
let buf = BufReader::new(file);
|
||||||
|
buf.lines()
|
||||||
|
.map(|l| l.expect("Could not parse line"))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for file in file_list {
|
|
||||||
let list = match File::open(file) {
|
|
||||||
Err(_) => continue,
|
|
||||||
Ok(file) => {
|
|
||||||
let buf = BufReader::new(file);
|
|
||||||
buf.lines()
|
|
||||||
.map(|l| l.expect("Could not parse line"))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return Self {
|
|
||||||
list,
|
|
||||||
state: ListState::default(),
|
|
||||||
changed: false,
|
|
||||||
opened_file: file,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//could not find docker-compose file
|
|
||||||
Self {
|
Self {
|
||||||
list: vec![format!("No docker-compose file found")],
|
list,
|
||||||
state: ListState::default(),
|
state: ListState::default(),
|
||||||
|
regex: Regex::new(r"( *image *): *([^:]*):?([^:]?) *").unwrap(),
|
||||||
changed: false,
|
changed: false,
|
||||||
opened_file: "No file",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,8 +60,8 @@ impl ServiceSwitcher<'_> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let title = match &self.changed {
|
let title = match &self.changed {
|
||||||
true => format!("File: *{}*", self.opened_file),
|
true => "File: *docker-compose.yml*",
|
||||||
false => format!("File: {}", self.opened_file),
|
false => "File: docker-compose.yml",
|
||||||
};
|
};
|
||||||
|
|
||||||
let items: Vec<tui::widgets::ListItem> = self
|
let items: Vec<tui::widgets::ListItem> = self
|
||||||
@ -115,7 +103,7 @@ impl ServiceSwitcher<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check if line matches
|
//check if line matches
|
||||||
if repo::match_yaml_image(&self.list[i]).is_ok() {
|
if self.regex.is_match(&self.list[i]) {
|
||||||
self.state.select(Some(i));
|
self.state.select(Some(i));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -147,7 +135,7 @@ impl ServiceSwitcher<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check if line matches
|
//check if line matches
|
||||||
if repo::match_yaml_image(&self.list[i]).is_ok() {
|
if self.regex.is_match(&self.list[i]) {
|
||||||
self.state.select(Some(i));
|
self.state.select(Some(i));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -164,10 +152,14 @@ impl ServiceSwitcher<'_> {
|
|||||||
pub fn extract_repo(&self) -> Result<String, Error> {
|
pub fn extract_repo(&self) -> Result<String, Error> {
|
||||||
match self.state.selected() {
|
match self.state.selected() {
|
||||||
None => return Err(Error::NoneSelected),
|
None => return Err(Error::NoneSelected),
|
||||||
Some(i) => match repo::match_yaml_image(&self.list[i]) {
|
Some(i) => {
|
||||||
Err(_) => return Err(Error::Parsing(String::from("Nothing found"))),
|
let caps = match self.regex.captures(&self.list[i]) {
|
||||||
Ok((_, repo)) => return Ok(repo.to_string()),
|
None => return Err(Error::Parsing(String::from("Nothing found"))),
|
||||||
},
|
Some(cap) => cap,
|
||||||
|
};
|
||||||
|
let result: String = caps.get(2).unwrap().as_str().to_string();
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,17 +167,24 @@ impl ServiceSwitcher<'_> {
|
|||||||
pub fn change_current_line(&mut self, repo_with_tag: String) {
|
pub fn change_current_line(&mut self, repo_with_tag: String) {
|
||||||
match self.state.selected() {
|
match self.state.selected() {
|
||||||
None => (),
|
None => (),
|
||||||
Some(i) => match repo::match_yaml_image(&self.list[i]) {
|
Some(i) => {
|
||||||
Err(_) => return,
|
let caps = match self.regex.captures(&self.list[i]) {
|
||||||
Ok((front, _)) => self.list[i] = format!("{}{}", front, repo_with_tag),
|
None => return,
|
||||||
},
|
Some(cap) => cap,
|
||||||
|
};
|
||||||
|
let mut line = caps.get(1).unwrap().as_str().to_string();
|
||||||
|
line.push_str(": ");
|
||||||
|
line.push_str(&repo_with_tag);
|
||||||
|
self.list[i] = line;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.changed = true;
|
self.changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// save the currently opened file
|
/// save the currently opened file
|
||||||
pub fn save(&mut self) -> Result<(), std::io::Error> {
|
pub fn save(&mut self) -> Result<(), std::io::Error> {
|
||||||
let mut file = File::create(self.opened_file)?;
|
let name = "docker-compose.yml";
|
||||||
|
let mut file = File::create(name)?;
|
||||||
for line in &self.list {
|
for line in &self.list {
|
||||||
file.write_all(line.as_bytes())?;
|
file.write_all(line.as_bytes())?;
|
||||||
file.write_all("\n".as_bytes())?;
|
file.write_all("\n".as_bytes())?;
|
||||||
|
Loading…
Reference in New Issue
Block a user