Compare commits

..

No commits in common. "8a35904c7943a7fa687f50c0e31833a67db989c1" and "45f2bb64b04c6f98556487610d9cf53c8cc6c735" have entirely different histories.

11 changed files with 48 additions and 78 deletions

View File

@ -1,37 +0,0 @@
# https://woodpecker-ci.org/docs/usage/intro
pipeline:
build_and_test:
image: rust
commands:
- cargo test
- cargo build --release
gitea_on_release:
# http://plugins.drone.io/drone-plugins/drone-gitea-release/
image: plugins/gitea-release
files: target/release/reel-moby
secrets: [gitea_release_api_key, gitea_release_base_url]
when:
event: tag
tag: v*
github_on_release:
# http://plugins.drone.io/drone-plugins/drone-github-release/
image: plugins/github-release
files: target/release/reel-moby
secrets: [github_release_api_key]
when:
event: tag
tag: v*
notify_when_failure:
# http://plugins.drone.io/appleboy/drone-discord/
image: appleboy/drone-discord
secrets: [ discord_webhook_id, discord_webhook_token]
message: "build {{build.number}} or release failed. Fix me please."
when:
status: failure
# http://plugins.drone.io/drone-plugins/drone-github-release/

View File

@ -1,7 +1,7 @@
[package] [package]
name = "reel-moby" name = "reel-moby"
version = "0.11.0" version = "0.10.0"
edition = "2018" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -7,4 +7,4 @@ search for new docker tags and update them in your docker-compose file
Searches the current folder for a docker-compose.(yml|yaml) file and opens it when it found one. Then it is possible to select a image line. The program then shows the found repository and shows the latest tags. The tags can be scrolled and selected, which updates the opened file. Searches the current folder for a docker-compose.(yml|yaml) file and opens it when it found one. Then it is possible to select a image line. The program then shows the found repository and shows the latest tags. The tags can be scrolled and selected, which updates the opened file.
From that point save the file and pull the new image with `docker-compose up -d` or `docker-compse pull`. From that point save the file and pull the new image with `docker-compose up -d` or `docker-compse pull`.
![screenshot](./screenshot.png) [screenshot](./screenshot.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -15,7 +15,7 @@ pub struct Opt {
/// A custom path to a docker-compose file /// A custom path to a docker-compose file
#[structopt(short, long, parse(from_os_str))] #[structopt(short, long, parse(from_os_str))]
file: Option<PathBuf>, config: Option<PathBuf>,
/// Give a Repository identifier, e.g. library/nginx /// Give a Repository identifier, e.g. library/nginx
#[structopt(short, long, parse(from_str))] #[structopt(short, long, parse(from_str))]

View File

@ -2,16 +2,24 @@ use std::fmt;
use regex::Regex; use regex::Regex;
// use crate::common;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Error { pub enum Error {
// Conversion,
// Empty,
NoTagFound, NoTagFound,
// InvalidChar,
MisformedInput, MisformedInput,
} }
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::Conversion => write!(f, "Conversion error"),
// Error::Empty => write!(f, "Input is empty"),
Error::NoTagFound => write!(f, "Expected a tag"), Error::NoTagFound => write!(f, "Expected a tag"),
// Error::InvalidChar => write!(f, "Invalid character found"),
Error::MisformedInput => write!(f, "Unexpected input"), Error::MisformedInput => write!(f, "Unexpected input"),
} }
} }

View File

