-
-
Save mgoellnitz/c7c5effb4045d5484bf649eca674a374 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# | |
# Copyright 2017-2021 Martin Goellnitz | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
# defaults | |
API="https://api.bitbucket.org/2.0" | |
PRIVATE=true | |
BITBUCKETUSER=$BITBUCKET_USER | |
if [ ! -z $BITBUCKETUSER ] ; then | |
TEAM=`echo $BITBUCKETUSER|cut -d ':' -f 1` | |
fi | |
if [ $(which jq|wc -l) = 0 ] ; then | |
echo "To use this tool, jq must be installed." | |
exit | |
fi | |
if [ "$#" == "0" ]; then | |
echo "Bitbucket User Snippet Command Line Tool 'bucketsnip.sh'" | |
echo "" | |
echo "$0 [-u user] [-t team] [-s snippet title] [-l] [-p] [filenames...]" | |
echo "" | |
echo "If 'filename' points to an existing file, it is uploaded to Bitbucket with an optional title." | |
echo "If 'filename' describes a filename present in the user's snippets, it is downloaded." | |
echo "If 'filename' is not present, the contents of the current directory are used as file-set." | |
echo "" | |
echo " -l list snippets" | |
echo "" | |
echo " -u user name - optionally with app password appended after ':' - default \$BITBUCKET_USER" | |
echo "" | |
echo " -t team to use instead of users snippets" | |
echo "" | |
echo " -s snippet title - defaults to filename for single file snippets or to "$(basename `pwd`) | |
echo "" | |
echo " -p make snippet public" | |
echo "" | |
exit 1 | |
fi | |
PSTART=`echo $1|sed -e 's/^\(.\).*/\1/g'` | |
while [ "$PSTART" = "-" ] ; do | |
if [ "$1" = "-u" ] ; then | |
shift | |
BITBUCKETUSER="$1" | |
TEAM=`echo $BITBUCKETUSER|cut -d ':' -f 1` | |
fi | |
if [ "$1" = "-t" ] ; then | |
shift | |
TEAM="$1" | |
fi | |
if [ "$1" = "-s" ] ; then | |
shift | |
SNIPPET="$1" | |
fi | |
if [ "$1" = "-p" ] ; then | |
PRIVATE=false | |
fi | |
if [ "$1" = "-l" ] ; then | |
LISTING=true | |
fi | |
shift | |
PSTART=`echo $1|sed -e 's/^\(.\).*/\1/g'` | |
done | |
if [ -z "$BITBUCKETUSER" ] ; then | |
echo "Cannot work without the context of a bitbucket user name. Sorry..." | |
exit 1 | |
fi | |
if [ ! -z "$LISTING" ] ; then | |
echo "Listing snippets of $TEAM" | |
SNIPPETS=$(curl -k --basic -u $BITBUCKETUSER ${API}/snippets/${TEAM} 2> /dev/null|jq '.values[]|.id'|sed -e s/^\"//g|sed -e s/\"$//g) | |
for SNID in $SNIPPETS ; do | |
# echo $SNID | |
ITEM=$(curl -k --basic -u $BITBUCKETUSER ${API}/snippets/${TEAM}/${SNID} 2> /dev/null) | |
TITLE=$(echo $ITEM|jq '.title'|sed -e s/^\"//g|sed -e s/\"$//g) | |
UPDATE=$(echo $ITEM|jq '.updated_on'|sed -e s/^\"//g|sed -e s/\"$//g|sed -e 's/\..*//g'|sed -e 's/T/ /g') | |
PRIVATE=$(echo $ITEM|jq '.is_private'|sed -e s/^\"//g|sed -e s/\"$//g|sed -e s/true/private/g|sed -e s/false/public/g) | |
FILES=$(echo $ITEM|jq '(.files|keys)'|sed -e s/^\"//g|sed -e s/\"$//g) | |
echo -n "$PRIVATE $TITLE ($UPDATE) " | |
echo $FILES | |
# LISTING=$(curl -k --basic -u $BITBUCKETUSER ${API}/snippets/${TEAM}/${SNID} 2> /dev/null |jq '.title,.updated_on,.scm,.is_private,(.files|keys)'|sed -e s/^\"//g|sed -e s/\"$//g) | |
# echo $LISTING | |
done | |
else | |
FILES=$* | |
if [ -z "$FILES" ] ; then | |
FILES=$(ls) | |
fi | |
if [ -z "$SNIPPET" ] ; then | |
if [ "$#" == "1" ] ; then | |
SNIPPET=$(basename $1) | |
echo "Checking for present single file snippet" | |
SNIPPETS=$(curl -k --basic -u $BITBUCKETUSER ${API}/snippets/${TEAM} 2> /dev/null|jq '.values[]|.id'|sed -e s/^\"//g|sed -e s/\"$//g) | |
for SNID in $SNIPPETS ; do | |
JSON=$(curl -k --basic -u $BITBUCKETUSER ${API}/snippets/${TEAM}/${SNID} 2> /dev/null) | |
if [ $(echo $JSON|jq ".files[].links.self.href"|wc -l) == 1 ] ; then | |
LISTING=$(echo $JSON|jq ".files[\"$SNIPPET\"].links.self.href"|sed -e s/^\"//g|sed -e s/\"$//g) | |
if [ ! -z "$LISTING" ] ; then | |
if [ "$LISTING" != "null" ] ; then | |
SNIPPET=$(curl -k --basic -u $BITBUCKETUSER ${API}/snippets/${TEAM} 2> /dev/null|jq ".values[]|select(.id==\"${SNID}\")|.title"|sed -e s/^\"//g|sed -e s/\"$//g) | |
echo "Discovered $SNIPPET for snippet containing solely $1" | |
fi | |
fi | |
fi | |
done | |
else | |
SNIPPET=$(basename `pwd`) | |
fi | |
fi | |
SNID=$(curl -k --basic -u $BITBUCKETUSER ${API}/snippets/${TEAM} 2> /dev/null|jq ".values[]|select(.title==\"${SNIPPET}\")|.id"|sed -e s/^\"//g|sed -e s/\"$//g) | |
if [ -z "$SNID" ] ; then | |
echo -n "Creating" | |
test "true" == "$PRIVATE" && echo -n " private" | |
echo " snippet $SNIPPET in $TEAM" | |
DATA="" | |
for FILEPATH in $FILES ; do | |
if [ -f $FILEPATH ] ; then | |
FILE=$(basename $FILEPATH) | |
# echo $FILE $FILEPATH | |
DATA="$DATA -F file=@$FILEPATH" | |
fi | |
done | |
curl -k -X POST --basic -F title="$SNIPPET" -F is_private="$PRIVATE" $DATA -u $BITBUCKETUSER ${API}/snippets/${TEAM} 2> /dev/null | jq .title | |
else | |
echo "Updating snippet $SNIPPET in $TEAM" | |
DATA="" | |
DOWNLOADS="" | |
for FILEPATH in $FILES ; do | |
if [ -f $FILEPATH ] ; then | |
DATA="$DATA -F file=@$FILEPATH" | |
else | |
DOWNLOADS="$DOWNLOADS $FILEPATH" | |
fi | |
done | |
if [ ! -z "$DATA" ] ; then | |
curl -k -X PUT --basic -F title="$SNIPPET" -F is_private="$PRIVATE" $DATA -u $BITBUCKETUSER ${API}/snippets/${TEAM}/${SNID} 2> /dev/null | jq .title | |
else | |
echo "Nothing to upload" | |
fi | |
echo "Downloading missing files... $DOWNLOADS" | |
JSON=$(curl -k --basic -u $BITBUCKETUSER ${API}/snippets/${TEAM}/${SNID}?pagelen=100 2> /dev/null |jq '.') | |
LISTING=$(echo $JSON |jq '(.files|keys)') | |
LISTING=$(echo $LISTING|sed -e 's/\",.\"/ /g' -e 's/.\ \"//g' -e 's/\"\ .//g') | |
# echo $LISTING | |
if [ $# == 0 ] ; then | |
echo "No additional arguments" | |
for ELEMENT in $LISTING ; do | |
if [ ! -f "$ELEMENT" ] ; then | |
echo "Adding $ELEMENT to download list" | |
DOWNLOADS+=" $ELEMENT" | |
fi | |
done | |
fi | |
for ELEMENT in $LISTING ; do | |
for FILE in $DOWNLOADS ; do | |
if [ "$ELEMENT" == "$FILE" ] ; then | |
echo "Downloading $FILE" | |
URL=$(echo $JSON | jq '.|.files["'$FILE'"].links.self.href'|sed -e 's/\"//g') | |
curl -k --basic -u $BITBUCKETUSER ${URL} 2> /dev/null > $FILE | |
fi | |
done | |
done | |
fi | |
fi |
@SidIcarus Thanks!
After staring at documentation for several hours and getting nowhere I found this post and your for loop for multipart file uploads helped me. So thank you for that. I wanted to provide feedback that, by default the pagelen is 30, which in my case I have 57, so I'm not guaranteed to have what I want in the list, I think others that come here may also benefit.
`get_snippet_by_id_by_title(){
title="$1"
bit_bucket_creds="$2"
url="https://api.bitbucket.org/2.0/snippets/{slug}?q=role='member'&pagelen=300"
curl -s -L $url -X GET
--header "authorization: Basic ${bit_bucket_creds}" |
jq -r --arg title "$title" '. |
.values |
.[] |
select(.title == $title) |
.id
'
}
bit_bucket_creds=$(cat ~/.bit_bucket_hash)
title='TITLE OF SNIPPET'
get_snippet_by_id_by_title "$title" "$bit_bucket_creds"`
I keep modifying it. I realized if you don't have credentials passed in you still qualify for public snippets and since I was getting a return, I didn't notice. I'll check for errors later.
https://developer.atlassian.com/bitbucket/api/2/reference/meta/filtering
https://developer.atlassian.com/bitbucket/api/2/reference/resource/snippets/%7Bworkspace%7D#get
Hi, thanks for the note. I considered 57 files worth a "real repository". I now try to use a default of 100 instead of your 300.
Yes, access to public snippets is intentional in my snippet/gist tools. In fact, I maintain them using the tools itself. (gitlab sadly has no place for snippets not relating to any project)
Line 162 should be updated to be
DOWNLOADS+=" $ELEMENT"