-
Notifications
You must be signed in to change notification settings - Fork 0
/
phd
executable file
·1101 lines (902 loc) · 33 KB
/
phd
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env bash
PHD_VERSION="0.1"
PHD_GDOC_ID_MEETING_MINUTES=12Y79ci74ykhVJuS7kOQc5ge44owl4E4ntQK8Osy8fRE
PHD_GDOC_ID_REVIEW_FEEDBACK=1_HWrqVFU-W8_mq_OHjr4h2wzBfMor7yjy3rcX-Cs_JU
PHD_GDOC_ID_AUTHORSHIP_STMT=1LDKBHWtG_LV8v0TPnjjtPMAiorSfe4-B6njSHXIhdyY
PHD_GHUB_ID_PAPERS_TEMPLATE="https://github.com/alexcu/papers-template"
PHD_GHUB_TEMPLATE_GIT="https://github.com/alexcu/phd-template.git"
PHD_GHUB_TOOLS_GIT="https://github.com/alexcu/phd-tools.git"
OVERLEAF_URL="https://www.overleaf.com/project"
ANSI_BOLD=1
ANSI_ITALIC=3
ANSI_UNDERLINE=4
ANSI_RED=31
ANSI_YELLOW=33
ANSI_GREEN=32
ansi ()
{
echo -e "\033[${1}m${*:2}\033[0m";
}
checkcmd ()
{
if ! command -v "$1" &> /dev/null; then
return 1
else
return 0
fi
}
sethelp ()
{
if [[ "$HELP_ON" -eq 0 ]]; then
while read; do
echo "$REPLY"
done
exit 0
fi
}
chdir ()
{
pushd "$1" > /dev/null || (ansi $ANSI_RED "Cannot work within '$1'. Please report this error." >&2 && exit 1)
}
unchdir ()
{
popd > /dev/null || (ansi $ANSI_RED "Cannot return to previous working directory. Please report this error." >&2 && exit 1)
}
write_config ()
{
cat > "$PHD_CONFIG" <<- EOF
PHD_GDIR_ID_AUTHSTMTS=$PHD_GDIR_ID_AUTHSTMTS
PHD_GDIR_ID_MEETINGS=$PHD_GDIR_ID_MEETINGS
PHD_GDIR_ID_REVIEWS=$PHD_GDIR_ID_REVIEWS
EOF
chmod +x "$PHD_CONFIG"
}
get_gdir_id_retval=0
get_gdir_id ()
{
local folder_name=$1
local parent_folder_name=$2
local gdrive_website="http://drive.google.com/"
if [[ -n "$parent_folder_name" ]]; then
local parent_folder_name_prompt=" (under '$parent_folder_name')"
fi
ansi $ANSI_BOLD "The '$folder_name' folder is not yet known to PhD Tools."
cat <<- EOF
PhD Tools will open Google Drive in your web browser and ask you to copy the URL
of the folder '$folder_name'$parent_folder_name_prompt. Once Google Drive is opened, please return back to
your terminal for further instructions...
EOF
read -rp "Press enter now to open Google Drive..."
open $gdrive_website
ansi $ANSI_BOLD "\nWhat is URL of the Google Drive Folder named '$folder_name'$parent_folder_name_prompt?"
cat <<- EOF
Navigate to PhD folder stored within Google Drive and then double-click to the
'$folder_name' folder$parent_folder_name_prompt. Then copy the URL from the
address bar and paste it at the prompt below.
EOF
while [[ -z "$gdir_url" ]]; do
read -rp "Please enter the URL to the '$folder_name' folder$parent_folder_name_prompt: " gdir_url
done
get_gdir_id_retval=$(basename "$gdir_url")
}
copy_gdoc_template ()
{
local source_template_id=$1
local destination_folder_id=$2
local title=$3
local gdoc_type=$4
[[ -z $4 ]] && gdoc_type="document" || gdoc_type=$4
local url="https://docs.google.com/$gdoc_type/d/$source_template_id/copy?id=$source_template_id©Collaborators=false©Comments=false&includeResolvedCommentsOnCopy=false&title=$title©Destination=$destination_folder_id"
read -rp "About to create a new document named '$title'. Press enter to continue..."
open "$url"
}
setup ()
{
if ! checkcmd "brew"; then
echo "Homembrew missing. Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
if checkcmd "brew" -ne 0; then
ansi $ANSI_RED "ERROR: Homebrew didn't install properly. Try installing this yourself." >&2
exit 1
fi
fi
if ! checkcmd "gh"; then
echo "GitHub CLI missing. Installing GitHub CLI via Homebrew..."
ansi $ANSI_ORANGE "WARN: Please ensure you have a GitHub account!"
brew install gh
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not install gh command via brew. Try installing this yourself." >&2
exit 1
fi
fi
if ! checkcmd "greadlink"; then
echo "Coreutils missing. Installing coreutils via Homebrew..."
brew install coreutils
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not install coreutils command via brew. Try installing this yourself." >&2
exit 1
fi
fi
if [[ ! -f "$PHD_CONFIG" || ! -x "$PHD_CONFIG" ]]; then
echo "Config file missing or not executable. Creating new one at $PHD_CONFIG..."
write_config
fi
}
install ()
{
local gdfs_mount_dir="/Volumes/GoogleDrive/My Drive"
local gbas_mount_dir="$HOME/Google Drive"
local gdfs_download_url="https://dl.google.com/drive-file-stream/googledrivefilestream.dmg"
local gbas_download_url="https://dl.google.com/drive/InstallBackupAndSync.dmg"
local gdfs_brew_formula="google-drive-file-stream"
local gbas_brew_formula="google-backup-and-sync"
local gdfs_exists=1
local gbas_exists=1
local steps=7
ansi $ANSI_BOLD "(1/$steps) Checking if Google Drive File System (GDFS) is mounted..."
if [[ ! -d "$gdfs_mount_dir" ]]; then
ansi $ANSI_YELLOW "WARN: Google Drive File System (GDFS) does not seem to be mounted in the default"
ansi $ANSI_YELLOW " directory of '$gdfs_mount_dir'. Please ensure you have"
ansi $ANSI_YELLOW " installed GDFS and are logged into your GSuite account, or use GB&S."
else
ansi $ANSI_GREEN "OKAY: GDFS is mounted at $gdfs_mount_dir."
local gdfs_exists=0
fi
ansi $ANSI_BOLD "(2/$steps) Checking for Google Backup and Sync (GB&S) directory..."
if [[ ! -d "$gbas_mount_dir" ]]; then
ansi $ANSI_YELLOW "WARN: Google Backup and Sync (GB&S) does not seem to be mounted in the default"
ansi $ANSI_YELLOW " directory of '$gbas_mount_dir'. Please ensure you have"
ansi $ANSI_YELLOW " installed GB&S and are logged into your Google account, or use GDFS."
else
ansi $ANSI_GREEN "OKAY: GB&S is mounted at ~/GoogleDrive."
local gbas_exists=0
fi
if [[ "$gdfs_exists" -eq 1 && "$gbas_exists" -eq 1 ]]; then
ansi $ANSI_RED "ERROR: You don't seem to have either GDFS or GB&S installed. You need this to" >&2
ansi $ANSI_RED " create relevant Google Docs." >&2
cat >&2 <<- EOF
Please install either one at the following first, then try again.
Download URLs:
- GDFS: $gdfs_download_url
- GB&S: $gbas_download_url
Or install via Homebrew:
- GDFS: brew install $gdfs_brew_formula
- GB&S: brew install $gbas_brew_formula
Note that GDFS requires a GSuite Team, while GB&S is free up to 15GB.
EOF
exit 1
fi
PHD_BASEDIR=""
local confirm=""
while [[ ! "$confirm" == "y" ]]; do
ansi $ANSI_BOLD "(3/$steps) Where do you want to store your PhD base directory?"
cat <<- EOF
PhD Tools works with Google Drive and needs to be in a GDFS or GB&S directory.
E.g., '$gdfs_mount_dir/PhD' or '$gbas_mount_dir/PhD'.
EOF
if [[ "$gdfs_exists" -eq 0 ]]; then
read -rp "Enter a PhD base directory now ['$gdfs_mount_dir/PhD']: " PHD_BASEDIR
PHD_BASEDIR=${PHD_BASEDIR:-"$gdfs_mount_dir/PhD"}
elif [[ "$gbas_exists" -eq 0 ]]; then
read -rp "Enter a PhD base directory now ['$gbas_mount_dir/PhD']: " PHD_BASEDIR
PHD_BASEDIR=${PHD_BASEDIR:-"$gbas_mount_dir/PhD"}
fi
if [[ -d "$PHD_BASEDIR" ]]; then
ansi $ANSI_YELLOW "WARN: There is already a directory at $PHD_BASEDIR. It *will* be deleted!"
fi
read -rp "Your PhD base directory is '$PHD_BASEDIR'. Are you sure this is correct (y/n)? " confirm
done
PHD_SCRIPTDIR="$PHD_BASEDIR/Scripts"
rm -rf "$PHD_BASEDIR"
git clone --depth=1 --branch=master "$PHD_GHUB_TEMPLATE_GIT" "$PHD_BASEDIR"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not clone PhD template repo $PHD_GHUB_TEMPLATE_GIT. Try cloning this yourself and report this bug." >&2
exit 1
fi
rm -rf "$PHD_BASEDIR/.git"
find "$PHD_BASEDIR" -name "*.keep" -type f -delete
git clone --depth=1 --branch=master "$PHD_GHUB_TOOLS_GIT" "$PHD_SCRIPTDIR"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not clone PhD tools repo $PHD_GHUB_TOOLS_GIT. Try cloning this yourself and report this bug." >&2
exit 1
fi
ansi $ANSI_GREEN "OKAY: Set up your PhD base directory at '$PHD_BASEDIR'."
ansi $ANSI_BOLD "(4/$steps) Installing necessary software..."
PHD_CONFIG="$PHD_SCRIPTDIR/config"
setup
ansi $ANSI_BOLD "(5/$steps) Logging you into GitHub CLI..."
gh auth login
ansi $ANSI_BOLD "(6/$steps) Linking phd to /usr/local/bin..."
ln -nsf "$PHD_SCRIPTDIR/phd" /usr/local/bin/phd
ansi $ANSI_BOLD "(7/$steps) Ensuring all scripts executable..."
chmod +x /usr/local/bin/phd
find "$PHD_SCRIPTDIR" ! -name ".*" -type f -exec chmod +x {} \;
ansi $ANSI_GREEN "Successfully installed PhD tools!"
unset PHD_INSTALLER
phd help
return 0
}
find_pub_retval=""
find_pub ()
{
local pubkey=$1
if [[ -z "$pubkey" ]]; then
return 1
fi
find_pub_retval=$(find "$PHD_PAPERSDIR" -name "$pubkey" | grep -v arxiv)
return 0
}
unique_pubkey ()
{
local pubkey=$1
existing_pubkeys=$(find "$PHD_PAPERSDIR" -name "$pubkey" 2> /dev/null | wc -l)
if [[ "$existing_pubkeys" -gt 0 ]]; then
ansi $ANSI_RED "ERROR: A pubkey with a name '$pubkey' already exists. Please try again." >&2
echo "Location: $(find "$PHD_PAPERSDIR" -name "$pubkey")."
return 1
fi
return 0
}
pubkeywizard_retval=""
pubkeywizard ()
{
while [[ -z "$result" ]]; do
local venue=""
local year=""
local suffix=""
local result=""
local confirm=""
while [[ -z "$venue" ]]; do
ansi $ANSI_BOLD "(1/3) What is the abbreviation of the venue are you intending to publish at?"
cat << EOF
For example, this could be 'FSE' for Foundations of Software Engineering. If the
intended venue does not have an abbreviation (e.g., 'IEEE Software') then type
in the full name of the venue. If you do not have a venue yet, use 2–3 keywords
unique to your PhD instead (e.g., 'systematic review').
EOF
read -rp "Enter in an abbreviation: " venue
done
ansi $ANSI_BOLD "(2/3) Are you publishing at the same venue twice this year?"
cat << EOF
For example, if you are publishing at two different tracks at the same venue,
such as a demonstrations track and a industry track, you can enter in 'demo' and
'industry' here. Or if you are submitting two papers to the same track, you can
add in an additional keyword here (e.g., 'slr').
EOF
read -rp "Enter in a suffix if needed, or hit enter now to leave blank: " suffix
while [[ -z "$year" ]]; do
ansi $ANSI_BOLD "(3/3) What year do you intend to publish this work?"
cat << EOF
If you aren't sure yet (e.g., you aren't sure which venue you are publishing at)
then simply enter the current year.
EOF
read -rp "Enter in a year: " year
done
if [[ -z "$suffix" ]]; then
pubkey="$venue$year"
else
pubkey="$venue-$suffix$year"
fi
pubkey=$(echo "$pubkey" | tr "[:upper:]" "[:lower:]" | tr ' ' '-')
if ! unique_pubkey "$pubkey"; then
exit 1
fi
while [[ -z "$confirm" ]]; do
read -rp "Your publication key is '$pubkey'. Do you wish to use this pubkey (y/n)?" confirm
if [[ "$confirm" == "y" ]]; then
result="$pubkey"
fi
done
done
pubkeywizard_retval=$result
}
clonepub ()
{
sethelp <<- EOF
Usage: phd clonepub pubkey [newpubkey]
Clones an existing publication repo with the existing publication key, or
pubkey, as a pubkey. If no new pubkey is provided, then a wizard will help
you select a new pubkey.
EOF
local pubkey=$1
if [[ -z "$pubkey" ]]; then
ansi $ANSI_RED "ERROR: No pubkey provided! See help." >&2
exit 1
fi
if ! find_pub "$pubkey"; then
ansi $ANSI_RED "ERROR: No such publication with pubkey '$pubkey' exists." >&2
exit 1
fi
local newpubkey=$2
if [[ -z $newpubkey ]]; then
pubkeywizard
newpubkey=$pubkeywizard_retval
fi
if ! unique_pubkey "$newpubkey"; then
exit 1
fi
local steps=5
local pubdir
local new_pubdir
find_pub "$pubkey"
pubdir="$find_pub_retval"
new_pubdir="$(dirname "$find_pub_retval")/$newpubkey"
ansi $ANSI_BOLD "(1/$steps) Creating a new repo '$newpubkey' with flag 'inprogress'..."
chdir "$PHD_PAPERSDIR/inprogress"
gh repo create "$newpubkey" -y --private
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not create a repo. Please report this issue." >&2
exit 1
fi
unchdir
ansi $ANSI_BOLD "(2/$steps) Copying files from '$pubkey' to '$newpubkey'..."
rsync -avq --exclude='.git' "$pubdir/" "$new_pubdir"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not execute rsync command. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(3/$steps) Renaming '$pubkey.tex' to '$newpubkey.tex'..."
mv "$new_pubdir/$pubkey.tex" "$new_pubdir/$newpubkey.tex"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not remame '$pubkey.tex' to '$newpubkey.tex'. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(4/$steps) Pushing copied files to GitHub under repo '$newpubkey'..."
chdir "$new_pubdir"
# gh repo create does not honour its own config setting!
if [[ $(gh config get git_protocol) == "ssh" ]]; then
echo "Updating Git remote origin URL to use ssh..."
local gh_ssh_url=$(git config --get remote.origin.url | gsed -E "s/https:\/\/github.com\//git@github.com:/g")
git remote set-url origin "$gh_ssh_url"
fi
git add .
git commit -am "Intial commit from repo clone of '$pubkey'"
git push origin master
unchdir
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not push '$newpubkey' to GitHub. Please report this." >&2
exit 1
fi
ansi $ANSI_GREEN "Pushed copied files to '$newpubkey'!"
ansi $ANSI_BOLD "(5/$steps) Please import repo '$newpubkey' into a new Overleaf project"
cat <<- EOF
To continue, import the repository from GitHub into Overleaf by clicking on the
'New Project' button in the top left, then 'Import from GitHub' and search for
the repository named '$newpubkey'.
EOF
read -rp "Press enter now to open Overleaf..."
open "$OVERLEAF_URL"
ansi $ANSI_GREEN "Done! Your paper '$oldpubkey' was cloned to '$newpubkey'."
}
renamepub ()
{
sethelp <<- EOF
Usage: phd renamepub oldpubkey [newpubkey]
Renames an existing publication repo with the existing publication key, or
pubkey, to a new pubkey. If no new pubkey is provided, then a wizard will help
you select a new pubkey.
EOF
local oldpubkey=$1
if [[ -z "$oldpubkey" ]]; then
ansi $ANSI_RED "ERROR: No pubkey provided! See help." >&2
exit 1
fi
if ! find_pub "$oldpubkey"; then
ansi $ANSI_RED "ERROR: No such publication with pubkey '$oldpubkey' exists." >&2
exit 1
fi
local steps=6
local newpubkey=$2
if [[ -z $newpubkey ]]; then
pubkeywizard
newpubkey=$pubkeywizard_retval
fi
if ! unique_pubkey "$newpubkey"; then
exit 1
fi
local old_pubdir
local new_pubdir
find_pub "$oldpubkey"
old_pubdir="$find_pub_retval"
new_pubdir="$(dirname "$find_pub_retval")/$newpubkey"
ansi $ANSI_BOLD "(1/$steps) Renaming '$oldpubkey' to '$newpubkey' locally..."
mv "$old_pubdir" "$new_pubdir"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not execute mv command. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(2/$steps) Renaming '$oldpubkey.tex' to '$newpubkey.tex'..."
mv "$new_pubdir/$oldpubkey.tex" "$new_pubdir/$newpubkey.tex"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not rename '$oldpubkey.tex' to '$newpubkey.tex' command. Please report this." >&2
exit 1
fi
chdir "$new_pubdir"
ansi $ANSI_BOLD "(3/$steps) Commiting change of name and pushing to GitHub..."
git add "$newpubkey.tex"
git commit -am "Rename '$oldpubkey.tex' to '$newpubkey.tex'"
git push origin master
ansi $ANSI_BOLD "(4/$steps) Updating remote GitHub 'origin' URL for '$newpubkey'"
local old_gitremote
local new_gitremote
old_gitremote=$(git config --get remote.origin.url)
new_gitremote=$(echo "$old_gitremote" | gsed -E "s/[^/]+\.git$/$newpubkey\.git/g")
git remote set-url origin "$new_gitremote"
unchdir
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not push changes to GitHub. Please report this." >&2
exit 1
fi
local gh_repo
local gh_open_settings
gh_repo=$(echo "$old_gitremote" | gsed -E "s/^[^:]+:([^:]+)\.git$/\1/g")
gh_open_settings="https://github.com/$gh_repo/settings"
ansi $ANSI_BOLD "(5/$steps) Please update GitHub settings to rename the repo '$oldpubkey' to '$newpubkey'"
cat <<- EOF
To continue, you must open up GitHub's settings page for the old repo named
'$oldpubkey' and manually change its repo name to '$newpubkey'.
If you are not sure how to rename a GitHub repo, please refer to:
https://bit.ly/2JaAKYm.
EOF
read -rp "Press enter to open the GitHub settings page for this repo..."
open "$gh_open_settings"
ansi $ANSI_BOLD "(6/$steps) Please rename Overleaf project from '$oldpubkey' to '$newpubkey'"
cat <<- EOF
To continue, you must open up the Overleaf Dashboard, click on the checkbox
next to the project listed as '$oldpubkey', then click 'More' (in the top
righthand corner), and then click 'Rename'. Please ensure you set the new name
to '$newpubkey'.
For more details on how to rename an Overleaf project, please refer to:
https://bit.ly/2HBakyi.
EOF
read -rp "Press enter now to open Overleaf..."
open "$OVERLEAF_URL"
ansi $ANSI_GREEN "Done! Your paper '$oldpubkey' was renamed to '$newpubkey'."
}
newpub ()
{
sethelp <<- EOF
Usage: phd newpub [pubkey]
Sets up a new repo and relevant subdirectories for a new paper you wish to work
on. A publication key (pubkey) is a unique identifier for a publication. Follow
the below guidelines to form a pubkey:
1. Use the abbreviation of your venue lowercased and, if applicable
hyphenated (e.g., 'icse' or 'ieee-software'). If you don't have an intended
venue yet, think of the primary contribution of your paper and hyphenate it
(e.g., 'systematic-review').
2. Append any additional info if you plan to submit two papers at the same
venue (e.g., a demonstrations track could have a suffix 'demo').
3. Use the year the intended publication will be published (e.g., '2020'). Use
the current year if you do not have an intended publication year (yet).
4. Hyphenate (1) and (2) if applicable, and add the year at the end
(e.g., 'ieee-software2020' or 'icse-demo2020').
If no pubkey is provided, then a small wizard will help you generate one. Once
you have an intended venue, it is advised you update it.
EOF
local pubkey=$1
if [[ -z $pubkey ]]; then
pubkeywizard
pubkey=$pubkeywizard_retval
fi
if ! unique_pubkey "$pubkey"; then
exit 1
fi
local steps=6
ansi $ANSI_BOLD "(1/$steps) Creating a new repo '$pubkey' on GitHub..."
chdir "$PHD_PAPERSDIR/inprogress"
gh repo create "$pubkey" -y --private --template $PHD_GHUB_ID_PAPERS_TEMPLATE
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not create a repo. Please report this issue." >&2
exit 1
fi
unchdir
ansi $ANSI_GREEN "Created '$pubkey' on GitHub and set up on '$PHD_PAPERSDIR/inprogress."
ansi $ANSI_BOLD "(2/$steps) Pulling down contents of '$pubkey' from GitHub..."
chdir "$PHD_PAPERSDIR/inprogress/$pubkey"
# gh repo create does not honour its own config setting!
if [[ $(gh config get git_protocol) == "ssh" ]]; then
echo "Updating Git remote origin URL to use ssh..."
local gh_ssh_url=$(git config --get remote.origin.url | gsed -E "s/https:\/\/github.com\//git@github.com:/g")
git remote set-url origin "$gh_ssh_url"
fi
git pull origin master
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not pull contents of repo '$pubkey.tex'. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(3/$steps) Renaming template 'main.tex' to '$pubkey.tex'..."
mv main.tex "$pubkey.tex"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not rename 'main.tex' to '$pubkey.tex' command. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(4/$steps) Removing 'README.md'..."
rm README.md
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not remove 'README.md'. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(5/$steps) Commiting changes and pushing to GitHub..."
git commit -am "Remove template README.md"
git add "$pubkey.tex"
git commit -am "Rename 'main.tex' to '$pubkey.tex'"
git push origin master
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not push changes to GitHub. Please report this." >&2
exit 1
fi
unchdir
ansi $ANSI_BOLD "(6/$steps) Please import repo '$pubkey' into a new Overleaf project"
cat <<- EOF
To continue, import the repository from GitHub into Overleaf by clicking on the
'New Project' button in the top left, then 'Import from GitHub' and search for
the repository named '$pubkey'.
EOF
read -rp "Press enter now to open Overleaf..."
open "$OVERLEAF_URL"
ansi $ANSI_GREEN "Done! Please refer to https://github.com/alexcu/papers-template on how to use the template."
}
flagpub ()
{
sethelp <<- EOF
Usage: phd flagpub pubkey [abandonded|inprogress|published|rejected]
Moves the publication with the given pubkey to the new directory to indicate its
status of publication.
EOF
local pubkey=$1
local flag=$2
case "$flag" in
abandoned) ;;
inprogress) ;;
published) ;;
rejected) ;;
arxiv) ansi $ANSI_RED "ERROR: Please use the arxivpub command for this purpose." >&2 && exit 1 ;;
*) ansi $ANSI_RED "ERROR: Unknown flag or no flag provided." >&2 && exit 1 ;;
esac
if ! find_pub "$pubkey"; then
ansi $ANSI_RED "ERROR: No such publication with pubkey '$pubkey' exists." >&2
exit 1
fi
local pubdir="$find_pub_retval"
mv "$pubdir" "$PHD_PAPERSDIR/$flag"
ansi $ANSI_GREEN "Moved '$pubkey' to '$flag' papers"
}
arxivpub ()
{
sethelp <<- EOF
Usage: phd arxiv pubkey
Prepares the publication with the pubkey provided for submission to arXiv by
removing all comments and consolidating all .tex files (using \input) into a
single file, main.tex. Zips these files up ready to be uploaded to arXiv.
EOF
local pubkey=$1
if ! find_pub "$pubkey"; then
ansi $ANSI_RED "ERROR: No such publication with pubkey '$pubkey' exists." >&2
exit 1
fi
local pubdir="$find_pub_retval"
local arxiv_dir="$PHD_PAPERSDIR/arxiv/$pubkey"
local arxiv_zip="$PHD_PAPERSDIR/arxiv/$pubkey.zip"
if [[ -d "$arxiv_dir" || -f "$arxiv_zip" ]]; then
ansi $ANSI_YELLOW "WARN: There seems to be an arXiv folder for '$pubkey'."
ansi $ANSI_YELLOW " This *will* be deleted along with any associated ZIPs."
read -rp "Press enter to continue, or Ctrl+C to stop..."
rm -rf "$arxiv_dir" "$arxiv_zip"
fi
local steps=6
ansi $ANSI_BOLD "(1/$steps) Making arXiv directory at $arxiv_dir..."
mkdir "$arxiv_dir"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not create directory '$arxiv_dir'. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(2/$steps) Copying all non-TeX files over..."
rsync -avq --exclude='.git' --exclude='*.tex' --exclude='*.bib' "$pubdir/" "$arxiv_dir"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not rsync correctly. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(3/$steps) Merging all TeX files into '$pubkey.tex' with all comments stripped..."
chdir "$pubdir"
local recursiveinputawk="$PHD_SCRIPTDIR/recursiveinput.awk"
export PHD_RECUSRIVE_INPUT_AWK=\"$recursiveinputawk\"
"$recursiveinputawk" "$pubkey.tex" 2> /dev/null | gsed '/\s*%/d' | cat -s > "$arxiv_dir/$pubkey.tex"
unset PHD_RECUSRIVE_INPUT_AWK
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not compile merged TeX file. Please report this." >&2
exit 1
fi
unchdir
ansi $ANSI_BOLD "(4/$steps) arXiv requires all .bbl files to be added for each .bib file"
local bib_files
local bbl_files
local count_bibs
bib_files=$(ls -1 "$pubdir"/*.bib)
count_bibs=$(echo "$bib_files" | wc -l | gsed "s/\s//g")
bbl_files=$(echo "$bib_files" | gsed -E "s/.bib/.bbl/g")
cat <<-EOF
You have $count_bibs .bib files. Please open up the project '$pubkey' in
Overleaf and *recompile* your project. Next, click on the 'Logs & Output Files'
button (the page icon) next to the 'Recompile' button. Scroll to the bottom of
the logs. At the bottom righthand corner, click 'Other logs & files' and
download all $count_bibs of the following .bbl file(s):
$bbl_files
Place the $count_bibs .bbl file(s) into $arxiv_dir. Note that Overleaf will name
the default bbl file as output.bbl.
EOF
read -rp "Press enter now to open Overleaf..."
open "$OVERLEAF_URL"
read -rp "Press enter once you have placed all $count_bibs .bbl file(s) in $arxiv_dir..."
while [ ! -f "$arxiv_dir/output.bbl" ]; do
ansi $ANSI_YELLOW "WARN: There does not seem to be the default 'output.bbl' downloaded from"
ansi $ANSI_YELLOW " Overleaf in the directory '$arxiv_dir'. Please ensure this is placed"
ansi $ANSI_YELLOW " along with any other .bbl files downloaded from Overleaf (total of $count_bibs)."
read -rp "Press enter once you have placed all $count_bibs .bbl file(s) in $arxiv_dir..."
done
ansi $ANSI_BOLD "(5/$steps) Renaming default 'output.bbl' to '$pubkey.bbl'..."
mv "$arxiv_dir/output.bbl" "$arxiv_dir/$pubkey.bbl"
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not rename 'output.bbl' to '$pubkey.bbl'. Please report this." >&2
exit 1
fi
ansi $ANSI_BOLD "(6/$steps) Preparing ZIP to be uploaded into arXiv..."
chdir "$arxiv_dir"
zip -r "$arxiv_zip" .
if [[ "$?" -ne 0 ]]; then
ansi $ANSI_RED "ERROR: Could not ZIP contents for arXiv. Please report this." >&2
exit 1
fi
unchdir
ansi $ANSI_GREEN "Prepared $arxiv_zip for submission to arXiv."
echo "You may need to make minor modifications to your files if arXiv finds issues."
echo "Please ensure you update your changes within $arxiv_dir."
}
reviewpub ()
{
sethelp <<- EOF
Usage: phd review pubkey
Prepares a reviewer feedback spreadsheet for the publication with the pubkey
provided. For instructions on how to break down reviewer feedback using the
reviewer spreadsheet, please visit the following URL: https://bit.ly/33ebKGF.
Additionally asks for the .eml file containing the reviewer feedback email for
record-keeping purposes.
EOF
local pubkey=$1
if ! find_pub "$pubkey"; then
ansi $ANSI_RED "ERROR: No such publication with pubkey '$pubkey' exists." >&2
exit 1
fi
ansi $ANSI_BOLD "Please drag-and-drop your reviewer email from Outlook/Mail into the 'Reviews' folder."
cat <<- EOF
Keep a record of the email you have recieved with your reviewer feedback on the
publication '$pubkey'.
If you are using Outlook/Mail for Mac, you can drag and drop the email file out
from Outlook/Mail and into the 'Reviews' folder. If you are using a web-browser
client, please try to export an .eml file from the email recieved.
Make sure to rename the .eml file to '$pubkey.eml'.
EOF
read -rp "Press enter now to open your Reviews folder..."
open "$PHD_BASEDIR/Reviews"
ansi $ANSI_BOLD "Creating copy of reviewer template."
if [[ -z $PHD_GDIR_ID_REVIEWS ]]; then
get_gdir_id 'Reviews'
PHD_GDIR_ID_REVIEWS=$get_gdir_id_retval
write_config
fi
copy_gdoc_template "$PHD_GDOC_ID_REVIEW_FEEDBACK" "$PHD_GDIR_ID_REVIEWS" "$pubkey" "spreadsheets"
ansi $ANSI_GREEN "Reviewer feedback spreadsheet opened. Please press the 'Make a copy' button."
echo "Please refer to https://bit.ly/33ebKGF for methods on how to break down reviewer feedback."
}
authorpub ()
{
sethelp <<- EOF
Usage: phd author pubkey
Prepares an authorship statement document for the publication with the pubkey
provided. Authorship statements should be made for all publications made with
co-authors during your PhD candidature. These forms should be signed by all
authors and at the time of publication acceptance.
EOF
local pubkey=$1
if ! find_pub "$pubkey"; then
ansi $ANSI_RED "ERROR: No such publication with pubkey '$pubkey' exists." >&2
exit 1
fi
ansi $ANSI_BOLD "Creating copy of authorship template."
if [[ -z $PHD_GDIR_ID_AUTHSTMTS ]]; then
get_gdir_id 'Authorship Statements' 'Admin'
PHD_GDIR_ID_AUTHSTMTS=$get_gdir_id_retval
write_config
fi
copy_gdoc_template "$PHD_GDOC_ID_AUTHORSHIP_STMT" "$PHD_GDIR_ID_AUTHSTMTS" "$pubkey"
ansi $ANSI_GREEN "Authorship statement document opened. Please press the 'Make a copy' button."
}
phdopen ()
{
sethelp <<- EOF
Usage: phd open
Opens your PhD Google Drive directory.
EOF
open "$PHD_BASEDIR"
}
meeting ()
{
sethelp <<- EOF
Usage: phd meeting [yyyy-dd-mm]
Creates a meeting minute document set to today's date or the date provided.
EOF
local date
[[ -z $1 ]] && date=$(date +%F) || date=$1
ansi $ANSI_BOLD "Creating copy of meeting minutes template."
if [[ -z $PHD_GDIR_ID_MEETINGS ]]; then
get_gdir_id 'Meetings'
PHD_GDIR_ID_MEETINGS=$get_gdir_id_retval
write_config
fi
copy_gdoc_template "$PHD_GDOC_ID_MEETING_MINUTES" "$PHD_GDIR_ID_MEETINGS" "$date"
ansi $ANSI_GREEN "Meeting document opened. Please press the 'Make a copy' button."
}
lint ()
{
sethelp <<- EOF
Usage: phd lint [type] [pubkey|/path/to/latex/file.tex]
Lints a LaTeX file, where type is one of:
- dups scans for two duplicate *words words* in a row;
- tlas scans for *TLAs* (three-letter acronyms);
- passive scans for phrases that *is written* in the passive tense;
- weasel scans for *a lot* of weasel words in your TeX file.
Unless an absolute path is provided, the path to the LaTeX file autodefaults to
a file relative to the Papers directory. Or uses the default pubkey LaTeX file.
EOF
local script="$PHD_SCRIPTDIR/$1"
local texfile=$2
if [[ ! -f "$script" ]]; then
ansi $ANSI_RED "ERROR: Unknown lint script '$1'. Run with -h or --help for linters." >&2
exit 1
fi
find_pub "$texfile" # treat input as pubkey...
local pubdir="$find_pub_retval"
if [[ ! -f "$texfile" ]]; then
texfile="$pubdir/$texfile.tex"
if [[ ! -f "$texfile" ]]; then
ansi $ANSI_RED "ERROR: Cannot find file at $texfile." >&2
exit 1
fi
fi
local recursiveinputawk="$PHD_SCRIPTDIR/recursiveinput.awk"
export PHD_RECUSRIVE_INPUT_AWK=\"$recursiveinputawk\"
local temp=$(mktemp)
"$recursiveinputawk" "$texfile" 2> /dev/null > "$temp"
unset PHD_RECUSRIVE_INPUT_AWK
"$script" "$temp"
rm "$temp"
}
update ()
{
sethelp <<- EOF
Usage: phd update
Checks for the latest version.
EOF
ansi $ANSI_BOLD "Checking for PhD Tool updates..."
chdir "$PHD_SCRIPTDIR"
git pull origin master
unchdir
}
version ()
{
sethelp <<- EOF
Usage: phd version
Prints out the current version of this tool.
EOF
echo $PHD_VERSION
}
wordcount ()
{
sethelp <<- EOF
Usage: phd wordcount [pubkey|/path/to/latex/file.tex]
Performs a wordcount on a LaTeX file, or a group of related LaTeX files using
the \input{another-file.tex} command. Or uses the default pubkey LaTeX file.
Unless an absolute path is provided, the path to the LaTeX file autodefaults to
a file relative to the Papers directory.
EOF
local recursiveinputawk="$PHD_SCRIPTDIR/recursiveinput.awk"
local texcountpl="$PHD_SCRIPTDIR/texcount.pl"
local texfile=$1
find_pub "$texfile" # treat input as pubkey...
local pubdir="$find_pub_retval"
if [[ ! -f "$texfile" ]]; then
texfile="$pubdir/$texfile.tex"
if [[ ! -f "$texfile" ]]; then
ansi $ANSI_RED "ERROR: Cannot find file at $texfile." >&2
exit 1
fi
fi
ansi $ANSI_BOLD "Running word count on $texfile and its subfiles..."
chdir "$(greadlink -f "$(dirname "$texfile")")"
export PHD_RECUSRIVE_INPUT_AWK=\"$recursiveinputawk\"
"$recursiveinputawk" "$texfile" 2> /dev/null | perl "$texcountpl" -col -
unset PHD_RECUSRIVE_INPUT_AWK
unchdir
}
help ()
{
sethelp <<- EOF