Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2891204
phutil_mapper.php
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
5 KB
Referenced Files
None
Subscribers
None
phutil_mapper.php
View Options
#!/usr/bin/env php
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once
dirname
(
__FILE__
)
.
'/__init_script__.php'
;
if
(
$argc
!=
2
)
{
$self
=
basename
(
$argv
[
0
]
)
;
echo
"usage: {$self} <phutil_library_root>\n"
;
exit
(
1
)
;
}
phutil_require_module
(
'phutil'
,
'filesystem'
)
;
phutil_require_module
(
'phutil'
,
'filesystem/filefinder'
)
;
phutil_require_module
(
'phutil'
,
'future/exec'
)
;
$root
=
Filesystem
::
resolvePath
(
$argv
[
1
]
)
;
if
(
!
@
file_exists
(
$root
.
'/__phutil_library_init__.php'
)
)
{
throw
new
Exception
(
"Provided path is not a phutil library."
)
;
}
echo
"Finding phutil modules...\n"
;
$files
=
id
(
new
FileFinder
(
$root
)
)
->
withType
(
'f'
)
->
withSuffix
(
'php'
)
->
excludePath
(
'*/.*'
)
->
setGenerateChecksums
(
true
)
->
find
(
)
;
// NOTE: Sorting by filename ensures that hash computation is stable; it is
// important we sort by name instead of by hash because sorting by hash could
// create a bad cache hit if the user swaps the contents of two files.
ksort
(
$files
)
;
$modules
=
array
(
)
;
foreach
(
$files
as
$file
=>
$hash
)
{
if
(
dirname
(
$file
)
==
$root
)
{
continue
;
}
$modules
[
Filesystem
::
readablePath
(
dirname
(
$file
)
,
$root
)
]
[
]
=
$hash
;
}
echo
"Found "
.
count
(
$files
)
.
" files in "
.
count
(
$modules
)
.
" modules.\n"
;
$signatures
=
array
(
)
;
foreach
(
$modules
as
$module
=>
$hashes
)
{
$hashes
=
implode
(
' '
,
$hashes
)
;
$signature
=
md5
(
$hashes
)
;
$signatures
[
$module
]
=
$signature
;
}
try
{
$cache
=
Filesystem
::
readFile
(
$root
.
'/.phutil_module_cache'
)
;
}
catch
(
Exception
$ex
)
{
$cache
=
null
;
}
$signature_cache
=
array
(
)
;
if
(
$cache
)
{
$signature_cache
=
json_decode
(
$cache
,
true
)
;
if
(
!
is_array
(
$signature_cache
)
)
{
$signature_cache
=
array
(
)
;
}
}
$specs
=
array
(
)
;
$futures
=
array
(
)
;
foreach
(
$signatures
as
$module
=>
$signature
)
{
if
(
isset
(
$signature_cache
[
$module
]
)
&&
$signature_cache
[
$module
]
[
'signature'
]
==
$signature
)
{
$specs
[
$module
]
=
$signature_cache
[
$module
]
;
}
else
{
$futures
[
$module
]
=
new
ExecFuture
(
'%s %s'
,
dirname
(
__FILE__
)
.
'/phutil_analyzer.php'
,
$root
.
'/'
.
$module
)
;
}
}
if
(
$futures
)
{
echo
"Found "
.
count
(
$specs
)
.
" modules in cache; "
.
"analyzing "
.
count
(
$futures
)
.
" modified modules"
;
foreach
(
Futures
(
$futures
)
->
limit
(
8
)
as
$module
=>
$future
)
{
echo
"."
;
$specs
[
$module
]
=
array
(
'signature'
=>
$signatures
[
$module
]
,
'spec'
=>
$future
->
resolveJSON
(
)
,
)
;
}
echo
"\n"
;
}
else
{
echo
"All modules were found in cache.\n"
;
}
$class_map
=
array
(
)
;
$requires_class_map
=
array
(
)
;
$requires_interface_map
=
array
(
)
;
$function_map
=
array
(
)
;
foreach
(
$specs
as
$module
=>
$info
)
{
$spec
=
$info
[
'spec'
]
;
foreach
(
array
(
'class'
,
'interface'
)
as
$type
)
{
foreach
(
$spec
[
'declares'
]
[
$type
]
as
$class
=>
$where
)
{
if
(
!
empty
(
$class_map
[
$class
]
)
)
{
$prior
=
$class_map
[
$class
]
;
echo
"\n"
;
echo
"Error: definition of {$type} '{$class}' in module '{$module}' "
.
"duplicates prior definition in module '{$prior}'."
;
echo
"\n"
;
exit
(
1
)
;
}
$class_map
[
$class
]
=
$module
;
}
}
if
(
!
empty
(
$spec
[
'chain'
]
[
'class'
]
)
)
{
$requires_class_map
+=
$spec
[
'chain'
]
[
'class'
]
;
}
if
(
!
empty
(
$spec
[
'chain'
]
[
'interface'
]
)
)
{
$requires_interface_map
+=
$spec
[
'chain'
]
[
'interface'
]
;
}
foreach
(
$spec
[
'declares'
]
[
'function'
]
as
$function
=>
$where
)
{
if
(
!
empty
(
$function_map
[
$function
]
)
)
{
$prior
=
$function_map
[
$function
]
;
echo
"\n"
;
echo
"Error: definition of function '{$function}' in module '{$module}' "
.
"duplicates prior definition in module '{$prior}'."
;
echo
"\n"
;
exit
(
1
)
;
}
$function_map
[
$function
]
=
$module
;
}
}
echo
"\n"
;
ksort
(
$class_map
)
;
ksort
(
$requires_class_map
)
;
ksort
(
$requires_interface_map
)
;
ksort
(
$function_map
)
;
$library_map
=
array
(
'class'
=>
$class_map
,
'function'
=>
$function_map
,
'requires_class'
=>
$requires_class_map
,
'requires_interface'
=>
$requires_interface_map
,
)
;
$library_map
=
var_export
(
$library_map
,
$return_string
=
true
)
;
$library_map
=
preg_replace
(
'/\s+$/m'
,
''
,
$library_map
)
;
$library_map
=
preg_replace
(
'/array \(/'
,
'array('
,
$library_map
)
;
$at
=
'@'
;
$map_file
=
<<<EOPHP
<?php
/**
* This file is automatically generated. Use 'phutil_mapper.php' to rebuild it.
* {$at}generated
*/
phutil_register_library_map({$library_map});
EOPHP
;
echo
"Writing library map file...\n"
;
Filesystem
::
writeFile
(
$root
.
'/__phutil_library_map__.php'
,
$map_file
)
;
echo
"Writing module cache...\n"
;
Filesystem
::
writeFile
(
$root
.
'/.phutil_module_cache'
,
json_encode
(
$specs
)
)
;
echo
"Done.\n"
;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 19, 14:49 (3 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1125662
Default Alt Text
phutil_mapper.php (5 KB)
Attached To
Mode
rARC Arcanist
Attached
Detach File
Event Timeline
Log In to Comment