Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix building on Windows or with Python 3.12 #7

Merged
merged 5 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ python_compressed.js
/*compiler*.jar
/local_blockly_compressed_vertical.js
/chromedriver
# --flagfiles used on Windows
/*.config
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,27 @@

## Local development

Requires Node.js (`node`), Python (`python3`), and Java (`java`). It is known to work in these environments but should work in many others:

- Windows 10, Python 3.12.1 (Microsoft Store), Node.js 20.10.0 (nodejs.org installer), Java 11 (Temurin-11.0.21+9)
- macOS 14.2.1, Python 3.11.6 (Apple), Node.js 20.10.0 (installed manually), Java 21 (Temurin-21.0.1+12)
- Ubuntu 22.04, Python 3.10.12 (python3 package), Node.js 20.10.0 (installed manually), Java 11 (openjdk-11-jre package)

Install dependencies:

```sh
npm ci
```

The playground to use for local testing is tests/vertical_playground.html.
Open tests/vertical_playground.html in a browser for development. You don't need to rebuild compressed versions for most changes. Open tests/vertical_playground_compressed.html instead to test if the compressed versions built properly.

To build, run:
To re-build compressed versions, run:

```sh
npm run prepublish
```

requires Python (2 or 3). scratch-gui development server must be restarted to update linked scratch-blocks.
scratch-gui development server must be restarted to update linked scratch-blocks.

<!--
#### Scratch Blocks is a library for building creative computing interfaces.
Expand Down
83 changes: 47 additions & 36 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

import sys

import errno, glob, json, os, re, subprocess, threading, codecs, functools
import errno, glob, json, os, re, subprocess, threading, codecs, functools, platform

if sys.version_info[0] == 2:
import httplib
Expand Down Expand Up @@ -116,7 +116,7 @@ def run(self):
if (!isNodeJS) {
// Find name of current directory.
var scripts = document.getElementsByTagName('script');
var re = new RegExp('(.+)[\/]blockly_uncompressed(_vertical|_horizontal|)\.js$');
var re = new RegExp('(.+)[\\/]blockly_uncompressed(_vertical|_horizontal|)\\.js$');
for (var i = 0, script; script = scripts[i]; i++) {
var match = re.exec(script.src);
if (match) {
Expand Down Expand Up @@ -333,9 +333,21 @@ def do_compile_local(self, params, target_filename):
for group in [[CLOSURE_COMPILER_NPM], dash_args]:
args.extend(filter(lambda item: item, group))

# On Windows, the command line is too long, so we save the arguments to a file instead
use_flagfile = platform.system() == "Windows"
if platform.system() == "Windows":
flagfile_name = target_filename + ".config"
with open(flagfile_name, "w") as f:
# \ needs to be escaped still
f.write(" ".join(args[1:]).replace("\\", "\\\\"))
args = [CLOSURE_COMPILER_NPM, "--flagfile", flagfile_name]

proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
(stdout, stderr) = proc.communicate()

if use_flagfile:
os.remove(flagfile_name)

# Build the JSON response.
filesizes = [os.path.getsize(value) for (arg, value) in params if arg == "js_file"]
return dict(
Expand Down Expand Up @@ -439,12 +451,12 @@ def write_output(self, target_filename, remove, json_data):
# The Closure Compiler preserves these.
LICENSE = re.compile("""/\\*

[\w ]+
[\\w ]+

Copyright \\d+ Google Inc.
https://developers.google.com/blockly/

Licensed under the Apache License, Version 2.0 \(the "License"\);
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

Expand Down Expand Up @@ -583,28 +595,17 @@ def exclude_horizontal(item):

print("Using local compiler: %s ...\n" % CLOSURE_COMPILER_NPM)
except (ImportError, AssertionError):
print("Using remote compiler: closure-compiler.appspot.com ...\n")

try:
closure_dir = CLOSURE_DIR
closure_root = CLOSURE_ROOT
closure_library = CLOSURE_LIBRARY
closure_compiler = CLOSURE_COMPILER

calcdeps = import_path(os.path.join(
closure_root, closure_library, "closure", "bin", "calcdeps.py"))
except ImportError:
if os.path.isdir(os.path.join(os.path.pardir, "closure-library-read-only")):
# Dir got renamed when Closure moved from Google Code to GitHub in 2014.
print("Error: Closure directory needs to be renamed from"
"'closure-library-read-only' to 'closure-library'.\n"
"Please rename this directory.")
elif os.path.isdir(os.path.join(os.path.pardir, "google-closure-library")):
print("Error: Closure directory needs to be renamed from"
"'google-closure-library' to 'closure-library'.\n"
"Please rename this directory.")
else:
print("""Error: Closure not found. Read this:
if os.path.isdir(os.path.join(os.path.pardir, "closure-library-read-only")):
# Dir got renamed when Closure moved from Google Code to GitHub in 2014.
print("Error: Closure directory needs to be renamed from"
"'closure-library-read-only' to 'closure-library'.\n"
"Please rename this directory.")
elif os.path.isdir(os.path.join(os.path.pardir, "google-closure-library")):
print("Error: Closure directory needs to be renamed from"
"'google-closure-library' to 'closure-library'.\n"
"Please rename this directory.")
else:
print("""Error: Closure not found. Usually this means 'npm ci' failed. Try running it again? More resources:
developers.google.com/blockly/guides/modify/web/closure""")
sys.exit(1)

Expand All @@ -624,13 +625,23 @@ def exclude_horizontal(item):
# Run all tasks in parallel threads.
# Uncompressed is limited by processor speed.
# Compressed is limited by network and server speed.
# Vertical:
Gen_uncompressed(search_paths_vertical, True, closure_env).start()
# Horizontal:
Gen_uncompressed(search_paths_horizontal, False, closure_env).start()

# Compressed forms of vertical and horizontal.
Gen_compressed(search_paths_vertical, search_paths_horizontal, closure_env).start()

# This is run locally in a separate thread.
# Gen_langfiles().start()
threads = [
# Vertical:
Gen_uncompressed(search_paths_vertical, True, closure_env),
# Horizontal:
Gen_uncompressed(search_paths_horizontal, False, closure_env),
# Compressed forms of vertical and horizontal.
Gen_compressed(search_paths_vertical, search_paths_horizontal, closure_env),

# This is run locally in a separate thread.
# Gen_langfiles()
]

for thread in threads:
thread.start()

# Need to wait for all threads to finish before the main process ends as in Python 3.12,
# once the main interpreter is being shutdown, trying to spawn more child threads will
# raise "RuntimeError: can't create new thread at interpreter shutdown"
for thread in threads:
thread.join()