blob: 2297a7ce822c12288a0248dec93f564309816c6e [file] [log] [blame]
#!/usr/bin/env python
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
import os
import subprocess
import util
from simplebuild import *
class GetFileInfoRule(SimpleAsyncRule):
"""
Rule which synchronizes the state of external file.
"""
def __init__(self, path):
self.path = str(path)
def run(self):
util.note("getting file info: %r" % (self.path,))
return util.get_stat_info(self.path)
def is_data_valid(self, engine, data):
# Check if the current info is up-to-date.
util.note("checking file info: %r" % (self.path,))
return util.get_stat_info(self.path) == data
class GetDirectoryContentsRule(SimpleAsyncRule):
def __init__(self, path):
self.path = path
def start(self, engine):
# Get the file info for the directory, to ensure we treat the external
# directory as an input.
engine.task_needs_input(self, GetFileInfoRule.asKey(self.path))
def provide_data(self, engine, input_id, data):
pass
def run(self):
util.note("listing directory contents: %r" % (str(self.path),))
try:
return sorted(os.listdir(self.path))
except OSError:
return []
class SpawnJobRule(SimpleAsyncRule):
def __init__(self, args, input_files, output_files, other_inputs=()):
self.args = list(args)
self.input_files = list(input_files)
self.output_files = list(output_files)
def start(self, engine):
# Request all of the inputs.
for path in self.input_files:
engine.task_needs_input(self, GetFileInfoRule.asKey(path))
def provide_data(self, engine, input_id, data):
pass
def run(self):
try:
util.message(' '.join(self.args))
subprocess.check_call(self.args)
except:
import traceback
traceback.print_exc()
util.error("error: command failed: %s" % (' '.join(self.args),))
return { "error" : True }
# Get the file info on all of the output files.
output_infos = [util.get_stat_info(path)
for path in self.output_files]
return { "output_info" : output_infos }
class CountSourceLinesRule(SimpleAsyncRule):
get_dir_input_ID = 0
source_count_input_ID = 1
def __init__(self, path):
super(CountSourceLinesRule, self).__init__()
self.path = str(path)
self.output_paths = None
self.result = None
def start(self, engine):
engine.task_needs_input(self, GetDirectoryContentsRule.asKey(self.path),
self.get_dir_input_ID)
def provide_data(self, engine, input_id, data):
# If this is the directory result, scan it and request individual
# counts.
if input_id == 0:
self.output_paths = []
for input in data:
if input.endswith(".c"):
input_path = os.path.join(self.path, input)
output_path = os.path.join(self.path, input + ".wc")
self.output_paths.append(output_path)
cmd = ['/bin/sh', '-c', "wc -l < %s > %s" % (input_path,
output_path)]
engine.task_needs_input(
self, SpawnJobRule.asKey(cmd, [input_path],
[output_path]),
self.source_count_input_ID)
return
def run(self):
# Gather all the results.
self.result = 0
for path in self.output_paths:
with open(path) as f:
self.result += int(f.read())
return self.result
# Get the input path.
_,path = sys.argv
# Run the job
engine = DataDrivenEngine(globals())
engine.attach_db(".count-source-lines-with-wc.db")
result = engine.build(CountSourceLinesRule.asKey(path))
print result