Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117881600
install-jsdeps.sh
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
13 KB
Referenced Files
None
Subscribers
None
install-jsdeps.sh
View Options
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
|
This file is part of the Roundcube Webmail client
|
|
|
|
Copyright
(
C
)
The Roundcube Dev Team
|
|
|
|
Licensed under the GNU General Public License version
3
or
|
|
any later version with exceptions
for
skins
&
plugins.
|
|
See the README file
for
a full license statement.
|
|
|
|
PURPOSE:
|
|
Utility script to fetch and install all 3rd party javascript
|
|
libraries used
in
Roundcube from source.
|
+-----------------------------------------------------------------------+
|
Author: Thomas Bruederli <thomas@roundcube.net>
|
+-----------------------------------------------------------------------+
*/
define
(
'INSTALL_PATH'
, realpath
(
__DIR__ .
'/..'
)
.
'/'
)
;
require_once INSTALL_PATH .
'program/include/clisetup.php'
;
if
(
!function_exists
(
'exec'
))
{
rcube::raise_error
(
"PHP exec() function is required. Check disable_functions in php.ini."
, false,
true
)
;
}
$cfgfile
=
INSTALL_PATH .
'jsdeps.json'
;
$SOURCES
=
json_decode
(
file_get_contents
(
$cfgfile
)
,
true
)
;
if
(
empty
(
$SOURCES
[
'dependencies'
]))
{
rcube::raise_error
(
"Failed to read dependencies list from
$cfgfile
"
, false,
true
)
;
}
$CURL
=
trim
(
`
which curl
`
)
;
$WGET
=
trim
(
`
which wget
`
)
;
$UNZIP
=
trim
(
`
which unzip
`
)
;
if
((
$CACHEDIR
=
getenv
(
"CACHEDIR"
))
&&
is_writeable
(
$CACHEDIR
))
{
// use
$CACHEDIR
}
else
if
(
is_writeable
(
INSTALL_PATH .
'temp/js_cache'
)
||
@mkdir
(
INSTALL_PATH .
'temp/js_cache'
,
0774
,
true
))
{
$CACHEDIR
=
INSTALL_PATH .
'temp/js_cache'
;
}
else
{
$CACHEDIR
=
sys_get_temp_dir
()
;
}
//////////////// License definitions
$LICENSES
=
[]
;
$LICENSES
[
'MIT'
]
=
<<<
EOM
* Licensed under the MIT licenses
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
(
the
*
"Software"
)
, to deal
in
the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to
do
so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included
in
all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED
"AS IS"
, WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EOM
;
$LICENSES
[
'GPLv3'
]
=
<<<
EOG
* The JavaScript code
in
this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License
(
GNU GPL
)
as published by the Free Software
* Foundation, either version
3
of the License, or
(
at your option
)
* any later version. The code is distributed WITHOUT ANY WARRANTY
;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL
for
more details.
*
* As additional permission under GNU GPL version
3
section
7
, you
* may distribute non-source
(
e.g., minimized or compacted
)
forms of
* that code without the copy of the GNU GPL normally required by
* section
4
, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
EOG
;
$LICENSES
[
'LGPL'
]
=
<<<
EOL
* The JavaScript code
in
this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation, either version
3
of the License, or
(
at your option
)
* any later version.
EOL
;
//////////////// Functions
/**
* Fetch package file from
source
*/
function
fetch_from_source
(
$package
,
$useCache
=
true,
&
$filetype
=
null
)
{
global
$CURL
,
$WGET
;
$cache_file
=
extract_filetype
(
$package
,
$filetype
)
;
if
(
!is_readable
(
$cache_file
)
||
!
$useCache
)
{
if
(
empty
(
$CURL
)
&&
empty
(
$WGET
))
{
rcube::raise_error
(
"Required 'wget' or 'curl' program not found."
, false,
true
)
;
}
$url
=
str_replace
(
'$v'
,
$package
[
'version'
]
,
$package
[
'url'
])
;
echo
"Fetching
$url
\n"
;
if
(
$CURL
)
{
exec
(
sprintf
(
'%s -L -s %s -o %s'
,
$CURL
, escapeshellarg
(
$url
)
,
$cache_file
)
,
$out
,
$retval
)
;
}
else
{
exec
(
sprintf
(
'%s -q %s -O %s'
,
$WGET
, escapeshellarg
(
$url
)
,
$cache_file
)
,
$out
,
$retval
)
;
}
// Try Github API as a fallback
(
#6248)
if
(
$retval
!
==
0
&&
!empty
(
$package
[
'api_url'
]))
{
$url
=
str_replace
(
'$v'
,
$package
[
'version'
]
,
$package
[
'api_url'
])
;
$header
=
'Accept:application/vnd.github.v3.raw'
;
rcube::raise_error
(
"Fetching failed. Using Github API on
$url
"
)
;
if
(
$CURL
)
{
exec
(
sprintf
(
'%s -L -H %s -s %s -o %s'
,
$CURL
, escapeshellarg
(
$header
)
, escapeshellarg
(
$url
)
,
$cache_file
)
,
$out
,
$retval
)
;
}
else
{
exec
(
sprintf
(
'%s --header %s -q %s -O %s'
,
$WGET
, escapeshellarg
(
$header
)
, escapeshellarg
(
$url
)
,
$cache_file
)
,
$out
,
$retval
)
;
}
}
if
(
$retval
!
==
0
)
{
rcube::raise_error
(
"Failed to download source file from
$url
"
, false,
true
)
;
}
}
return
$cache_file
;
}
/**
* Returns package
source
file location and
type
*/
function
extract_filetype
(
$package
,
&
$filetype
=
null
)
{
global
$CACHEDIR
;
$filetype
=
pathinfo
(
$package
[
'url'
]
, PATHINFO_EXTENSION
)
?:
'tmp'
;
$cache_file
=
$CACHEDIR
.
'/'
.
$package
[
'lib'
]
.
'-'
.
$package
[
'version'
]
.
'.'
.
$filetype
;
// Make sure it is a zip file
if
(
file_exists
(
$cache_file
))
{
$magic
=
file_get_contents
(
$cache_file
, false, null,
0
,
4
)
;
if
(
$magic
===
"PK\003\004"
)
{
$filetype
=
'zip'
;
}
}
return
$cache_file
;
}
/**
* Create a destination javascript file with copyright and license header
*/
function
compose_destfile
(
$package
,
$srcfile
)
{
global
$LICENSES
;
$header
=
sprintf
(
"/**\n * %s - v%s\n *\n"
,
$package
[
'name'
]
,
$package
[
'version'
])
;
if
(
!empty
(
$package
[
'source'
]))
{
$header
.
=
" * @source "
. str_replace
(
'$v'
,
$package
[
'version'
]
,
$package
[
'source'
])
.
"\n"
;
$header
.
=
" *\n"
;
}
if
(
!empty
(
$package
[
'license'
])
&&
isset
(
$LICENSES
[
$package
[
'license'
]]))
{
$header
.
=
" * @licstart The following is the entire license notice for the\n"
;
$header
.
=
" * JavaScript code in this file.\n"
;
$header
.
=
" *\n"
;
if
(
!empty
(
$package
[
'copyright'
]))
{
$header
.
=
" * "
.
$package
[
'copyright'
]
.
"\n"
;
$header
.
=
" *\n"
;
}
$header
.
=
$LICENSES
[
$package
[
'license'
]]
;
$header
.
=
" *\n"
;
$header
.
=
" * @licend The above is the entire license notice\n"
;
$header
.
=
" * for the JavaScript code in this file.\n"
;
}
$header
.
=
" */\n"
;
if
(
file_put_contents
(
INSTALL_PATH .
$package
[
'dest'
]
,
$header
. file_get_contents
(
$srcfile
)))
{
echo
"Wrote file "
. INSTALL_PATH .
$package
[
'dest'
]
.
"\n"
;
}
else
{
rcube::raise_error
(
"Failed to write destination file "
. INSTALL_PATH .
$package
[
'dest'
]
, false,
true
)
;
}
}
/**
* Extract a Zip archive into the destination specified by the package config
*/
function
extract_zipfile
(
$package
,
$srcfile
)
{
global
$UNZIP
,
$CACHEDIR
;
if
(
empty
(
$UNZIP
))
{
rcube::raise_error
(
"Required 'unzip' program not found."
, false,
true
)
;
}
$destdir
=
INSTALL_PATH .
$package
[
'dest'
]
;
if
(
!is_dir
(
$destdir
))
{
mkdir
(
$destdir
,
0775
,
true
)
;
}
if
(
!is_writeable
(
$destdir
))
{
rcube::raise_error
(
"Cannot write to destination directory:
$destdir
"
, false,
true
)
;
}
// pick files from zip archive
if
(
!empty
(
$package
[
'pick'
]))
{
foreach
(
$package
[
'pick'
]
as
$pattern
)
{
echo
"Extracting files
$pattern
into
$destdir
\n"
;
exec
(
sprintf
(
'%s -o %s %s -d %s'
,
$UNZIP
, escapeshellarg
(
$srcfile
)
, escapeshellarg
(
$pattern
)
,
$destdir
)
,
$out
,
$retval
)
;
if
(
$retval
!
==
0
)
{
rcube::raise_error
(
"Failed to unpack
$pattern
; "
. implode
(
'; '
.
$out
))
;
}
}
}
// unzip the archive and map
source
to dest files/directories
else
if
(
!empty
(
$package
[
'map'
]))
{
$extract
=
$CACHEDIR
.
'/'
.
$package
[
'lib'
]
.
'-extract'
;
if
(
!is_dir
(
$extract
))
{
mkdir
(
$extract
,
0774
,
true
)
;
}
$zip_command
=
'%s -'
.
(
!empty
(
$package
[
'flat'
])
?
'j'
:
'o'
)
.
' %s -d %s'
;
exec
(
sprintf
(
$zip_command
,
$UNZIP
, escapeshellarg
(
$srcfile
)
,
$extract
)
,
$out
,
$retval
)
;
// get the root folder of the extracted package
$extract_tree
=
glob
(
"
$extract
/*"
, GLOB_ONLYDIR
)
;
$sourcedir
=
count
(
$extract_tree
)
?
$extract_tree
[
0
]
:
$extract
;
foreach
(
$package
[
'map'
]
as
$src
=
>
$dest
)
{
echo
"Installing
$sourcedir
/
$src
into
$destdir
/
$dest
\n"
;
$dest_file
=
$destdir
.
'/'
.
$dest
;
$src_file
=
$sourcedir
.
'/'
.
$src
;
// make sure the destination
's parent directory exists
if (strpos($dest, '
/
') !== false) {
$parentdir = dirname($dest_file);
if (!is_dir($parentdir)) {
mkdir($parentdir, 0775, true);
}
}
// avoid copying source directory as a child into destination
if (is_dir($src_file) && is_dir($dest_file)) {
exec(sprintf('
rm -rf %s
', $dest_file));
}
exec(sprintf('
mv -f %s %s
', $src_file, $dest_file), $out, $retval);
if ($retval !== 0) {
rcube::raise_error("Failed to move $src into $dest_file; " . implode('
;
' . $out));
}
// Remove sourceMappingURL
else if (isset($package['
sourcemap
']) && $package['
sourcemap
'] === false) {
if ($content = file($dest_file)) {
$index = count($content);
if (preg_match('
|
sourceMappingURL
=
|
', $content[$index-1])) {
array_pop($content);
file_put_contents($dest_file, implode('', $content));
}
}
}
}
// remove temp extraction dir
exec('
rm -rf
' . $extract);
}
// extract the archive into the destination directory
else {
echo "Extracting zip archive into $destdir\n";
exec(sprintf('
%s -o %s -d %s
', $UNZIP, escapeshellarg($srcfile), $destdir), $out, $retval);
if ($retval !== 0) {
rcube::raise_error("Failed to unzip $srcfile; " . implode('
;
' . $out));
}
}
// remove some files from the destination
if (!empty($package['
omit
'])) {
foreach ((array)$package['
omit
'] as $glob) {
exec(sprintf('
rm -rf %s/%s
', $destdir, escapeshellarg($glob)));
}
}
// prepend license header to extracted files
if (!empty($package['
addlicense
'])) {
foreach ((array)$package['
addlicense
'] as $filename) {
$pkg = $package;
$pkg['
dest
'] = $package['
dest
'] . '
/
' . $filename;
compose_destfile($pkg, $destdir . '
/
' . $filename);
}
}
}
/**
* Delete the package destination file/dir
*/
function delete_destfile($package)
{
$destdir = INSTALL_PATH . (!empty($package['
rm
']) ? $package['
rm
'] : $package['
dest
']);
if (file_exists($destdir)) {
if (PHP_OS === '
Windows
') {
exec(sprintf("rd /s /q %s", escapeshellarg($destdir)));
}
else {
exec(sprintf("rm -rf %s", escapeshellarg($destdir)));
}
}
}
//////////////// Execution
$args = rcube_utils::get_opt([
'
f
' => '
force:bool
',
'
d
' => '
delete:bool
',
'
g
' => '
get:bool
',
'
e
' => '
extract:bool
'
])
+ [
'
force
' => false,
'
delete
' => false,
'
get
' => false,
'
extract
' => false
];
$WHAT = isset($args[0]) ? $args[0] : null;
$useCache = !$args['
force
'] && !$args['
get
'];
if (!$args['
get
'] && !$args['
extract
'] && !$args['
delete
']) {
$args['
get
'] = $args['
extract
'] = 1;
}
foreach ($SOURCES['
dependencies
'] as $package) {
if (!isset($package['
name
'])) {
$package['
name
'] = $package['
lib
'];
}
if ($WHAT && $package['
lib
'] !== $WHAT) {
continue;
}
if ($args['
delete
']) {
delete_destfile($package);
continue;
}
if ($args['
get
']) {
$srcfile = fetch_from_source($package, $useCache, $filetype);
}
else {
$srcfile = extract_filetype($package, $filetype);
}
if (!empty($package['
sha1
']) && ($sum = sha1_file($srcfile)) !== $package['
sha1
']) {
rcube::raise_error("Incorrect sha1 sum of $srcfile. Expected: {$package['
sha1
']}, got: $sum", false, true);
}
if ($args['
extract
']) {
echo "Installing {$package['
name
']}...\n";
if ($filetype === '
zip
'
)
{
extract_zipfile
(
$package
,
$srcfile
)
;
}
else
{
compose_destfile
(
$package
,
$srcfile
)
;
}
echo
"Done.\n"
;
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 12:00 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18725178
Default Alt Text
install-jsdeps.sh (13 KB)
Attached To
Mode
R113 roundcubemail
Attached
Detach File
Event Timeline