| #!/usr/bin/env python3 |
| """Swift Action Compiler |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You 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. |
| # |
| """ |
| |
| from __future__ import print_function |
| import os |
| import re |
| import sys |
| import codecs |
| import subprocess |
| from io import StringIO |
| |
| def eprint(*args, **kwargs): |
| print(*args, file=sys.stderr, **kwargs) |
| |
| def sources(launcher, source_dir, main): |
| actiondir = "%s/Sources" % source_dir |
| # copy the launcher fixing the main |
| dst = "%s/main.swift" % actiondir |
| with codecs.open(dst, 'a', 'utf-8') as d: |
| with codecs.open(launcher, 'r', 'utf-8') as e: |
| code = e.read() |
| code += "while let inputStr: String = readLine() {\n" |
| code += " let json = inputStr.data(using: .utf8, allowLossyConversion: true)!\n" |
| code += " let parsed = try JSONSerialization.jsonObject(with: json, options: []) as! [String: Any]\n" |
| code += " for (key, value) in parsed {\n" |
| code += " if key != \"value\" {\n" |
| code += " setenv(\"__OW_\\(key.uppercased())\",value as! String,1)\n" |
| code += " }\n" |
| code += " }\n" |
| code += " let jsonData = try JSONSerialization.data(withJSONObject: parsed[\"value\"] as Any, options: [])\n" |
| code += " _run_main(mainFunction: %s, json: jsonData)\n" % main |
| code += "} \n" |
| d.write(code) |
| |
| def swift_build(dir, buildcmd): |
| # compile... |
| env = { |
| "PATH": os.environ["PATH"] |
| } |
| p = subprocess.Popen(buildcmd, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE, |
| cwd=dir, |
| env=env) |
| (o, e) = p.communicate() |
| # stdout/stderr may be either text or bytes, depending on Python |
| # version, so if bytes, decode to text. Note that in Python 2 |
| # a string will match both types; so also skip decoding in that case |
| if isinstance(o, bytes) and not isinstance(o, str): |
| o = o.decode('utf-8') |
| if isinstance(e, bytes) and not isinstance(e, str): |
| e = e.decode('utf-8') |
| return p.returncode, o, e |
| |
| def build(source_dir, target_file, buildcmd): |
| r, o, e = swift_build(source_dir, buildcmd) |
| #if e: print(e) |
| #if o: print(o) |
| if r != 0: |
| print(e) |
| print(o) |
| print(r) |
| return |
| |
| bin_file = "%s/.build/release/Action" % source_dir |
| os.rename(bin_file, target_file) |
| if not os.path.isfile(target_file): |
| print("failed %s -> %s" % (bin_file, target_file)) |
| return |
| |
| |
| def main(argv): |
| if len(argv) < 4: |
| print("usage: <main-function> <source-dir> <target-dir>") |
| sys.exit(1) |
| |
| main = argv[1] |
| source_dir = os.path.abspath(argv[2]) |
| target = os.path.abspath("%s/exec" % argv[3]) |
| launch = os.path.abspath(argv[0]+".launcher.swift") |
| |
| src = "%s/exec" % source_dir |
| |
| #check if single source |
| if os.path.isfile(src): |
| actiondir = os.path.abspath("Sources") |
| if not os.path.isdir(actiondir): |
| os.makedirs(actiondir, mode=0o755) |
| dst = "%s/main.swift" % actiondir |
| os.rename(src, dst) |
| sources(launch, os.path.abspath("."), main) |
| build(os.path.abspath("."), target, ["./swiftbuildandlink.sh"]) |
| else: |
| actiondir = "%s/Sources" % source_dir |
| if not os.path.isdir(actiondir): |
| os.makedirs(actiondir, mode=0o755) |
| os.rename(os.path.abspath("Sources/_Whisk.swift"),"%s/Sources/_Whisk.swift" % source_dir) |
| sources(launch, source_dir, main) |
| build(source_dir, target, ["swift", "build", "-c", "release"]) |
| |
| if __name__ == '__main__': |
| main(sys.argv) |