aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/usr/bin/.drive-find-gd
blob: 040bac91e7fa204f8c4f235b46b689626396a020 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/bin/bash
###################################################################################################
# .drive-find-gd
###################################################################################################
# Copyright 2017-2023 Jean-Christophe Manciot <jcmanciot@sdxlive.com>
#
# Licensed under a GPLv3 License.
# You may not use this file except in compliance with the License. You may obtain a copy of the 
# License at:
#
#    https://www.gnu.org/licenses/gpl-3.0.md
#
# The licensor cannot revoke these freedoms as long as you follow the license terms.
#
# Attribution — You must give appropriate credit, provide a link to the license, and indicate if 
#               changes were made. You may do so in any reasonable manner, but not in any way that 
#               suggests the licensor endorses you or your use.
###################################################################################################

###################################################################################################
#
# Finding and changing directory to local root Google Drive folder.
#
###################################################################################################
#
# Requirements:
# ------------
#
# - We assume that:
#       + drive-google is already installed with all drive-* scripts located in /usr/bin.
#       + grep & sed packages are already installed.
#
# - This command must be called from within your local Google Drive folder(s).
#
###################################################################################################
#
# Parameters:
# ----------
#
# none
#
###################################################################################################
#
# Return strings:
# --------------
#
# - "<.gd root folder>":        we have found the local root Google Drive folder.
# - "No drive context found":   we have not found any drive context.
#
###################################################################################################
#
# Return codes:
# ------------
#
# - 0:  we have found the local root Google Drive folder.
# - 7:  we have found the local root Google Drive folder, but we are not located beneath it.
# - 8:  we have not found any drive context below and above local folder:
#       + either drive has not been initialized properly (at least one hop away from '/')
#       + or we are not located below the <google_drive_folder> top level branch
#
###################################################################################################
#
# Notes:
# -----
#
# - We do support **symlinks**.
#
# - We **don't support** .gd root folder located at the root of the local partition: '/.gd'
#       /                                                       --> root of the partition
#       |
#       + .gd                                                   --> location of .gd 0 hop 
#       |                                                           away from /
#
# - .gd root folder **won't** be found if it is located on a totally different branch from the root
#   than the one we're calling the script from, i.e in the following situation(s):
#       /                                                       --> root of the partition
#       |
#       + <google_drive_folder>/.gd                             --> location of .gd
#       |
#       + <folder1>/.../# gd_root_folder="$(.drive-find-gd)"    --> call from a totally different 
#       |                                                           branch: 
#       |                                                       <folder1> != <google_drive_folder> 
#       |               OR
#       |
#       + <folder1>/.../# drive-<command>                       --> call from a totally different 
#       |                                                           branch
#         
# - .gd root folder **will** be found if it is located on a branch from the root which has at least
#   a common top folder with the one we're calling the script from, i.e in the following 
#   situation(s):
#       /                                                       --> root of the partition
#       |
#       + <folder1>/<google_drive_folder>/.gd                   --> location of .gd
#       |
#       + <folder1>/.../# gd_root_folder="$(.drive-find-gd)"
#       |
#       |               OR
#       |
#       + <folder1>/.../# drive-<command>
#
#       OR
#
#       /                                                       --> root of the partition
#       |
#       + <google_drive_folder>/.gd                             --> location of .gd
#       |
#       + <google_drive_folder>/.../# gd_root_folder="$(.drive-find-gd)"
#       |
#       |               OR
#       |
#       + <google_drive_folder>/.../# drive-<command>
#
###################################################################################################
#
# Usage examples:
# --------------
# cd ~/<google_drive_folder>/parent/folder/
# gd_root_folder="$(.drive-find-gd)"
#
###################################################################################################
if [[ $LOG_DRIVE_FIND_GD == ON ]]; then
        # Getting the last existing file descriptor of ~/.drive-google/logs/drive-google.log
        fd=$(ls -al /proc/$$/fd | grep ~/.drive-google/logs/drive-google.log | sed -E 's|^.* ([0-9]+) -> .*$|\1|g' | sort -V | tail -n 1)

        # Case where fd is unset, i.e the file ~/.drive-google/logs/drive-google.log has not yet been opened
        if [[ -z $fd ]]; then
                lowest_unused_fd () 
                {
                        local fd=0
                        while [ -e /proc/$$/fd/${fd} ]; do
                                fd=$((fd+1))
                        done
                        echo $fd
                }
                fd=$(lowest_unused_fd)

                # Opening ~/.drive-google/logs/drive-google.log as file descriptor $fd for appending
                eval "exec $fd>> ~/.drive-google/logs/drive-google.log"
        fi

        # Writing the trace output generated when set -x is enabled to file descriptor $fd 
        eval "BASH_XTRACEFD=$fd"
        # Logging line numbers - We could also use ${0} for ${BASH_SOURCE}
        BASH_SOURCE_BASENAME=$(basename ${BASH_SOURCE})
        export PS4='${BASH_SOURCE_BASENAME}.${LINENO}+ '
        # Expanding all variables and prints the full commands before output of the command
        set -x
fi

# Preventing globbing (pathname expansion)
set -o noglob
# Allowing extended globbing
shopt -s extglob
# Expanding aliases
shopt -s expand_aliases

# Including alias definitions to sed/grep/awk/perl commands for readability sake
. /usr/include/drive-google/aliases

local_folder="$(pwd)"

# Removing all occurrences of '&' in $local_folder as a workaround to a markup ampersand issue with zenity
noamp_local_folder="$(echo "${local_folder}" | rm_ampersand)"

while [[ "$(pwd)" != '/' ]]
do
        # Stopping find at first match - we don't' support symlinks when used with multiple Google Drive root folders
        gd_folder="$(find . -name  ".gd" -print -quit)"
        if [[ -n "$gd_folder" ]]; then
                # Supporting the case when going upstream (cd ..) from a symlink does not land us into its symlink parent,
                # but rather into its physical (real) parent
                # Actually, we don't really need to compute the number of times '/' appears in the path
                # number_of_occurrences=$(grep -o "/" <<< "$gd_folder" | wc -l)
                # if [[ $number_of_occurrences gt 1 ]]; then
                        cd "$gd_folder"/..
                # fi
                gd_root_folder="$(pwd)"
                break
        else
                cd ..
        fi
done

grep_esc_gd_root_folder=$(echo "$gd_root_folder" | escape_grep_search_string)

if [[ "$(pwd)" == '/' ]]; then
        # drive context does not exist
        echo  "No drive context found"
        exit 8
elif [[ -z "$(echo "$local_folder" | select_gd_root_folder)" ]]; then
        # We started from outside $gd_root_folder tree
        # previous "cd "$gd_folder"/.." is lost even if this script is sourced, because we have to return the "$gd_root_folder" string 
        echo "$gd_root_folder"
        exit 7
else
        # We started from below $gd_root_folder tree
        # cd "$local_folder" is useless since this script is not sourced
        echo "$gd_root_folder"
        exit 0
fi