Utils for auto-file-discovery

This patch creates horizon.utils.file-discovery module which provides
functionalities for automatic file-discovery.  With these infrastructural
helpers, we can build JavaScript and HTML file auto-discovery for horizon
align with th existing plug-in mechanism.

1) discover_files(base_path, sub_path='', ext='', trim_base_path=False):
   Discover all files with certain extension in given paths

2) sort_js_files(js_files):
   Sorts JavaScript files in `js_files` into source files, mock files
   and spec files based on file extension.

   Output:
   * sources: source files for production.  The order of source files
     is significant and should be listed in the below order:
     - First all the files that defines application's angular module.
       Those files have extension of `.module.js`.  The order among them
       is not significant.
     - Followed by all other source code files.  The order among them
       is not significant.

   * mocks: mock files provide mock data/services for tests.  They have
     extension of `.mock.js`. The order among them is not significant.

   * specs: spec files for testing.  They have extension of `.spec.js`.
     The order among them is not significant.

3) discover_static_files(base_path, sub_path=''):
   Discover static files in given paths, returns JavaScript sources,
   mocks, specs and HTML templates files grouped in lists.

Partially-Implements: blueprint auto-js-file-finding
Change-Id: Idd0b69451f81b2f740b10515e3e274d48b681dbe
This commit is contained in:
Shaoquan Chen 2015-05-14 17:18:50 -07:00
parent 1611cba86f
commit 018b39b84a

View File

@ -0,0 +1,108 @@
# 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.
import logging
from os import path
from os import walk
LOG = logging.getLogger(__name__)
MODULE_EXT = '.module.js'
MOCK_EXT = '.mock.js'
SPEC_EXT = '.spec.js'
def discover_files(base_path, sub_path='', ext='', trim_base_path=False):
"""Discovers all files with certain extension in given paths.
"""
file_list = []
for root, dirs, files in walk(path.join(base_path, sub_path)):
if trim_base_path:
root = root.replace(base_path, '', 1)
file_list.extend([path.join(root, file_name)
for file_name in files
if file_name.endswith(ext)])
return file_list
def sort_js_files(js_files):
"""Sorts JavaScript files in `js_files` into source files, mock files
and spec files based on file extension.
Output:
* sources: source files for production. The order of source files
is significant and should be listed in the below order:
- First, all the that defines the other application's angular module.
Those files have extension of `.module.js`. The order among them is
not significant.
- Followed by all other source code files. The order among them
is not significant.
* mocks: mock files provide mock data/services for tests. They have
extension of `.mock.js`. The order among them is not significant.
* specs: spec files for testing. They have extension of `.spec.js`.
The order among them is not significant.
"""
modules = [f for f in js_files if f.endswith(MODULE_EXT)]
mocks = [f for f in js_files if f.endswith(MOCK_EXT)]
specs = [f for f in js_files if f.endswith(SPEC_EXT)]
other_sources = [f for f in js_files if
not f.endswith(MODULE_EXT)
and not f.endswith(MOCK_EXT)
and not f.endswith(SPEC_EXT)]
sources = modules + other_sources
return sources, mocks, specs
def discover_static_files(base_path, sub_path=''):
"""Discovers static files in given paths, returning JavaScript sources,
mocks, specs and HTML templates, all grouped in lists.
"""
js_files = discover_files(base_path, sub_path=sub_path,
ext='.js', trim_base_path=True)
sources, mocks, specs = sort_js_files(js_files)
html_files = discover_files(base_path, sub_path=sub_path,
ext='.html', trim_base_path=True)
p = path.join(base_path, sub_path)
_log(sources, 'JavaScript source', p)
_log(mocks, 'JavaScript mock', p)
_log(specs, 'JavaScript spec', p)
_log(html_files, 'HTML template', p)
return sources, mocks, specs, html_files
def populate_horizon_config(horizon_config, base_path,
sub_path='', prepend=False):
sources, mocks, specs, template = discover_static_files(
base_path, sub_path=sub_path)
if prepend:
horizon_config.setdefault('js_files', [])[:0] = sources
horizon_config.setdefault('js_spec_files', [])[:0] = mocks + specs
horizon_config.setdefault('external_templates', [])[:0] = template
else:
horizon_config.setdefault('js_files', []).extend(sources)
horizon_config.setdefault('js_spec_files', []).extend(mocks + specs)
horizon_config.setdefault('external_templates', []).extend(template)
def _log(file_list, list_name, in_path):
"""Logs result at debug level
"""
file_names = '\n'.join(file_list)
LOG.debug("\nDiscovered {0} {1} file(s) in {2}:\n{3}\n"
.format(len(file_list), list_name, in_path, file_names))