-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathbloomr.build.R
2754 lines (2169 loc) · 101 KB
/
bloomr.build.R
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
### BloomR source
## TODO
## Complete commonilisation of Rmd components in Rmd's in BloomR.src/src/br-libs/ as for bloomr-time.Rmd
## In bloomr.init.R, eikonapir loading removes requestInfo from .GlobalEnv with a hack. Test it and then delete eikon.fallback()
## In bloomr.Rmd bdh always.display.ticker, dates.as.row.names and perhaps more relate to old java package.
## Custom polymode (bremacs-rmd-mode), temporary disabled, to be restored in br-setmode.el
## Repurpose tests and test data
##
##
## Usage:
## Source this file and run:
## makeBloomR("path/to/workDir")
## You will get the BloomR green installer in workDir
##
## Requirements:
## xml2 and curl packages. If missing, I try to download and install them.
## R should be able to connect to the Internet.
## .Platform$OS.type == "windows"
##
## Credits:
## R from https://www.r-project.org/
## blpapi_java*.tar from http://www.openbloomberg.com/open-api/
## TinyTeX https://yihui.org/tinytex/TinyTeX-1.zip
## peazip from http://sourceforge.net/projects/peazip
## ahkscript from http://ahkscript.org
## Nsis from nsis.sourceforge.net
## innoextract from http://constexpr.org/innoextract
## Icon set Simplicio CC 3.0 by Neurovit: http://neurovit.deviantart.com
## retrieved at https://www.iconfinder.com/icons/48750/direction_right_icon
##
### Globals
### =======
G <- new.env()
### Customisable globals
### Contribs
## Eikon
G$eikonurl <- "https://github.com/ahmedmohamedali/eikonapir/archive/master.zip"
G$eikonzip <- 'eikon'
## Ahkscript
G$ahkurl <- "AutoHotkey/Ahk2Exe" # (on GitHub)
G$ahkzip <- "ahk"
## Github project
G$github <- "https://raw.githubusercontent.com/AntonioFasano/BloomR/master"
## Packages to download. Case sensitive
## To learn about deps use:
## x <- available.packages(); x["ggplot2","Imports"]; x["ggplot2","Depends"]
pks <- "knitr Rblpapi xts xml2 httr rmarkdown sodium httpuv"
pks <- paste(pks, "XML plyr pbapply") # for read read.xlx
## All packs deps
G$packlist <- pks
rm(pks)
## BloomR infrastructure packages
G$bloomrpacks <- c("secretR", "pcloudr", "elearnr") |>
paste0(".tar.gz")
## Innoextract
G$innourl <- "http://constexpr.org/innoextract/files"
G$innozip <- 'innoextract'
## R
G$rurl <- "https://cloud.r-project.org/bin/windows/base/"
G$rzip <- 'rmain'
## Emacs
G$emacsurl <- "http://ftp.gnu.org/gnu/emacs/windows/"
G$emacszip <- "emacs"
G$emacs.type <- "emacs.*?.zip$" # e.g. emacs-28.2.zip
## BR/Emacs packages
G$bremacs.paks.repos <- c( # archives in Elisp lingo
## Order is relevant in case of multiple matches
`stable-melpa` = "https://stable.melpa.org/",
elpa = "https://elpa.gnu.org/",
melpa = "https://melpa.org/")
G$bremacs.paks <- c("ess", "poly-R", "bm")
G$bremacs.paks.pinned <- NULL
G$bremacs.paks.pinned <- c(ess = "melpa") # or NULL
G$bremacs.paks.manual <- NULL # Manually (tar) linked with a descriptive .el file. prevailing on pinned.
## G$bremacs.paks.manual <- # list(NAME = c(tarurl = VALUE, descurl = VALUE), ...). See bremacs.pak.getdata.manual()
##
## list(
## ess = c(tarurl = "https://github.com/emacs-ess/ESS/archive/refs/tags/ESSRv1.8.tar.gz",
## descurl = "https://raw.githubusercontent.com/emacs-ess/ESS/a1d177cb87bf96e34f58cd59854ddfb2a2957b39/lisp/ess.el"
## ),
## `ado-mode` = c(tarurl = "https://github.com/louabill/ado-mode/archive/refs/tags/1.17.0.2.tar.gz",
## descurl = "https://raw.githubusercontent.com/louabill/ado-mode/5610074e29ce08631c5210f1873938c3bcd9cbde/lisp/ado-mode.el")
## )
G$bremacs.paks.tree <- NULL # BRemacs pack names, deps, etc
G$bremacs.paks.order <- NULL # BRemacs pack setup order
## zst, used to unpack Mingw Aspell
G$zstdgit <- "facebook/zstd"
G$zstd <- "zst"
## Aspell
G$aspell <- "aspell"
G$aspellurl <- "https://raw.githubusercontent.com/ScoopInstaller/Main/master/bucket/aspell.json"
## SourceForge items
G$pzip <- "peazip"
G$nsisurl <- 'portableapps'
G$nsiszip <- 'nsis'
## Pandoc for Studio
G$panurl <- "jgm/pandoc" # (on GitHub)
G$panzip <- "pandoc"
## TeX distro
G$texurl <- "https://yihui.org/tinytex/TinyTeX-1.zip"
G$texzip <- "tinytex"
### Internal globals not intended to be customised.
G$lastshell <- NULL # Output of last shell invocation
G$curver <- NULL # The sam found in the file curver.txt
## Local paths
G$work <- NULL # This is the build workdir, not to be confused wtih R getwd()
G$downdir <- NULL # This is the downloads dir
G$appname <- "apps" # BloomR application folder name, used by app.pt(). It's hardcoded at least in br-init.el, so don't change.
G$branch <- NULL # Branch dir. The value can be "brCore" or "brEmacs" (for non-Core editions)
G$me <- NULL # This file (automatically detected)
G$prjdir <- NULL # The project directory, based on G$me
G$frames <- sys.frames() # used to find G$me wihtout calling the build function
G$tempmap <- NULL # Temporary Windows net drive, used by commands not supporting a detected UNC path
G$workcpy <- NULL # A copy of G$work stored when a remap occures
## makeBloomR() arguments
G$bremacs <- NULL
G$studio <- NULL
G$ndown <- 0
G$what <- NULL # What edition? If what !'core', then is.bremacs() TRUE
G$builds <- NULL # Char vector of remaining builds to go
G$github.local <- "" # Auto-set by makeBloomR() if gitsim=T, relative to the build workdir
## Path conventions
## Paths are normally related to G$work or G$downdir.
## Absolute paths are retrieved by means of work.pt() and down.pt().
## Other *.pt functions return paths relative to special BloomR folders e.g. root.pt().
## Primitive functions not using the *.pt functions use a foo_ template
makeBloomR <- function( # Build BloomR
work, # work dir path, absolute or relative to cur path
downdir=NULL, # optional directory for assets download. It can't be a subidrectory `work`, nor end with a ":".
tight=FALSE, # Reuse the downloads directory and build workdir
ndown=2, # num of download attempts
what='all', # what edition: all/core/lab/studio
## For debug/test:
bundle='exe', # exe/zip/all/none make the related installer for distribution
ask=TRUE, # asks if to overwrite the existent build workdir and installer
deb=1:6, # defaults to 1:6 to execute all steps build steps, modify to debug, avoid with what=all
gitsim=FALSE, # local path (abs. or relative) to simulate github downloads.
reset=TRUE # Only set FALSE internally to allow multi-builds calls and keep globals
) {
## Get the local git project directory
get.project()
## Set work dir
if(!is.null(work) && !nzchar(work)) stop("Please, specify a work directory as first arg!")
chk.colon(work)
chk.zero.path(work)
G$work <- work
## Set downloads dir
if(!is.null(downdir)){
chk.colon(downdir)
chk.zero.path(downdir)
if(is.subdir_gen(downdir, work))
stop(downdir, "\n cannot be a subidrectory of\n", work, ".")
}
G$downdir <- if(is.null(downdir)) work.pt("!downloads") else downdir
## Set git dir
G$github.local <- ""
if(gitsim!=FALSE && nzchar(gitsim))
if (file.info(gitsim)$isdir)
G$github.local <- gitsim else {
stop(gitsim, "is not an existing dir")}
## Windows?
if(.Platform$OS.type != "windows")
stop("Sorry, Bloomberg Terminal only exists for Windows and so BloomR.")
## Check for required packages
if(!loadLib("curl")) return(1)
if(!loadLib("xml2")) return(1)
## Parse Arguments
editions <- c('all', 'core', 'lab', 'studio')
if(length(what) > 1 || ! what %in% editions) stop(pv("'what' argument is not one in", sQuote(editions)))
G$what <- what
## Don't touch the build history, if reset =FALSE
if(reset) {
G$builds <- what
if(what == 'all') G$builds <- editions[-1]
}
## We use a single branch directory for Lab and Studio. The former needs be bundled before adding Studio files
G$branch <- ifelse(is.bremacs(), "brEmacs", "brCore")
## Parse residual arguments
G$ndown <- ndown
## Step 1
if(1 %in% deb) {
existMake( '', overwrite=!tight, ask, paste("working dir:\n", G$work))
existMake.dd('', overwrite=!tight, ask, paste("downloads dir:\n", G$downdir))
}
## Step 2
if(2 %in% deb) downloads(tight)
## Step 3
if(3 %in% deb) expand()
## Step 4
if(4 %in% deb) bloomrTree()
## Step 5
if(5 %in% deb) initScripts()
## Step 6
if(6 %in% deb) makeBundle(bundle, ask)
## Make additional builds. If what == 'all', during the Studio build several steps are skipped. See was.lab()
G$builds <- G$builds[-1] # needs makeBloomR(reset=F)
if(length(G$builds)) makeBloomR(
work=work, downdir=downdir, tight=TRUE,
ndown=ndown, bundle=bundle, ask=ask,
what=what,
reset =FALSE, # this will keep G$builds status
deb=deb, gitsim=gitsim)
}
### Editions' predicates
is.multi <- function() G$what == 'all'
get.edition <- function() G$builds[1]
is.core <- function() get.edition() == 'core'
is.lab <- function() get.edition() == 'lab'
is.studio <- function() get.edition() == 'studio'
is.bremacs <- function() is.lab() || is.studio()
was.core <- function() is.multi() && is.bremacs()
was.lab <- function() is.multi() && is.studio()
###== Main steps ==
### Load CRAN packages
loadLib <- function(lib){
if (!lib %in% rownames(installed.packages())){
repo <- getOption("repos")[["CRAN"]]
if(repo=="@CRAN@") repo <- "http://cran.r-project.org"
install.packages(lib, repos=repo)
}
if(success <- require(lib, character.only = TRUE)) return(success)
message("\nUnable to load ", lib, " library")
FALSE
}
### Get components
downloads <- function(tight){
overwrite <- !tight
if(!was.core()) downloads.core(overwrite)
if(is.bremacs() && !was.lab()) downloads.lab(overwrite)
if(is.studio()) downloads.studio(overwrite)
}
downloads.core <- function(overwrite){
## PeaZip
cback <- function(){
url <- sfFirstInProject(G$pzip, '[[:digit:]]') #get release dir
url <- sfFirstInUrl(url, "portable[^\"]*?windows")
sfDirectLink(url)
}
download.nice(cback, G$pzip, overwrite,
"Peazip files")
## innoextract
cback <- function(){
dir <- web.greplink("innoextract-", pos=-1, G$innourl, abs=TRUE)
web.greplink("\\.zip$", pos=0, dir, abs=TRUE)
}
download.nice(cback, G$innozip, overwrite,
"Innoextract")
## R
from <- web.greplink("R.+win\\.exe", pos=0, G$rurl, abs=TRUE)
download.nice(from, G$rzip, overwrite,
"main R files")
## NSIS
cback <- function(){
url <- sfFirstInProject(G$nsisurl, G$nsiszip)
url <- sfFirstInUrl(url, 'english\\.paf')
sfDirectLink(url)
}
download.nice(cback, G$nsiszip, overwrite,
"NSIS")
## CRAN packages
existMake.dd("rlibs", overwrite=overwrite, ask=FALSE, "packages dir:")
packs <- getDeps.format(G$packlist)
for(pack in unique(packs)) # Loop over packs and download them
download.nice(cran.geturl(pack), makePath("rlibs", pack), overwrite,
pack)
## Eikon
download.nice(G$eikonurl, G$eikonzip, overwrite,
"Eikon files")
## ahkscript
cback <- \() github.latest(G$ahkurl, "zip$")
download.nice(cback, G$ahkzip, overwrite, "AutoHotkey")
}
downloads.lab <- function(overwrite){
### BloomR Lab downloads
## Create BRemacs download folder
existMake.dd("bremacs-libs", overwrite=overwrite, ask=FALSE, "BRemacs packages dir:")
cback <- function(){
dir <- web.greplink("emacs-../", pos=-1, G$emacsurl, abs=TRUE)
zip <- web.greplink(G$emacs.type, pos=-1, dir)
p0(dir, zip)
}
download.nice(cback, G$emacszip, overwrite,
"Emacs files")
## Elisp packages
bremacs.pak.getrepos(overwrite)
G$bremacs.paks.tree <- bremacs.pak.maketree() # G$bremacs.paks + deps
paknames <- names(G$bremacs.paks.tree)
pakurls <- bremacs.pak.tree.el("url")
basenames <- bremacs.pak.tree.el("basename")
existMake("bremacs-retar", overwrite=overwrite, ask=FALSE, "BRemacs retar dir:") # only used in case of compressed tars
message(sprintf(
"Melpa archive changes often. If you recycled it and get a package download error, try deleting \n%s",
down.pt("melpa.el")
))
for(pack in paknames){ # Loop over packs and download them
from <- pakurls[pack]
to <- makePath("bremacs-libs", basenames[pack])
download.nice(from, to, overwrite, pack)
## Remove compression and rename tar.gz, tgz
retar(to, "bremacs-retar", pack)
}
## zst
cback <- \() github.latest(G$zstdgit, "win64.zip$")
download.nice(cback, G$zstd, overwrite, "zst")
## Aspell (some libs are not used)
existMake.dd(G$aspell, overwrite=overwrite, ask=FALSE, "Spell check dir")
json <- readLines(G$aspellurl)
regex <- "https://.+mingw64.+pkg.tar.zst"
zsts <- regmatches(json, regexpr(regex, json))
for(zst in zsts) # Loop over zst files and download them
download.nice(zst, makePath(G$aspell, basename(zst)), overwrite, basename(zst))
}
downloads.studio <- function(overwrite){
### BloomR Studio downloads
## Download TinyTeX distro
download.nice(G$texurl, G$texzip , overwrite, "TinyTeX")
## Pandoc
cback <- \() github.latest(G$panurl, "windows.+zip$")
download.nice(cback, G$panzip, overwrite, "Pandoc")
}
### Expand components
expand <- function(){
if(!was.core()) expand.core()
if(is.bremacs() && !was.lab()) expand.lab()
if(is.studio()) expand.studio()
}
expand.core <- function(){
## Peazip
uzip(G$pzip, G$pzip, "Peazip binaries")
## innoextract
uzip(G$innozip, G$innozip, "innoextract binaries")
## R files
innoextract(G$rzip, G$rzip, "R files")
## NSIS files
uzip.7z(G$nsiszip, G$nsiszip, "NSIS files")
## Eikon
uzip(G$eikonzip, G$eikonzip, "Eikon binaries")
## CRAN packages
message('\nExpanding packages', '...')
from <- "rlibs"
del.path("rlibs")
## Loop and extract packs
for(pack in dir(down.pt(from)))
uzip(makePath('rlibs', pack), 'rlibs',
paste('R package', pack), delTarget=FALSE)
## ahkscript
uzip(G$ahkzip, G$ahkzip, "ahkscript")
}
expand.lab <- function(){
### Expand BloomR Lab
uzip(G$emacszip, G$emacszip, "BRemacs files")
#browser()
## zstd
uzip(G$zstd, G$zstd, "zstd binaries")
## Aspell
makeDir(G$aspell, "Spell check dir")
for(zst in dir(down.pt(G$aspell))) {
zstpt <- makePath(G$aspell, zst)
tarpt <- tools::file_path_sans_ext(zstpt) # arg like *.tar.zst
uzip.zx(zstpt, tarpt, zst)
utar.ww(tarpt, makePath(G$aspell, "tars"), basename(tarpt), delTarget = FALSE)
}
}
expand.studio <- function(){
## Expand TinyTeX
uzip(G$texzip, G$texzip, "TinyTeX distro")
## Expand Pandoc
uzip(G$panzip, G$panzip, "Pandoc binaries")
}
bloomrTree <- function(){
### Make BloomR directory tree
### Core components are needed by Lab and Studio too, and Lab's by Studio too.
### However, to save space/time Lab and Studio share a common `brEmacs' branch dir,
### i.e., in a multi-build, Studio recycles previous Lab `brEmacs' dir rather than build a new dir from scratch
switch(get.edition(),
core= bloomrTree.Core(),
lab= {
bloomrTree.Core()
bloomrTree.brEmacs()
},
studio={
## For a Studio build, after a Lab build, we recycle the dir and skip else we go
if (was.lab()){
messagev("This is a Studio Edition build, but a previous Lab Edition has been bundled,",
"\nso we are recycling its branch folder.")
bloomrTree.Studio()
} else {
bloomrTree.Core()
bloomrTree.brEmacs()
bloomrTree.Studio()
}
})
}
bloomrTree.AddVersion <- function() { # Add and possible relpace version file (ver, build, edition) to tree
### Studio will replace the Lab version file, Lab will replace the Core file.
download.git("curver.txt", "curver.txt")
G$curver <- ver <- file.read("curver.txt")[1]
edt <- paste(get.edition(), "edition")
build <- makeBuildnum()
file.write(p0(ver, "\n", build, "\n", edt), app.pt("bloomr.txt"))
}
bloomrTree.Core <- function() {
### Make BloomR Core tree
### All editions contain Core edition files, so this function output differs only in the name given to the build folder, which is
### G$branch, that is "brCore" or "brEmacs" (for non-Core editions)
message("\nCreating BloomR tree")
desc <- if(is.core()) "BloomR Core" else "Common BloomR Lab/Studio"
existMake(G$branch, TRUE, FALSE, p0(desc, " root dir:"))
makeDir(app.pt(), "BloomR app dir:")
## Add version file
bloomrTree.AddVersion()
## Copy R and make site directory
from <- p0(G$rzip , '/app')
to <- app.pt("R")
copy.dir(from, to, "main R files")
makeDir(app.pt('R/site-library'), "BloomR library:")
## Copy libs
message("\nAdding R libraries")
lib.from <- 'rlibs'
lib.to <- app.pt("R/library")
for(lib in dir(work.pt(lib.from))){
message("Adding ", lib)
from <- makePath(lib.from, lib)
to <- makePath(lib.to, lib)
copy.dir(from, to)
}
## Install Eikon package
message("Install Eikon API")
## In Windows R CMD invokes cmd.exe, which is incompatible with a UNC build workdir.
## So we'll use a local workdir when invoking it and absolute paths
exe <- winwork.pt(app.pt('R/bin/R.exe'))
from <- winwork.pt(p0(G$eikonzip,'/eikonapir-master'))
to <- winwork.pt(app.pt('R/library'))
to <- p0("--library=", to)
cmd <- c(exe, "--no-site-file --no-environ --no-save --no-restore --quiet CMD INSTALL", from, to)
shell.cd(cmd, wd="c:") # In Windows cmd.exe is invoked, so we need to set wd to a non-UNC path
## Install BloomR infrastructure packages
message("Install BloomR infrastructure packages")
existMake("rlibs-bloomr", TRUE, FALSE, "BloomR infrastructure packages dir:")
exe <- winwork.pt(app.pt('R/bin/R.exe'))
to <- winwork.pt(app.pt('R/library'))
to <- p0("--library=", to)
for(pack in G$bloomrpacks) { # Loop over packs and download them
pack.relpath <- p0("res/", pack)
download.git(pack.relpath, "rlibs-bloomr")
from <- winwork.pt(makePath("rlibs-bloomr", pack))
cmd <- c(exe, "--no-site-file --no-environ --no-save --no-restore --quiet CMD INSTALL", from, to)
shell.cd(cmd, wd="c:") # In Windows cmd.exe is invoked, so we need to set wd to a non-UNC path
}
## Download docs
message("\nDownloading BloomR help resources")
download.git("README.html", root.pt("README.html"))
download.git("LICENSE", root.pt("LICENSE.txt"))
makeDir(root.pt("help"), "BloomR help directory:")
download.git("src/xlx/xlx.help.html", root.pt("help/xlx.help.html"))
download.git("src/xlx/xlx.help.pdf", root.pt("help/xlx.help.pdf"))
download.git("reports/reporting.pdf", root.pt("help/reporting.pdf"))
download.git("src/br-libs/bloomr-bbg.html", root.pt("help/bloomr-bbg.html"))
download.git("src/br-libs/bloomr-bbg.pdf", root.pt("help/bloomr-bbg.pdf"))
download.git("src/br-libs/bloomr-rmd.html", root.pt("help/bloomr-rmd.html"))
download.git("src/br-libs/bloomr-rmd.pdf", root.pt("help/bloomr-rmd.pdf"))
download.git("src/br-libs/bloomr-time.html", root.pt("help/bloomr-time.html"))
download.git("src/br-libs/bloomr-time.pdf", root.pt("help/bloomr-time.pdf"))
download.git("res/elearnr.pdf", root.pt("help/elearnr.pdf"))
download.git("res/pcloudr.pdf", root.pt("help/pcloudr.pdf"))
download.git("res/secretR.pdf", root.pt("help/secretR.pdf"))
download.git("res/frontier.pdf", root.pt("help/frontier.pdf"))
download.git("res/Bloomberg API Intro.pdf", root.pt("help/Bloomberg API Intro.pdf"))
## These docs are not uploaded on git, so they are added only with gitsim != FALSE
if(nzchar(G$github.local)){
# Old temporary temp-help/ material, now mostly in res/ or auto-generated
}
## Environment diagnostic
message("\nAdding ED tools")
makeDir(app.pt('ed'), "ED tools:")
download.git("src/ed/core.cmd", app.pt("ed/core.cmd"))
}
bloomrTree.brEmacs <- function() {
### Make BRemacs directory tree
bremacs <- app.pt("bremacs")
existMake(bremacs, TRUE, FALSE, "BRemacs tree")
## Replace version file
bloomrTree.AddVersion()
## Copy Emacs
message("Copying main BRemacs files")
from <- G$emacszip
dirs <- c('bin', 'lib', 'libexec', 'share/emacs', 'share/icons', 'share/info', 'share/man')
copy.glob(from, bremacs, dirs)
## === Download BRemacs lib files === ##
makeDir(slisp.pt("bremacs"), "BRemacs library:")
## Filename list. If chhanged rubuild like that
## dir("src/bremacs/lib/", "\\.el$")
brlib.files <- "br-init-dbg.el br-init.el br-keys.el br-menico.el br-recentf.el
br-rnw.el br-setmodes.el br-simple-buffer-menu.el
splith.svg splith.xpm" |>
gsub("\n", "", x =_) |> strsplit(split= " +") |> unlist() |> Filter(nzchar, x=_)
## Ready to download BRemacs lib files
d <- slisp.pt("bremacs")
x <- sapply(brlib.files, function(f)
download.git(makePath("src/bremacs/lib", f), makePath(d, f)))
## Download BRemacs early-init.el
makeDir(app.pt("bremacs/.emacs.d"), "BRemacs init dir:")
download.git("src/bremacs/lib/early-init.el", app.pt("bremacs/.emacs.d/early-init.el"))
## Environemnt diagnostic
message("\nAdding ED tools")
download.git("src/ed/bremacs.cmd", app.pt("ed/bremacs.cmd"))
download.git("src/ed/bremacs-dbg.cmd", app.pt("ed/bremacs-dbg.cmd"))
## Run with log
## download.git("src/cs/run.cs", "run.cs") # currently evaluate in local src to keep a working git exe
build.runtool()
## === Install local BRemacs packages === ##
message("Installing local BRemacs packages")
message("...this may take a bit")
if(is.null(G$bremacs.paks.tree)) stop("'G$bremacs.paks.tree', to be populated during the download step, is NULL.
The download step was not executed or something went wrong")
tarpaths <- makePath(down.pt("bremacs-libs"), bremacs.pak.tree.el("basename"))
G$bremacs.paks.order <- bloomrTree.brEmacs.pakorder()
tarpaths.ord <- tarpaths[G$bremacs.paks.order]
tarpaths.txt <- paste(lapply(tarpaths.ord, dquoteu), collapse = " ")
package.user.dir <- normalizePath(work.pt(slisp.pt()))
elisp.t <- "
(let ((package-user-dir %s)
(default-directory %s))
(require 'package)
(mapc #'package-install-file (list %s)))
"
sprintf(elisp.t, dquoteu(package.user.dir), dquoteu(getwd()), tarpaths.txt) |>
runsexp(log = "run.breamcs-paks.txt")
## debug
## tarpaths.txt <- paste(lapply(tarpaths.ord[1], dquoteu), collapse = " ") # just first pak
## runsexp(elisp, "dbg")
message("\n\n*** Local BRemacs packages setup successfully completed ***\n\n")
## === Byte compile BRemacs packages === ##
message("Starting byte-compilation...")
message("...this may take a bit")
## (byte-recompile-directory DIR 0) recompile subdirs of DIR even if no elc is present
## Recompile builtin Emacs GNU files. Sometimes some are not
message("Recompiling builtin packages")
eldir.gnu <- normalizePath(work.pt(globpaths(bremacs, 'share/emacs/[0-9]*')))
sprintf("(byte-recompile-directory %s)", dquoteu(eldir.gnu)) |> # was: %s 0 Check COMPATIBILITY
runsexp(log = "run.breamcs-gnu.txt")
## Compile our BRemacs libs.
message("Recompiling BRemacs specific packages")
eldir.site <- normalizePath(work.pt(slisp.pt()))
eldir.bremacs <- normalizePath(work.pt(slisp.pt("bremacs")))
elisp.t <- "
(let* ((default-directory %s)
(bremacs-libs %s))
(normal-top-level-add-subdirs-to-load-path)
(byte-recompile-directory bremacs-libs 0))
"
sprintf(elisp.t, dquoteu(eldir.site), dquoteu(eldir.bremacs)) |>
runsexp(log = "run.breamcs-paks.txt", append = TRUE)
## For a debug .el file, its .elc would only add a layer of complexity
debug.init <- slisp.pt("bremacs/br-init-dbg.elc")
if(is.path(debug.init)) del.path(debug.init) else stop("Can't find debug init file\n", debug.init)
## Backup elc files
elcs <- globpaths(slisp.pt("bremacs"), "*.elc")
copy.bak(elcs)
## Recompile all site-lisp packs.
## `package-install-file' alredy does, so normally not needed
eldir.site <- normalizePath(work.pt(slisp.pt()))
elisp.t <- "
(let* ((site-lisp %s)
(default-directory site-lisp))
(normal-top-level-add-subdirs-to-load-path)
(byte-recompile-directory site-lisp 0))
"
## sprintf(elisp.t, dquoteu(eldir.site)) |> runsexp() # not usually used
message("\n\n*** Byte-compilation completed ***\n\n")
#browser()
## Aspell
copy.dir(makePath(G$aspell, "tars/mingw64"), app.pt('bremacs/share/aspell'), "Aspell files...")
}
bloomrTree.brEmacs.pakorder <- function() { # Find Elisp pack setup order
### Output intended for G$bremacs.paks.order
## Recursive
vitinst <- function(paknames, installed = NULL) { # simulate recursive the install
for(pakname in paknames) {
if(pakname %in% installed) next
deps <- G$bremacs.paks.tree[[pakname]]$deps
are.deps.installed <- if(length(deps)) deps %in% installed else TRUE
deps.to.inst <- deps[!are.deps.installed]
if(all(are.deps.installed)) {
installed <- c(installed, pakname)
} else {
installed <- vitinst(c(deps.to.inst, pakname), installed)
}
}
installed
}
## Kick off recursive setup
vitinst(names(G$bremacs.paks.tree))
}
bloomrTree.Studio <- function() {
### We add the to the tree created by bloomrTree.brEmacs() the LaTeX related component
## Replace version file
bloomrTree.AddVersion()
makeStudio.addLatex()
## makeStudio.addPerl()
makeStudio.addPandoc()
}
makeStudio.addLatex <- function() {
### Install LaTeX. Currently TinyTex
## Copy TinyTeX distro
message("Adding LaTeX files")
copy.glob(G$texzip, app.pt(), "tinytex")
## TeXLive installer path
tlmgrpt <- makePath(app.pt(G$texzip), 'bin/windows/tlmgr.bat')
if(!is.path(tlmgrpt)) stop("Unable to find executable:\n ", work.pt(tlmgrpt))
tlmgr <- \() pswork.pt(tlmgrpt) # parametric for of UNC remappting used in the past
## Set xetex fonts dir to local
## Check before and after with: texmf-var/fonts/conf/fonts.conf
cmd <- paste(tlmgr(), "postaction install script xetex")
shell.ps(cmd, winwork.pt("ps.tinytex.txt"))
## Do not wrap short (80 columns) log file lines
cmd <- paste(tlmgr(), "conf texmf max_print_line 10000")
shell.ps(cmd, winwork.pt("ps.tinytex.txt"))
## Set repo for updates to nearby
cmd <- paste(tlmgr(), "option repository 'ctan'")
shell.ps(cmd, winwork.pt("ps.tinytex.txt"))
## Updates might be necessary
## There is a luahbtex issue with a missing vcruntime140_1.dll
## BTW, the exclution does not prevent post-update buldint and
## hence an error
cmd <- paste(tlmgr(), "update --self --all --exclude luahbtex")
shell.ps(cmd, winwork.pt("ps.tinytex.txt"))
## Extra packages: bookmark needed for most reports, makeindex for
## R package manuals, and beamer is for slides
extratex <- c("bookmark", "makeindex", "beamer")
cmd <- pv(tlmgr(), "install", extratex)
shell.ps(cmd, winwork.pt("ps.tinytex.txt"))
## Test they are there
cmd <- paste(tlmgr() , "info --list --only-installed --data name")
shell.ps(cmd, winwork.pt("ps.tinytex-paks.txt"))
con <- file(work.pt("ps.tinytex-paks.txt"), "r", encoding = 'UTF-16')
texpks <- readLines(con)
close(con)
fail.texpks <- !extratex %in% texpks
if(any(fail.texpks)) stop("Failed to instal TeX packages:\n", pv(extratex[fail.texpks]))
return()
### ==============
## More packs for minimal Rnw: palatino breakurl fpl mathpazo
morepaks <- c("palatino", "breakurl", "fpl", "mathpazo")
## TODO: attempt to customise Tinytex paths Now PDF building
## functions add on the fly paths to system PATH and remove them
## on exit. Before fixing compare with tlmgr() above
rscript <- makePath(app.pt("R"), 'bin/Rscript.exe')
rscript <- winwork.pt(rscript)
args <- "library('tinytex')"
tinytex.dir <- work.pt(app.pt("tinytex"))
## Powershell call operator doesnt work with double quotes and backslash in shQuote(). This is a temp fix:
usquote <- function(path) squoteu(normalizePath(path, winslash = "/", mustWork = FALSE))
tinytex.dir.sh <- usquote(tinytex.dir)
morepaks <- paste(sapply(morepaks, squoteu), collapse = ', ')
args <- c(args,
sprintf(
"install_tinytex(dir = %s, version = 'daily', add_path = FALSE, extra_packages = c(%s))",
tinytex.dir.sh, morepaks))
## Find tlmgr for r_texmf
tlmgr <- makePath(tinytex.dir, "bin/windows/tlmgr.bat")
tlmgr <- usquote(tlmgr)
args <- c(args,
sprintf("options(tinytex.tlmgr.path = %s)", tlmgr))
## Remove hard path. The alternative could be to copy files to texmf-local
args <- c(args, "r_texmf('remove')")
message("Executing:")
message(rscript)
messagev(args, s = "\n")
qargs <- shQuote(pv(args, s="; "))
cmd <- paste(rscript, "-e", qargs)
shell.ps(cmd, winwork.pt("ps.tinytex.txt"))
## Old MikTeX paks
toinstall <- "upquote microtype parskip kvoptions ltxcmds kvsetkeys xurl bookmark infwarerr kvdefinekeys
pdfescape hycolor letltxmacro auxhook intcalc etexcmds bitset bigintcalc rerunfilecheck
uniquecounter geometry fancyvrb framed booktabs footnotehyper refcount gettitlestring"
toinstall <- paste(toinstall, "pdfcrop") # required by intermediate commands
}
makeStudio.addPandoc <- function(){ # NOT USED
## Pandoc variables (msi wants abs path)
pandir <- app.pt("pandoc")
## Create Pandoc dir
existMake(pandir, TRUE, FALSE, "Pandoc dir:")
globpaths(G$panzip, "/pandoc*") |>
copy.dir(makePath(pandir, "/bin"), "Pandoc files")
}
makeStudio.addPerl <- function(){
message("Making Perl tiny")
perlsource <- G$perlzip
perldir <- app.pt("perl")
perlbins <- makePath(perldir, "bin")
perllibs <- makePath(perldir, "lib")
existMake(perldir, TRUE, FALSE, "Adding Perl files")
makeDir(perlbins)
makeDir(perllibs)
binpaths <- "
libgcc_s_seh-1.dll
libstdc++-6.dll
libwinpthread-1.dll
perl.exe
perl532.dll
"
libpaths <- "
auto
Config.pm
Config_git.pl
Config_heavy.pl
constant.pm
Cwd.pm
DynaLoader.pm
Exporter
Exporter.pm
File
Getopt
overload.pm
overloading.pm
strict.pm
vars.pm
warnings
warnings.pm
Win32.pm
XSLoader.pm
"
f <- function(string) sapply(strsplit(trimws(string), "\n")[[1]], trimws, USE.NAMES = FALSE)
binpaths <-f(binpaths)
libpaths <- f(libpaths)
sbins <- sapply(binpaths, function(pth) makePath(perlsource, p0("perl\\bin\\", pth)))
slibs <- sapply(libpaths, function(pth) makePath(perlsource, p0("perl\\lib\\", pth)))
sapply(sbins, function(from) file.copy(work.pt(from), work.pt(perlbins)))
sapply(slibs, function(from) file.copy(work.pt(from), work.pt(perllibs), recursive=TRUE))
}
###== Boot functions ==
initScripts <- function(){
### Make R and BloomR etc files (configs such as Rprofile.site from PROF()) and the launchers
### Etc. files are currently the same for all the editions while launchers differ
## Test deb/what mismatch
debug.mismatch()
initScripts.etc()
## Make R bootstrapper launcher
if(is.core()) makeLauncher.Core()
## brEmacs editons include also the Core edition, thus the launcher
if(is.bremacs()) {
makeLauncher.Core()
makeLauncher.brEmacs()
}
}
initScripts.etc <- function() {
message("\nMaking etc/Rprofile.site and shared directory")
## Make new Rprofile.site and keep old
p <- capture.output(PROF) # Get PROF function definition
p <- p[-c(1, length(p))] # Remove "function {", "}"
prof.new <- app.pt('R/etc/Rprofile.site')
prof.nat <- app.pt('R/etc/Rprofile.native')
## Append with Unix line endings
if(!is.file(prof.nat)){
prof.new <- work.pt(prof.new)
prof.nat <- work.pt(prof.nat)
file.copy(prof.new, prof.nat)
con <- file(prof.new, open="ab")
writeLines(text=p, con=con)
close(con)
}
## Get bloomr lib files including xlx.R from Github
to <- app.pt("R/share/bloomr")
makeDir(to,"BloomR share directory:")
download.git("src/bloomr.init.R", app.pt("R/share/bloomr/bloomr.init.R"))
## download.git("src/bloomr.beta.R", app.pt("R/share/bloomr/bloomr.beta.R"))
## download.git("src/bloomr.api.R", app.pt("R/share/bloomr/bloomr.api.R"))
download.git("src/bloomr.sys.R", app.pt("R/share/bloomr/bloomr.sys.R"))
download.git("src/bloomr.test.R", app.pt("R/site-library/bloomr.test.R"))
download.git("src/br-libs/bloomr-bbg.R", app.pt("R/share/bloomr/bloomr-bbg.R"))
download.git("src/br-libs/bloomr-rmd.R", app.pt("R/share/bloomr/bloomr-rmd.R"))
download.git("src/br-libs/bloomr-time.R", app.pt("R/share/bloomr/bloomr-time.R"))
download.git("src/xlx/xlx.R", app.pt("R/share/bloomr/xlx.R"))
## Testdata
to <- app.pt("R/share/bloomr/testdata")
makeDir(to,"BloomR share directory:")
download.git("src/testdata/testdata.high.R", app.pt("R/share/bloomr/testdata/testdata.high.R"))
download.git("src/testdata/testdata.low.R", app.pt("R/share/bloomr/testdata/testdata.low.R"))
## Make personal dir with some sample files
makeDir(root.pt('mybloomr'), "personal directory:")
makeDir(root.pt('mybloomr/examples'), "personal directory:")
download.git("res/semic.csv", root.pt("mybloomr/examples/semic.csv"))
download.git("res/tickers.csv", root.pt("mybloomr/examples/tickers.csv"))
download.git("res/tickers.eqt.csv", root.pt("mybloomr/examples/tickers.eqt.csv"))
download.git("res/my-first-report.Rmd", root.pt("mybloomr/examples/my-first-report.Rmd"))
download.git("res/tryme.R", root.pt("mybloomr/examples/tryme.R"))
}
makeLauncher.Core <- function(){
### Make launcher of Core editions
## Boot string
core.run <- "
EnvSet, BLOOMR, %A_ScriptDir%
EnvSet, HOME, %A_ScriptDir%\\mybloomr
EnvSet, bloomr_branch, core
Run, apps\\R\\bin\\x64\\Rgui.exe LANGUAGE=en
"
core.run <- gsub("%AppDir%", G$appname, core.run)
makeLauncher_(core.run, "core")
}
makeLauncher.brEmacs <- function(){
### Make launcher of Lab and Studio editions
bremacs.run <- "
EnvSet, BLOOMR, %A_ScriptDir%
EnvSet, HOME, %A_ScriptDir%\\mybloomr