@ -7,6 +7,7 @@ use serde::Deserialize;
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
struct ImageDetails { struct ImageDetails {
architecture: String, architecture: String,
// os: String,
size: usize, size: usize,
} }
@ -24,30 +25,6 @@ pub struct Images {
last_updated: String, last_updated: String,
} }
impl fmt::Display for Images {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
//architecture infos
let mut arch = String::new();
for image in self.images.iter().take(1) {
arch.push_str(&format!("{}", image));
}
for image in self.images.iter().skip(1) {
arch.push_str(&format!(", {}", image));
}
let now = chrono::Utc::now();
let rfc3339 = DateTime::parse_from_rfc3339(&self.last_updated).unwrap();
let dif = now - rfc3339.with_timezone(&chrono::Utc);
write!(
f,
"{} vor {} [{}]",
self.tag_name,
format_time_nice(dif),
arch
)
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct Tags { pub struct Tags {
count: usize, count: usize,
@ -64,6 +41,7 @@ pub enum Error {
Converting(String), Converting(String),
/// invalid repos show a valid json with 0 tags /// invalid repos show a valid json with 0 tags
NoTagsFound, NoTagsFound,
NoNextPage,
} }
impl fmt::Display for Error { impl fmt::Display for Error {
@ -71,6 +49,7 @@ impl fmt::Display for Error {
match self { match self {
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::NoTagsFound => write!(f, "Given Repo has 0 tags. Is it valid?"), Error::NoTagsFound => write!(f, "Given Repo has 0 tags. Is it valid?"),
} }
} }
@ -119,17 +98,38 @@ impl Tags {
} }
/// returns tags of next page /// returns tags of next page
pub fn next_page(&self) -> Option<Self> { pub fn next_page(&self) -> Result<Self, Error> {
match &self.next_page { match &self.next_page {
Some(url) => match Self::with_url(url) { Some(url) => Self::with_url(url),
Ok(tags) => Some(tags), None => Err(Error::NoNextPage),
Err(_) => None,
},
None => None,
} }
} }
} }
impl fmt::Display for Images {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
//architecture infos
let mut arch = String::new();
for image in self.images.iter().take(1) {
arch.push_str(&format!("{}", image));
}
for image in self.images.iter().skip(1) {
arch.push_str(&format!(", {}", image));
}
let now = chrono::Utc::now();
let rfc3339 = DateTime::parse_from_rfc3339(&self.last_updated).unwrap();
let dif = now - rfc3339.with_timezone(&chrono::Utc);
write!(
f,
"{} vor {} [{}]",
self.tag_name,
format_time_nice(dif),
arch
)
}
}
/// converts a given duration to a readable string /// converts a given duration to a readable string
fn format_time_nice(time: chrono::Duration) -> String { fn format_time_nice(time: chrono::Duration) -> String {
if time.num_weeks() == 52 { if time.num_weeks() == 52 {

View File

@ -54,7 +54,7 @@ impl Ui {
state: State::SelectService, state: State::SelectService,
repo: repo_entry::RepoEntry::new(repo_id), repo: repo_entry::RepoEntry::new(repo_id),
tags: tag_list::TagList::with_status("Tags are empty"), tags: tag_list::TagList::with_status("Tags are empty"),
services: service_switcher::ServiceSwitcher::new(&opt.file).unwrap(), services: service_switcher::ServiceSwitcher::new(&opt.config).unwrap(),
info: info::Info::new("Select image of edit Repository"), info: info::Info::new("Select image of edit Repository"),
}; };
@ -122,7 +122,6 @@ impl Ui {
State::SelectTag => { State::SelectTag => {
let mut repo = ui.repo.get(); let mut repo = ui.repo.get();
let tag = match ui.tags.get_selected() { let tag = match ui.tags.get_selected() {
Err(tag_list::Error::NextPageSelected) => continue,
Err(e) => { Err(e) => {
ui.info.set_info(&format!("{}", e)); ui.info.set_info(&format!("{}", e));
continue; continue;

View File

@ -10,7 +10,7 @@ use termion::input::TermRead;
use crate::widget::service_switcher; use crate::widget::service_switcher;
pub fn create_ui(opt: &Opt) { pub fn create_ui(opt: &Opt) {
let service_result = service_switcher::ServiceSwitcher::new(&opt.file); let service_result = service_switcher::ServiceSwitcher::new(&opt.config);
match service_result { match service_result {
None => no_yaml::NoYaml::run(opt), None => no_yaml::NoYaml::run(opt),
Some(_) => default::Ui::run(opt), Some(_) => default::Ui::run(opt),

View File

@ -11,7 +11,7 @@ impl Info {
Self { Self {
info: String::from(info), info: String::from(info),
keys: String::from( keys: String::from(
"Tab Cycle widgets C-s Save C-r Reload C-q Quit ↑ ↓ Select tags or image line Return Select current selection", "Tab Cycle widgets C-s Save C-r Reload C-q Quit ↑ ↓ Select tags or image line",
), ),
} }
} }

View File

@ -68,8 +68,8 @@ impl TagList {
.collect(); .collect();
match tags.next_page() { match tags.next_page() {
None => (), Err(_) => (),
Some(new_tags) => { Ok(new_tags) => {
lines.push(Line::NextPage(String::from("load more tags"))); lines.push(Line::NextPage(String::from("load more tags")));
tags = new_tags; tags = new_tags;
} }
@ -149,8 +149,8 @@ impl TagList {
fn load_next_page(&mut self) { fn load_next_page(&mut self) {
match &self.tags { match &self.tags {
Some(tags) => match tags.next_page() { Some(tags) => match tags.next_page() {
None => (), Err(_) => (),
Some(new_tags) => { Ok(new_tags) => {
//load new tags object //load new tags object
self.tags = Some(new_tags); self.tags = Some(new_tags);