]> git.proxmox.com Git - rustc.git/blob - extra/git2/examples/tag.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / extra / git2 / examples / tag.rs
1 /*
2 * libgit2 "tag" example - shows how to list, create and delete tags
3 *
4 * Written by the libgit2 contributors
5 *
6 * To the extent possible under law, the author(s) have dedicated all copyright
7 * and related and neighboring rights to this software to the public domain
8 * worldwide. This software is distributed without any warranty.
9 *
10 * You should have received a copy of the CC0 Public Domain Dedication along
11 * with this software. If not, see
12 * <http://creativecommons.org/publicdomain/zero/1.0/>.
13 */
14
15 #![deny(warnings)]
16
17 use git2::{Commit, Error, Repository, Tag};
18 use std::str;
19 use structopt::StructOpt;
20
21 #[derive(StructOpt)]
22 struct Args {
23 arg_tagname: Option<String>,
24 arg_object: Option<String>,
25 arg_pattern: Option<String>,
26 #[structopt(name = "n", short)]
27 /// specify number of lines from the annotation to print
28 flag_n: Option<u32>,
29 #[structopt(name = "force", short, long)]
30 /// replace an existing tag with the given name
31 flag_force: bool,
32 #[structopt(name = "list", short, long)]
33 /// list tags with names matching the pattern given
34 flag_list: bool,
35 #[structopt(name = "tag", short, long = "delete")]
36 /// delete the tag specified
37 flag_delete: Option<String>,
38 #[structopt(name = "msg", short, long = "message")]
39 /// message for a new tag
40 flag_message: Option<String>,
41 }
42
43 fn run(args: &Args) -> Result<(), Error> {
44 let repo = Repository::open(".")?;
45
46 if let Some(ref name) = args.arg_tagname {
47 let target = args.arg_object.as_ref().map(|s| &s[..]).unwrap_or("HEAD");
48 let obj = repo.revparse_single(target)?;
49
50 if let Some(ref message) = args.flag_message {
51 let sig = repo.signature()?;
52 repo.tag(name, &obj, &sig, message, args.flag_force)?;
53 } else {
54 repo.tag_lightweight(name, &obj, args.flag_force)?;
55 }
56 } else if let Some(ref name) = args.flag_delete {
57 let obj = repo.revparse_single(name)?;
58 let id = obj.short_id()?;
59 repo.tag_delete(name)?;
60 println!(
61 "Deleted tag '{}' (was {})",
62 name,
63 str::from_utf8(&*id).unwrap()
64 );
65 } else if args.flag_list {
66 let pattern = args.arg_pattern.as_ref().map(|s| &s[..]).unwrap_or("*");
67 for name in repo.tag_names(Some(pattern))?.iter() {
68 let name = name.unwrap();
69 let obj = repo.revparse_single(name)?;
70
71 if let Some(tag) = obj.as_tag() {
72 print_tag(tag, args);
73 } else if let Some(commit) = obj.as_commit() {
74 print_commit(commit, name, args);
75 } else {
76 print_name(name);
77 }
78 }
79 }
80 Ok(())
81 }
82
83 fn print_tag(tag: &Tag, args: &Args) {
84 print!("{:<16}", tag.name().unwrap());
85 if args.flag_n.is_some() {
86 print_list_lines(tag.message(), args);
87 } else {
88 println!();
89 }
90 }
91
92 fn print_commit(commit: &Commit, name: &str, args: &Args) {
93 print!("{:<16}", name);
94 if args.flag_n.is_some() {
95 print_list_lines(commit.message(), args);
96 } else {
97 println!();
98 }
99 }
100
101 fn print_name(name: &str) {
102 println!("{}", name);
103 }
104
105 fn print_list_lines(message: Option<&str>, args: &Args) {
106 let message = match message {
107 Some(s) => s,
108 None => return,
109 };
110 let mut lines = message.lines().filter(|l| !l.trim().is_empty());
111 if let Some(first) = lines.next() {
112 print!("{}", first);
113 }
114 println!();
115
116 for line in lines.take(args.flag_n.unwrap_or(0) as usize) {
117 print!(" {}", line);
118 }
119 }
120
121 fn main() {
122 let args = Args::from_args();
123 match run(&args) {
124 Ok(()) => {}
125 Err(e) => println!("error: {}", e),
126 }
127 }