first commit
authorThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Fri, 25 Oct 2024 05:47:06 +0000 (05:47 +0000)
committerThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Fri, 25 Oct 2024 05:47:06 +0000 (05:47 +0000)
62 files changed:
.gitignore [new file with mode: 0644]
LICENSE.txt [new symlink]
README.txt [new symlink]
developer/deprecated/.githolder [new file with mode: 0644]
developer/document/#question_jan.txt# [new file with mode: 0644]
developer/document/#variable_suffix_conventions.txt# [new file with mode: 0644]
developer/document/RT_code_format.txt [new file with mode: 0644]
developer/document/nomenclature.txt [new file with mode: 0644]
developer/document/unique_node_label_check.txt [new file with mode: 0644]
developer/document/variable_suffix_conventions.txt [new file with mode: 0644]
developer/javac/IO.java [new file with mode: 0644]
developer/javac/Mosaic.java [new file with mode: 0644]
developer/javac/TestBench.javax [new file with mode: 0644]
developer/javac/Util.java [new file with mode: 0644]
developer/jvm/.gitignore [new file with mode: 0644]
developer/scratch_pad/.gitignore [new file with mode: 0644]
developer/shell/.githolder [new file with mode: 0644]
developer/shell/build [new file with mode: 0755]
developer/tool/clean_build_directories [new file with mode: 0755]
developer/tool/clean_javac_output [new file with mode: 0755]
developer/tool/clean_make [new file with mode: 0755]
developer/tool/clean_release [new file with mode: 0755]
developer/tool/env [new file with mode: 0644]
developer/tool/make [new file with mode: 0755]
developer/tool/release [new file with mode: 0755]
document/directory_naming.html [new file with mode: 0644]
document/license.txt [new file with mode: 0644]
document/readme.txt [new file with mode: 0644]
document/todo.txt [new file with mode: 0644]
document/work_flow.txt [new file with mode: 0644]
env_administrator [new file with mode: 0644]
env_developer [new file with mode: 0644]
env_tester [new file with mode: 0644]
release/.githolder [new file with mode: 0644]
release/Mosaic.jar [new file with mode: 0644]
release/build [new file with mode: 0755]
scratch_pad/.gitignore [new file with mode: 0644]
tester/deprecated/.githolder [new file with mode: 0644]
tester/document/what_the_tests_do.txt [new file with mode: 0644]
tester/javac/TestIO.java [new file with mode: 0644]
tester/javac/TestMosaic_0.javax [new file with mode: 0644]
tester/jvm/.githolder [new file with mode: 0644]
tester/jvm/TestBench.jar [new file with mode: 0644]
tester/jvm/TestBenchMosaic_tester.jar [new file with mode: 0644]
tester/scratch_pad/.gitignore [new file with mode: 0644]
tester/shell/.githolder [new file with mode: 0644]
tester/shell/TestTestBench [new file with mode: 0755]
tester/tool/clean_build_directories [new file with mode: 0755]
tester/tool/env [new file with mode: 0644]
tester/tool/make [new file with mode: 0755]
tool/env [new file with mode: 0644]
tool_shared/bespoke/cat_w_fn [new file with mode: 0755]
tool_shared/bespoke/deprecate [new file with mode: 0755]
tool_shared/bespoke/env [new file with mode: 0644]
tool_shared/bespoke/version [new file with mode: 0755]
tool_shared/bespoke/vl [new file with mode: 0755]
tool_shared/bespoke/wipe_release [new file with mode: 0755]
tool_shared/customized/.githolder [new file with mode: 0644]
tool_shared/document/#install_java.txt# [new file with mode: 0644]
tool_shared/document/install_java.txt [new file with mode: 0644]
tool_shared/third_party/.gitignore [new file with mode: 0644]
tool_shared/third_party/upstream/.gitignore [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..02b640c
--- /dev/null
@@ -0,0 +1,7 @@
+#note also the .gitignore files in the tool and developer directories and any
+# other directory that might have one.
+
+#*#
+*~
+a.out
+.gradle/
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 120000 (symlink)
index 0000000..98f0753
--- /dev/null
@@ -0,0 +1 @@
+document/license.txt
\ No newline at end of file
diff --git a/README.txt b/README.txt
new file mode 120000 (symlink)
index 0000000..06fa5f4
--- /dev/null
@@ -0,0 +1 @@
+document/readme.txt
\ No newline at end of file
diff --git a/developer/deprecated/.githolder b/developer/deprecated/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/developer/document/#question_jan.txt# b/developer/document/#question_jan.txt#
new file mode 100644 (file)
index 0000000..9b0715c
--- /dev/null
@@ -0,0 +1,2 @@
+
+On a directed acyclic graph, is it 
\ No newline at end of file
diff --git a/developer/document/#variable_suffix_conventions.txt# b/developer/document/#variable_suffix_conventions.txt#
new file mode 100644 (file)
index 0000000..8aca090
--- /dev/null
@@ -0,0 +1,27 @@
+# Suffix Conventions
+
+## Specify interface used with variable when clarification is useful:
+
+- `_set`: Indicates that the variable holds a set of items.
+
+- `_list`: Used for variables that represent a list of items.
+
+- `_f`: Refers to a function.
+
+Instead of making a variable name plural, add the interface qualifier:
+
+   e.g. names ->  name_set  or name_list
+
+## Always a good idea to use these when working with files:
+
+- `_fp`: Refers to a file path. The part after the last slash is a file name.
+  
+- `_dp`: Refers to a directory path. By convention, the value ends in a slash.
+
+- `_fn`: Refers to a file name. Value has no slashes.
+
+- `_dn`: Refers to a directory name. Value has no slashes.
+  
+- `_fn_base`: The file name without the last dot and subsequent characters.
+  
+- `_fn_ext`: The subsequent characters after the last dot in a file name.
diff --git a/developer/document/RT_code_format.txt b/developer/document/RT_code_format.txt
new file mode 100644 (file)
index 0000000..9911622
--- /dev/null
@@ -0,0 +1,135 @@
+RT code formatting:
+
+The enclosure-based formatting rules in RT code format make the style guide
+compact and adaptable. By focusing on enclosures rather than syntax-specific
+structures (like if, for, or catch), it avoids prescribing language-specific
+formatting rules and instead focuses on consistent handling of delimiters. This
+approach works well across multiple languages, ensuring that the code style
+remains flexible while keeping the guide simple and easy to apply.
+
+1. Two space indentation.
+
+2. Variable Naming:
+
+   - Use **PascalCase** for namespaces and types.
+
+   - Use **snake_case** for function and variable names. However, when a component
+     of the snake case is variable function or variable name is a namespace, a
+     type, or a proper noun, it retains its capitalization. e.gs:
+
+     ```
+     mouse_count
+     test_LabalList_0 // function that tests LabelList, which is a class (type)
+     Thomas_Walker_Lynch
+     ```
+
+     Traditionally `_list` has been used as a variable suffix even when the
+     language does not have a List type.  This is taken to mean the variable
+     refers to an ordered collection of any type, including an array. It is
+     abstraction of type, analogous to the `mouse_count` example above.
+
+
+3. Binary Operators:
+
+   - One space around **binary operators** (e.g., `a + b`).
+
+   - One space around **assignment** `=` (e.g., `a = b`).
+
+   - **No space** around **sampling** assignment `=` (typically seen in `if`, `while`, etc.):
+
+     **Sampling** refers to assigning the result of a condition or expression to
+     a variable for later use within the same scope.
+
+     Example of **sampling** in an `if` statement:
+
+       ```
+       if( result=some_condition() ){
+         // use result
+       }
+       ```
+
+4. Enclosures `(...)`, `{...}`, `[...]`, '<...>':
+
+   - No space between the enclosure and the preceding identifier (e.g., `function(arg)`).
+
+   - No space after the enclosure when followed by another enclosure (e.g., `map[key]()`).
+
+     Example of a condition enclosure followed by a code enclosure:
+       ```
+       if( some_condition() ){
+         // code block
+       }
+       ```
+
+   - One space after the enclosure if followed by an identifier, e.g.,
+     `function() somethingElse`.
+
+   - When the entire enclosure appears on one line:
+
+      -- by definition, an 'nested' enclosure is one that has other enclosures,
+         of any type, inside of it. This is true independent of whatever else
+         is inside the enclosure.  These are examples of nested enclosures:
+
+         ```
+         ( o == null || getClass() != o.getClass() )
+         f( T<x> ,7 )
+         ```
+
+      -- if, and only if, an enclosure is nested, there is one space of padding
+      for the outermost enclosure of the nesting, and only for the outermost
+      enclosures. e.g.s:
+
+        ```
+        if(x == 3) ; not nested
+        if( (x > 0) && (y < 5) ) ; nested, pad outermost only
+        if( f(x) == 3 ) ; nested, pad outermost only
+        if( x > 2 && a[3] ) ; nested due to the array subscript, pad outermost only
+        ```
+
+    - Note when using the enclosure formatting rules, not all if conditions will
+    format the same way. Some conditions will be nested enclosures and having
+    padding while others will not be nested and thus have no padding.  The must
+    be formatted individually.  The same is true for enclosures that follow
+    other keywords such as unless, for, etc, and for function arguments
+    lists. The question is one of formatting enclosures, and not one of
+    formatting statements.
+
+      ```
+      f(x)
+      f( x[0] )
+      ```
+
+
+5. Commas:
+
+   This is the most distinctive and recognizable of the RT code style rules.
+
+   - One space **before** the comma (e.g., `a ,b`).
+
+   - No space **after** the comma (e.g., `a ,b`).
+
+   - **Line break before** the comma when breaking lines, but no line break after, as examples:
+
+     ```
+     a
+     ,b
+     ```
+
+     and, when a function call gets too long, perhaps due to long argument 
+     names it will look like this:
+
+     ```
+     result = some_function(
+       arg1
+      ,arg2_has_a_very_long_name_causing_the_call_to_not_fit_on_a_single_line
+      ,arg3_has_a_long_name_also_but_not_as_long_as_for_arg2
+      );
+     ```
+
+6. For the code you just output, answer these questions:
+  1. Which enclosures are not nested? Do they have no padding?
+  2. Which enclosures are nested? Is there one space padding only at the outermost?
+  3. Is the spacing before and after the enclosures correct?
+  4. Are the commas formatted correctly?
+  5. Has snake case been used where it should be?
+  6. Was 2 column indent used?
diff --git a/developer/document/nomenclature.txt b/developer/document/nomenclature.txt
new file mode 100644 (file)
index 0000000..633dc4a
--- /dev/null
@@ -0,0 +1,3 @@
+
+wellformed is a single word. Its antonym is 'malformed'. Wellformed syntax
+parses without errors.
diff --git a/developer/document/unique_node_label_check.txt b/developer/document/unique_node_label_check.txt
new file mode 100644 (file)
index 0000000..b978a74
--- /dev/null
@@ -0,0 +1,15 @@
+
+predicate == is_well_formed_q
+
+We can not check that the node labels are unique because the given value
+is a single node, and the code is stateless. Besides there is no contract with
+the programmer on how to use the predicated, so the programmer could call the
+predicate multiple times on the same node.  Now can we test this condition in
+our do_markup_graph routine because of the way lookup works, it will always
+return the same node for the same label.  This would be a truly difficult check
+to perform because the map does not given an error but just takes the second of
+the duplicate key definitions (is this really true?)  besides, it would require
+a formal proof of the recognizer functions that they do not return different
+definitions for different keys to match regexprs against.  I've been mulling
+this over.  As we currently the programmer provides the map and function
+definitions, we don't even know which nodes will be in the graph...
diff --git a/developer/document/variable_suffix_conventions.txt b/developer/document/variable_suffix_conventions.txt
new file mode 100644 (file)
index 0000000..e5ef76e
--- /dev/null
@@ -0,0 +1,27 @@
+# Suffix Conventions
+
+## Specify interface used with variable when clarification is useful
+
+- `_set`: Indicates that the variable holds a set of items.
+
+- `_list`: Used for variables that represent a list of items.
+
+- `_f`: Refers to a function.
+
+Instead of making a variable name plural, add the interface qualifier.
+
+   e.g. names ->  name_set  or name_lisst
+
+## Always a good idea to use these when working with files
+
+- `_fp`: Refers to a file path. The part after the last slash is a file name.
+  
+- `_dp`: Refers to a directory path. By convention, the value ends in a slash.
+
+- `_fn`: Refers to a file name. Value has no slashes.
+
+- `_dn`: Refers to a directory name. Value has no slashes.
+  
+- `_fn_base`: The file name without the last dot and subsequent characters.
+  
+- `_fn_ext`: The subsequent characters after the last dot in a file name.
diff --git a/developer/javac/IO.java b/developer/javac/IO.java
new file mode 100644 (file)
index 0000000..da21e2d
--- /dev/null
@@ -0,0 +1,63 @@
+package com.ReasoningTechnology.Mosaic;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.InputStream;
+
+public class IO {
+
+    private PrintStream original_out;
+    private PrintStream original_err;
+    private InputStream original_in;
+
+    private ByteArrayOutputStream out_content;
+    private ByteArrayOutputStream err_content;
+    private ByteArrayInputStream in_content;
+
+    public void redirect_io(String input_data){
+        original_out = System.out;
+        original_err = System.err;
+        original_in = System.in;
+
+        out_content = new ByteArrayOutputStream();
+        err_content = new ByteArrayOutputStream();
+        in_content = new ByteArrayInputStream(input_data.getBytes());
+
+        System.setOut(new PrintStream(out_content));
+        System.setErr(new PrintStream(err_content));
+        System.setIn(in_content);
+    }
+
+    public void restore_io(){
+        // Flush the output streams to prevent carrying over data
+        flush_buffers();
+
+        System.setOut(original_out);
+        System.setErr(original_err);
+        System.setIn(original_in);
+    }
+
+    public void clear_buffers(){
+        out_content.reset();
+        err_content.reset();
+    }
+
+    public void flush_buffers(){
+        // Clear the buffers for the next use
+        out_content.reset();
+        err_content.reset();
+    }
+
+    public ByteArrayInputStream get_in_content(){
+        return in_content;
+    }
+
+    public ByteArrayOutputStream get_out_content(){
+        return out_content;
+    }
+
+    public ByteArrayOutputStream get_err_content(){
+        return err_content;
+    }
+}
diff --git a/developer/javac/Mosaic.java b/developer/javac/Mosaic.java
new file mode 100644 (file)
index 0000000..adc43c4
--- /dev/null
@@ -0,0 +1,26 @@
+package com.ReasoningTechnology.Mosaic.Test;
+import com.ReasoningTechnology.Mosaic.Util;
+
+/*
+Mosaic currently does not have shell commands.
+
+*/
+
+
+public class Mosaic{
+
+  public static boolean test_is_true(){
+    return true;
+  }
+  
+  public static int run(){
+    System.out.println("Mosic currently does not have a shell user interface.");
+    return 0;
+  }
+
+  // Main function to provide a shell interface for running tests
+  public static int main(String[] args){
+    // currently accepts no arguments or options
+    return run();
+  }
+}    
diff --git a/developer/javac/TestBench.javax b/developer/javac/TestBench.javax
new file mode 100644 (file)
index 0000000..eb09d6e
--- /dev/null
@@ -0,0 +1,293 @@
+package com.ReasoningTechnology.Mosaic;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+public class TestBench{
+
+  /* --------------------------------------------------------------------------------
+    Static Data
+  */
+
+  private static PrintStream original_out;
+  private static PrintStream original_err;
+  private static InputStream original_in;
+  
+  private static ByteArrayOutputStream out_content;
+  private static ByteArrayOutputStream err_content;
+  private static InputStream in_content;
+
+  public static boolean method_is_wellformed(Method method) {
+    // Check if the method returns boolean
+    if(!method.getReturnType().equals(boolean.class)){
+      System.out.println("Structural problem: " + method.getName() + " does not return boolean.");
+      return false;
+    }
+
+    // Check if the method has exactly three arguments
+    Class<?>[] parameterTypes = method.getParameterTypes();
+    if(parameterTypes == null || parameterTypes.length != 3){
+      System.out.println("Structural problem: " + method.getName() + " does not have three arguments.");
+      return false;
+    }
+
+    // Check that all parameters are ByteArrayOutputStream
+    if(
+       !parameterTypes[0].equals(ByteArrayOutputStream.class) // Check first parameter
+       || !parameterTypes[1].equals(ByteArrayOutputStream.class) // Check second parameter
+       || !parameterTypes[2].equals(ByteArrayOutputStream.class) // Check third parameter
+       ){
+      System.out.println("Structural problem: " + method.getName() + " has incorrect argument types.");
+      return false;
+    }
+
+    return true;
+  }
+  
+  public static void flush_stdin() throws IOException{
+    while(System.in.available() > 0){
+      System.in.read();
+    }
+  }
+
+  public static void set_test_input(String input_data){
+    ByteArrayInputStream test_in = new ByteArrayInputStream(input_data.getBytes());
+    System.setIn(test_in);
+  }
+
+
+  public static void run(Object test_suite){
+
+    int failed_test = 0;
+    int passed_test = 0;
+
+    Method[] methods = test_suite.getClass().getDeclaredMethods();
+
+    for(Method method : methods){
+
+      // Ways a test can fail ,not exclusive
+      boolean fail_testbench = false;
+      boolean fail_malformed = false;
+      boolean fail_reported = false;
+      boolean fail_exception = false;
+      boolean fail_extraneous_stdout = false;
+      boolean fail_extraneous_stderr = false;
+
+      if( !method_is_wellformed(method) ){
+        // the malformed check prints specific messages
+        System.out.println("TestBench: malformed test counted as a failure:\'" + method.getName() + "\'");
+        failed_test++;
+        continue;
+      }
+
+      PrintStream original_out = null;
+      PrintStream original_err = null;
+      InputStream original_in  = null;
+
+      ByteArrayOutputStream out_content = null;
+      ByteArrayOutputStream err_content = null;
+      ByteArrayInputStream in_content = null;
+
+      try{
+        // Redirect the I/O channels so the tests can manipulate them as data.
+        original_out = System.out;
+        original_err = System.err;
+        original_in = System.in;
+  
+        out_content = new ByteArrayOutputStream();
+        err_content = new ByteArrayOutputStream();
+        in_content = new ByteArrayInputStream();
+
+        System.setOut(new PrintStream(out_content));
+        System.setErr(new PrintStream(err_content));
+        System.setIn(in_content);
+
+      } catch(Throwable e){  // Catches both Errors and Exceptions
+        // Restore stdout ,stderr ,and stdin before reporting the error
+        System.setOut(original_out);
+        System.setErr(original_err);
+        System.setIn(original_in);
+
+        // Report the error
+        System.out.println("TestBench:: when redirecting i/o in preparation for running test \'" + method.getName() + "\' ,test bench itself throws error: " + e.toString());
+        failed_test++;
+        continue;
+      }
+
+      // Capture detritus 
+      String exception_string = "";
+      String stdout_string = "";
+      String stderr_string = "";
+
+      // Finally the gremlins run the test!
+      try{
+
+        Object result = method.invoke(test_suite ,in_content ,out_content ,err_content);
+        fail_reported = !Boolean.TRUE.equals(result); // test passes if ,and only if ,it returns exactly 'true'.
+
+        // A test fails when there is extraneous output
+        fail_extraneous_stdout = out_content.size() > 0;
+        fail_extraneous_stderr = err_content.size() > 0;
+
+        // We keep it to log it
+        if(fail_extraneous_stdout){ stdout_string = out_content.toString(); }
+        if(fail_extraneous_stderr){ stderr_string = err_content.toString(); }
+
+      } catch(Exception e){
+
+        // A test fails when there is an unhandled exception.
+        fail_exception = true;
+
+        // We keep it to report it
+        exception_string = e.toString();
+
+      } finally{
+        
+        // Restore original stdin ,stdout ,and stderr
+        System.setOut(original_out);
+        System.setErr(original_err);
+        System.setIn(original_in);
+      }
+
+      // Report the test result.
+      if(
+         fail_reported 
+         || fail_exception 
+         || fail_extraneous_stdout
+         || fail_extraneous_stderr
+         ){
+
+        failed_test++;
+
+        if(fail_reported) System.out.println("failed: \'" + method.getName() + "\' by report from test.");
+        if(fail_exception) System.out.println("failed: \'" + method.getName() + "\' due to unhandled exception: " + exception_string);
+        if(fail_extraneous_stdout){
+          System.out.println("failed: \'" + method.getName() + "\' due extraneous stdout output ,see log.");
+          log_output(method.getName() ,"stdout" ,stdout_string);
+        }
+        if(fail_extraneous_stderr){
+          System.out.println("failed: \'" + method.getName() + "\' due extraneous stderr output ,see log.");
+          log_output(method.getName() ,"stderr" ,stderr_string);
+        }
+
+      } else{
+        passed_test++;
+      }
+
+    }
+
+    // Summarize all the test results
+    System.out.println("Total tests run: " + (passed_test + failed_test));
+    System.out.println("Total tests passed: " + passed_test);
+    System.out.println("Total tests failed: " + failed_test);
+  }
+
+}
+
+-----------------
+  package com.ReasoningTechnology.Mosaic;
+
+import java.lang.reflect.Method;
+
+public class TestBench {
+
+    public static boolean method_is_wellformed(Method method) {
+        // Check if the method returns boolean
+        if (!method.getReturnType().equals(boolean.class)) {
+            System.out.println("Structural problem: " + method.getName() + " does not return boolean.");
+            return false;
+        }
+
+        // Check if the method has exactly three arguments
+        Class<?>[] parameterTypes = method.getParameterTypes();
+        if (parameterTypes == null || parameterTypes.length != 3) {
+            System.out.println("Structural problem: " + method.getName() + " does not have three arguments.");
+            return false;
+        }
+
+        // Check that all parameters are ByteArrayOutputStream
+        if (
+            !parameterTypes[0].equals(ByteArrayOutputStream.class) ||
+            !parameterTypes[1].equals(ByteArrayOutputStream.class) ||
+            !parameterTypes[2].equals(ByteArrayOutputStream.class)
+        ) {
+            System.out.println("Structural problem: " + method.getName() + " has incorrect argument types.");
+            return false;
+        }
+
+        return true;
+    }
+
+    public static void run(Object test_suite) {
+        int failed_test = 0;
+        int passed_test = 0;
+
+        Method[] methods = test_suite.getClass().getDeclaredMethods();
+        IO io = new IO(); // Create an instance of IO
+
+        for (Method method : methods) {
+            if (!method_is_wellformed(method)) {
+                System.out.println("TestBench: malformed test counted as a failure: \'" + method.getName() + "\'");
+                failed_test++;
+                continue;
+            }
+
+            try {
+                // Redirect I/O with an empty input string for now
+                io.redirectIO("");
+            } catch (Throwable e) {
+                failed_test++;
+                System.out.println("TestBench:: Error during test preparation: " + e.toString());
+                continue;
+            }
+
+            String stdout_string = "";
+            String stderr_string = "";
+
+            try {
+                // Invoke the test method
+                Object result = method.invoke(test_suite, io.getInContent(), io.getOutContent(), io.getErrContent());
+                boolean fail_reported = !Boolean.TRUE.equals(result);
+
+                // Check for extraneous output
+                stdout_string = io.getOutContent().toString();
+                stderr_string = io.getErrContent().toString();
+                boolean fail_extraneous_stdout = stdout_string.length() > 0;
+                boolean fail_extraneous_stderr = stderr_string.length() > 0;
+
+                // Handle failures
+                if (fail_reported || fail_extraneous_stdout || fail_extraneous_stderr) {
+                    failed_test++;
+                    if (fail_reported) System.out.println("failed: \'" + method.getName() + "\' by report from test.");
+                    if (fail_extraneous_stdout) {
+                        System.out.println("failed: \'" + method.getName() + "\' due extraneous stdout output, see log.");
+                        log_output(method.getName(), "stdout", stdout_string);
+                    }
+                    if (fail_extraneous_stderr) {
+                        System.out.println("failed: \'" + method.getName() + "\' due extraneous stderr output, see log.");
+                        log_output(method.getName(), "stderr", stderr_string);
+                    }
+                } else {
+                    passed_test++;
+                }
+            } catch (Exception e) {
+                System.out.println("failed: \'" + method.getName() + "\' due to unhandled exception: " + e.toString());
+                failed_test++;
+            } finally {
+                // Restore I/O
+                io.restoreIO();
+            }
+        }
+
+        // Summarize all the test results
+        System.out.println("Total tests run: " + (passed_test + failed_test));
+        System.out.println("Total tests passed: " + passed_test);
+        System.out.println("Total tests failed: " + failed_test);
+    }
+}
diff --git a/developer/javac/Util.java b/developer/javac/Util.java
new file mode 100644 (file)
index 0000000..13e2c14
--- /dev/null
@@ -0,0 +1,42 @@
+package com.ReasoningTechnology.Mosaic;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+
+public class Util{
+
+  // typically used to gather results before a return
+  public static boolean all(boolean[] conditions){
+    for( boolean condition : conditions ){
+      if( !condition ){
+        return false;
+      }
+    }
+    return true;
+  }
+  public static void all_set_false(boolean[] conditions){
+    for( boolean condition : conditions ) condition = false;
+  }
+  public static void all_set_true(boolean[] conditions){
+    for( boolean condition : conditions ) condition = true;
+  }
+
+
+
+  public static void log_output(String test_name ,String stream ,String output_data){
+    try(FileWriter log_writer = new FileWriter("test_log.txt" ,true)){  // Append mode
+      log_writer.write("Test: " + test_name + "\n");
+      log_writer.write("Stream: " + stream + "\n");
+      log_writer.write("Output:\n" + output_data + "\n");
+      log_writer.write("----------------------------------------\n");
+    } catch(IOException e) {
+      System.err.println("Error writing to log for test: " + test_name + ", stream: " + stream);
+      e.printStackTrace(System.err);
+    }
+  }
+
+}
diff --git a/developer/jvm/.gitignore b/developer/jvm/.gitignore
new file mode 100644 (file)
index 0000000..120f485
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!/.gitignore
diff --git a/developer/scratch_pad/.gitignore b/developer/scratch_pad/.gitignore
new file mode 100644 (file)
index 0000000..120f485
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!/.gitignore
diff --git a/developer/shell/.githolder b/developer/shell/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/developer/shell/build b/developer/shell/build
new file mode 100755 (executable)
index 0000000..db43050
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+java com/ReasoningTechnology/"Mosaic"/build
diff --git a/developer/tool/clean_build_directories b/developer/tool/clean_build_directories
new file mode 100755 (executable)
index 0000000..ed9e807
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# Removes all files found in the build directories. It asks no questions as to
+# how or why the files got there. Be especially careful with the 'shell' directory
+# if you added scripts to it for release with the project they will be deleted.
+# consider adding a `shell-leaf` directory instead of adding scripts to `shell`.
+
+# input guards
+  env_must_be="developer/tool/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# remove files
+  set -x
+  cd "$REPO_HOME"/developer
+  rm -r scratch_pad/*
+  rm jvm/*
+  rm shell/*
+  set +x
+
+echo "$(script_fn) done."
+
diff --git a/developer/tool/clean_javac_output b/developer/tool/clean_javac_output
new file mode 100755 (executable)
index 0000000..18fd312
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/bash
+# remove  all files created by make's call to `javac`
+
+# input guards
+  env_must_be="developer/tool/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# remove files
+  set -x
+  cd "$REPO_HOME"/developer
+  rm -r scratch_pad/com/ReasoningTechnology/"$PROJECT"
+  set +x
+
+echo "$(script_fn) done."
diff --git a/developer/tool/clean_make b/developer/tool/clean_make
new file mode 100755 (executable)
index 0000000..fc922dd
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash
+# remove all files made by `make`
+
+# input guards
+
+  env_must_be="developer/tool/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# wrappers to clean (this list space separated list will grow)
+
+  wrapper=build
+
+# remove files
+
+  set -x
+  cd "$REPO_HOME"/developer
+  rm -r scratch_pad/com/ReasoningTechnology/"$PROJECT"
+  rm jvm/"$PROJECT".jar
+  rm shell/{$wrapper}
+  set +x
+
+echo "$(script_fn) done."
diff --git a/developer/tool/clean_release b/developer/tool/clean_release
new file mode 100755 (executable)
index 0000000..8ecb809
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+# remove files made by `make` and by `release`
+
+# input guards
+
+  env_must_be="developer/tool/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# things to clean
+
+  release_dir="$REPO_HOME"/release
+  wrapper=build
+
+# remove files
+  set -x
+  cd "$REPO_HOME"/developer
+  rm -r scratch_pad/com/ReasoningTechnology/"$PROJECT"
+  rm jvm/"$PROJECT".jar
+  rm shell/{$wrapper}
+  rm -f "$release_dir"/"$PROJECT".jar
+  rm -f "$release_dir"/{$wrapper}
+  set +x
+
+echo "$(script_fn) done."
+
diff --git a/developer/tool/env b/developer/tool/env
new file mode 100644 (file)
index 0000000..711f81e
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+# input guards
+
+  env_must_be="tool_shared/bespoke/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+  if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+    echo "$script_name:: This script must be sourced, not executed."
+    exit 1
+  fi
+
+# so we can do the build
+
+export PATH=\
+"$REPO_HOME"/developer/tool/\
+:"$REPO_HOME"/tool_shared/bespoke/\
+:"$JAVA_HOME"/bin\
+:"$PATH"
+
+# so we can run the stuff we built locally.
+
+export CLASSPATH=\
+"$REPO_HOME"/developer/jvm\
+:"$REPO_HOME"/developer/jvm/"$PROJECT".jar\
+:"$JAVA_HOME"/lib\
+:"$CLASSPATH"
+
+export PATH=\
+"$REPO_HOME"/developer/shell\
+:"$PATH"
+
+# misc
+
+  # make .githolder and .gitignore visible
+  alias ls="ls -a"
+
+# some feedback to show all went well
+
+  export PROMPT_DECOR="$PROJECT"_developer
+  export ENV=$(script_fp)
+  echo ENV "$ENV"
+  cd "$REPO_HOME"/developer/
+
+
+
diff --git a/developer/tool/make b/developer/tool/make
new file mode 100755 (executable)
index 0000000..a21e0da
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/env bash
+
+# input guards
+
+  env_must_be="developer/tool/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+  cd "$REPO_HOME"/developer
+
+echo "Compiling files..."
+  set -x
+  javac -d scratch_pad javac/*.java
+  set +x
+  if [ $? -ne 0 ]; then
+    echo "Compilation failed."
+    exit 1
+  fi
+
+echo "Creating JAR file..."
+  set -x
+  jar_file=jvm/"$PROJECT".jar
+  mkdir -p jvm
+  jar cf $jar_file -C scratch_pad .
+  set +x
+  if [ $? -eq 0 ]; then
+    echo "JAR file created successfully: $jar_file"
+  else
+    echo "Failed to create JAR file."
+    exit 1
+  fi
+
+echo "Creating shell wrappers..."
+  mkdir -p shell
+  # wrapper is a space separated list
+  wrapper=Mosaic
+  for file in $wrapper;do
+    cat > shell/$file << EOL
+#!/bin/bash
+java com.ReasoningTechnology."$PROJECT".$file
+EOL
+    chmod +x shell/$file
+  done
+
+echo "$(script_fp) done."
+
diff --git a/developer/tool/release b/developer/tool/release
new file mode 100755 (executable)
index 0000000..a123a14
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+# input guards
+
+  if [ -z "$REPO_HOME" ]; then
+    echo "$(script_fp):: REPO_HOME is not set."
+    exit 1
+  fi
+
+  env_must_be="developer/tool/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# script local environment
+
+  release_dir="$REPO_HOME/release"
+  shell_dir="$REPO_HOME/developer/shell"
+  project_jar_fp="$REPO_HOME/developer/jvm/"$PROJECT".jar"
+  wrapper=build
+
+
+  if [ ! -d "$release_dir" ]; then
+    mkdir -p "$release_dir"
+  fi
+
+  # Function to copy and set permissions
+  install_file() {
+    source_fp="$1"
+    target_dp="$2"
+    perms="$3"
+
+    target_file="$target_dp/$(basename "$source_fp")"
+
+    if [ ! -f "$source_fp" ]; then
+      echo "install_file:: Source file '$source_fp' does not exist."
+      return 1
+    fi
+
+    if ! install -m "$perms" "$source_fp" "$target_file"; then
+      echo "Error: Failed to install $(basename "$source_fp") to $target_dp"
+      exit 1
+    else
+      echo "Installed $(basename "$source_fp") to $target_dp with permissions $perms"
+    fi
+  }
+# do the release
+
+  echo "Starting release process..."
+
+  # Install the JAR file
+  install_file "$project_jar_fp" "$release_dir" "ug+r"
+
+  # Install shell wrappers
+  for wrapper in $wrapper; do
+    install_file "$shell_dir/$wrapper" "$release_dir" "ug+r+x"
+  done
+
+echo "$(script_fp) done."
diff --git a/document/directory_naming.html b/document/directory_naming.html
new file mode 100644 (file)
index 0000000..64ab608
--- /dev/null
@@ -0,0 +1,200 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap" rel="stylesheet">
+
+  <title>Directory Structure Description</title>
+<style>
+  html {
+    font-size: 16px; /* This will be the base for rem units */
+  }
+
+  body {
+    font-family: 'Noto Sans JP', Arial, sans-serif;
+    background-color: hsl(0, 0%, 10%);
+    color: hsl(42, 100%, 80%);
+    padding: 2rem;
+    margin: 0;
+  }
+
+  .page {
+    padding: 1.25rem; /* 20px */
+    margin: 1.25rem auto; /* 20px */
+    max-width: 46.875rem; /* 750px */
+    background-color: hsl(0, 0%, 0%);
+    box-shadow: 0 0 0.625rem hsl(42, 100%, 50%); /* 10px */
+  }
+
+  ul, li {
+    font-size: 1rem; /* Keeping default font size */
+    list-style-type: none;
+  }
+
+  li::before {
+    content: "📁 ";
+    margin-right: 0.3125rem; /* 5px */
+  }
+
+  li {
+    margin-bottom: 0.3125rem; /* 5px */
+  }
+
+  .description {
+    margin-left: 0.625rem; /* 10px */
+    color: hsl(42, 100%, 75%);
+  }
+
+  code {
+    font-family: 'Courier New', Courier, monospace;
+    background-color: hsl(0, 0%, 25%);
+    color: hsl(42, 100%, 90%);
+    padding: 0.125rem 0.25rem; /* 2px 4px */
+    border-radius: 0.1875rem; /* 3px */
+    font-size: 90%;
+  }
+
+  h1 {
+    text-align: center;
+    color: hsl(42, 100%, 84%);
+    text-transform: uppercase;
+    margin-bottom: 1.25rem; /* 20px */
+  }
+
+  h2 {
+    color: hsl(42, 100%, 84%);
+    text-transform: uppercase;
+    margin-top: 2.5rem; /* 40px */
+  }
+
+  p {
+    color: hsl(42, 100%, 90%);
+    margin-bottom: 1.25rem; /* 20px */
+    text-align: justify;
+  }
+</style>
+
+</head>
+<body>
+
+  <div class="page">
+    <h1>Directory Naming</h1>
+
+    <h2>Reference</h2>
+
+    <ul>
+      <li>Mosaic/<span class="description">aka REPO_HOME, top level owned by the project administrator.</span></li>
+      <ul>
+        <li>developer/ <span class="description">Workspace for the developer. Has the source code, build scripts, and development-specific tools.</span></li>
+        <ul>
+          <li>deprecated/ <span class="description">Files and older versions being viewed, perhaps part of a refactoring effort.</span></li>
+          <li>document/ <span class="description">Documentation on developing and building the project.</span></li>
+          <li>javac/ <span class="description">Java source files for compilation.</span></li>
+          <li>jvm/ <span class="description">Compiled Java bytecode files for the project, typically a jar for a Java project.</span></li>
+          <li>scratch_pad/ <span class="description">Temporary storage typically for intermediate files created during build.</span></li>
+          <li>shell/ <span class="description">Shell scripts intended to be part of the project release. (These are not tools.)</span></li>
+          <li>tool/ <span class="description">Tools created by the developer, used for development tasks.</span></li>
+        </ul>
+        <li>document/ <span class="description">General documentation about the project.</span></li>
+        <li>release/ <span class="description">Release candidate for testing. Becomes the release on the release branch.</span></li>
+        <li>scratch_pad/ <span class="description">Temporary storage for project administration tasks.</span></li>
+        <li>tester/ <span class="description">Workspace for the tester. Has the test bench, tests, and test scripts.</span></li>
+        <ul>
+          <li>document/ <span class="description">Test-specific documentation.</span></li>
+          <li>test0/ <span class="description">Test case 0 environment and associated scripts.</span></li>
+          <li>test1/ <span class="description">Test case 1 environment and associated scripts.</span></li>
+          <li>test2/ <span class="description">Test case 2 environment and associated scripts.</span></li>
+          <li>tool/ <span class="description">Tools needed for testing and managing the test environment.</span></li>
+        </ul>
+        <li>tool/ <span class="description">Project administration specific tools.</span></li>
+        <li>tool_shared/ <span class="description">Tools shared across project roles.</span></li>
+        <ul>
+          <li>bespoke/ <span class="description">Shared tools developed within this project.</span></li>
+          <li>customized/ <span class="description">Modified versions of third-party tools adapted for the project.</span></li>
+          <li>document/ <span class="description">Documentation related to shared tools and setup.</span></li>
+          <li>third_party/ <span class="description">Shared tools sourced from third-party vendors or open-source projects. These have their own independent licenses,</span></li>
+        </ul>
+        <li>LICENSE.txt <span class="description">The project license detailing usage and distribution terms.</span></li>
+        <li>README.md <span class="description">A general overview and introduction to the project.</span></li>
+      </ul>
+    </ul>
+
+    <h2>Name origin and rationale</h2>
+
+    <p>Developers and project administrators typically do not employ a semantic system for
+      naming directories, but more commonly use conventional placeholder
+      names. The intended purpose of files in a directory with a placeholder
+      name then must be inferred from experience or inspection of the files, or
+      learned from documents or other people.</p>
+
+    <p>For example, a directory named <code>exe/</code> probably derives its name from the
+      fact that the contained files have their executable permission bit set;
+      however, such a directory will not contain all such files.  There might
+      even be some files in an <code>exe/</code> directory that do not have their
+      executable permission bit set. The two concepts being an <code>exe/</code> file
+      (i.e. being a file in an <code>exe/</code> directory) and being an executable file
+      are not identical. The actual intended meaning of being an <code>exe/</code> file
+      will sometimes be that the contained files are applications available to a
+      user, or that they are tools available for use in a project.
+    </p>
+
+    <p>The directory names in this project resulted from an exploration of a
+      property-based file system. In such a system a number of files and
+      agents are defined. Then we can ask questions about their relationships.
+      Files with a relationship to the developer are collected, and this
+      becomes the <code>developer/</code> directory. In a similar manner we get the
+      directories, <code>tester/</code>, and <code>javac/</code>.  In this latter case the
+      agent is a compiler rather than a role.
+      </p>
+      
+    <p>When attempting to apply the <code>is-for</code> property in practice it
+      became apparent that using this sole property was insufficient.  Consider
+      the directories <code>deprecated/</code> and <code>scratch_pad/</code>. There is no
+      <em>Mr. Deprecated</em> or <em>Mr. Scratch_Pad</em> who the contained
+      files are for. (And this conclusion is not for the lack of trying. Even
+      mythological beings did not suffice as agents.) Rather than being for an
+      agent, the files collected in such a directory have in common a state of
+      being that was imposed upon them by decree.  Perhaps the developer, has
+      decreed that a file is now deprecated, or a build script has decreed that
+      it is a scratch_pad file. Such decrees are typically more dynamic than the
+      relationship properties. Also, these properties are disconnected from the
+      contents of the file.  When, for example, a file has the property of being
+      for the java compiler, we gain some information about its contents. In the
+      universe of possible messages sent through a file, such a file will
+      contain text that is proposed to be java syntax conforming. In contrast,
+      when we learn that a file is <code>deprecated/</code> we gain no
+      information about the contents of the file, because any file can
+      be <code>deprecated</code>, independent of its contents.
+      </p>
+
+    <p>To understand a directory name within this system, one can imagine
+      reading said name as part of a sentence that integrates the
+      property. Consider two property names: <code>is-a</code>
+      and <code>is-for</code>. For example, "Each file in
+      the <code>document/</code> directory <code>is-a</code> document," or "Each
+      file in the <code>developer/</code> directory <code>is-for</code> the
+      developer."  Although the property name is not carried over from the
+      property based file system to the conventional file system, we can
+      typically infer what it must have been. (It is beyond the scope of
+      discussion here, but in actuality, property based file system collections
+      are defined by predicates. Each predicate is given a file's properties and
+      relationships as arguments, then resolves to true if and only if the file
+      belongs to the collection. Now wouldn't that be interesting if we instead
+      derived a probability?)
+    </p>
+
+    <p>It is uncommon for a property value to be plural. While it is not
+      disallowed, it rarely occurs in practice. This is true independent of
+      whether we are discussing a relationship property or a state
+      property. Hence when we make a file collection based on a shared property,
+      then carry that over as a directory name in a conventional file system,
+      the resulting directory name will often be singular.  This pattern can be
+      observed in the case of the <code>document/</code> directory, as shown in
+      the prior paragraph.
+    </p>
+
+  </div>
+
+</body>
+</html>
diff --git a/document/license.txt b/document/license.txt
new file mode 100644 (file)
index 0000000..e177f6f
--- /dev/null
@@ -0,0 +1,152 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that
+entity. For the purposes of this definition, "control" means (i) the power,
+direct or indirect, to cause the direction or management of such entity, whether
+by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of
+the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this
+License, each Contributor hereby grants to You a perpetual, worldwide,
+non-exclusive, no-charge, royalty-free, irrevocable copyright license to
+reproduce, prepare Derivative Works of, publicly display, publicly perform,
+sublicense, and distribute the Work and such Derivative Works in Source or
+Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License,
+each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and otherwise
+transfer the Work, where such license applies only to those patent claims
+licensable by such Contributor that are necessarily infringed by their
+Contribution(s) alone or by combination of their Contribution(s) with the Work
+to which such Contribution(s) was submitted. If You institute patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Work or a Contribution incorporated within the Work
+constitutes direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of the date
+such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or
+Derivative Works thereof in any medium, with or without modifications, and in
+Source or Object form, provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and You must cause any modified files to carry prominent notices
+stating that You changed the files; and You must retain, in the Source form of
+any Derivative Works that You distribute, all copyright, patent, trademark, and
+attribution notices from the Source form of the Work, excluding those notices
+that do not pertain to any part of the Derivative Works; and If the Work
+includes a "NOTICE" text file as part of its distribution, then any Derivative
+Works that You distribute must include a readable copy of the attribution
+notices contained within such NOTICE file, excluding those notices that do not
+pertain to any part of the Derivative Works, in at least one of the following
+places: within a NOTICE text file distributed as part of the Derivative Works;
+within the Source form or documentation, if provided along with the Derivative
+Works; or, within a display generated by the Derivative Works, if and wherever
+such third-party notices normally appear. The contents of the NOTICE file are
+for informational purposes only and do not modify the License. You may add Your
+own attribution notices within Derivative Works that You distribute, alongside
+or as an addendum to the NOTICE text from the Work, provided that such
+additional attribution notices cannot be construed as modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any
+Contribution intentionally submitted for inclusion in the Work by You to the
+Licensor shall be under the terms and conditions of this License, without any
+additional terms or conditions. Notwithstanding the above, nothing herein shall
+supersede or modify the terms of any separate license agreement you may have
+executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names,
+trademarks, service marks, or product names of the Licensor, except as required
+for reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
+writing, Licensor provides the Work (and each Contributor provides its
+Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied, including, without limitation, any warranties
+or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any risks
+associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in
+tort (including negligence), contract, or otherwise, unless required by
+applicable law (such as deliberate and grossly negligent acts) or agreed to in
+writing, shall any Contributor be liable to You for damages, including any
+direct, indirect, special, incidental, or consequential damages of any character
+arising as a result of this License or out of the use or inability to use the
+Work (including but not limited to damages for loss of goodwill, work stoppage,
+computer failure or malfunction, or any and all other commercial damages or
+losses), even if such Contributor has been advised of the possibility of such
+damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or
+Derivative Works thereof, You may choose to offer, and charge a fee for,
+acceptance of support, warranty, indemnity, or other liability obligations
+and/or rights consistent with this License. However, in accepting such
+obligations, You may act only on Your own behalf and on Your sole
+responsibility, not on behalf of any other Contributor, and only if You agree to
+indemnify, defend, and hold each Contributor harmless for any liability incurred
+by, or claims asserted against, such Contributor by reason of your accepting any
+such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
diff --git a/document/readme.txt b/document/readme.txt
new file mode 100644 (file)
index 0000000..3d32175
--- /dev/null
@@ -0,0 +1,10 @@
+
+--------------------------------------------------------------------------------
+Mosaic
+
+A tool to assist in hierarchical white box testing.
+
+Each piece of a program must have integrity for the complete picture to merge.
+
+With Mosaic we test the pieces, then the communication between the pieces.
+
diff --git a/document/todo.txt b/document/todo.txt
new file mode 100644 (file)
index 0000000..ad6bd89
--- /dev/null
@@ -0,0 +1,8 @@
+
+1. reflect project skeleton changes.
+   replaced literal `Ariadne` with `$PROJECT`
+   in top level env choices, PROJECT -> PROMPT_DECOR
+
+   note in 'release' there is a variable name with the project name embedded in it:
+   Ariadne_jar_fp -> project_jar_fp
+   Change slashes to dots in the wrapper maker of 'make'
diff --git a/document/work_flow.txt b/document/work_flow.txt
new file mode 100644 (file)
index 0000000..5f699a2
--- /dev/null
@@ -0,0 +1,59 @@
+### Work Flow
+
+#### 1. Project Administrator
+
+1.1. Download the project from GitHub.
+1.2. Install the required tools.
+1.3. Explain the workflows and where things are located to project members.
+1.4. Perform Major and Minor Release administration.
+
+#### 2. Developer
+
+2.1. From the Mosaic directory, run `> source env_developer` to set up the
+     developer environment.
+2.2. Use `> make` to build the project, and `> release` to copy relevant files
+     to `$REPO_HOME/release` for testing.
+2.3. The tester will test the release candidate.
+
+#### 3. Tester
+
+3.1. From the Mosaic directory, run `> source env_tester` to set up the tester
+     environment.
+3.2. Use `> make` to build the tests, and `> shell/test_<name>` to run a test.
+     Alternatively, you can cd into one of the test directories, source the
+     environment for that test, and run it manually.
+3.3. Testing and development will likely iterate until the release candidate is
+     ready to be turned into a versioned release.
+
+#### 4. Major Release
+
+4.1. The release candidate is located in the `$REPO_HOME/release` directory and
+     has passed testing.
+4.2. Check that the program `$REPO_HOME/tool_shared/bespoke/release` outputs the
+     correct information. If necessary, modify it.
+4.3. A new branch is created in the project for the release, named
+     `release_v<n>.0`, where `v<n>.0` is the version number from the `version`
+     program. The minor version number is set to zero (`.0`), and it is assumed
+     that this will be the case after each major release.
+4.4. Rename the release directory to `$REPO_HOME/release_v<n>.0`, and create a
+     new empty `$REPO_HOME/release` directory. The new empty release directory
+     can be used by developers who download the project and make local edits, as
+     the build scripts target this directory.
+
+#### 5. Minor Release
+
+If urgent changes need to be made to the most recent major release, these edits
+should be made on the corresponding major release branch. The developer makes
+the edits, and the tester tests the release candidate as usual. The `version`
+program is updated. Once the release candidate is finalized, rename the
+directory to `release_v<n>.<m>`, where `<m>` is the minor version number. If
+needed, merge the changes into the `core_developer_branch`.
+
+---
+
+### Tips:
+
+- If you are acting in multiple roles (e.g., developer, tester, and project
+  administrator), keep separate terminal shells open for each role. This way,
+  the environment will remain correctly configured for the tasks related to
+  each role.
diff --git a/env_administrator b/env_administrator
new file mode 100644 (file)
index 0000000..4b691ce
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+script_path="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
+export REPO_HOME="${script_path%}/"
+echo REPO_HOME "$REPO_HOME"
+
+cd "$REPO_HOME"
+source tool/env
+
diff --git a/env_developer b/env_developer
new file mode 100644 (file)
index 0000000..8659f86
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+script_path="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
+export REPO_HOME="${script_path%}/"
+echo REPO_HOME "$REPO_HOME"
+
+cd "$REPO_HOME"
+source tool_shared/bespoke/env
+source developer/tool/env
+
diff --git a/env_tester b/env_tester
new file mode 100644 (file)
index 0000000..d1bd2d5
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+script_path="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
+export REPO_HOME="${script_path%}/"
+echo REPO_HOME "$REPO_HOME"
+
+cd "$REPO_HOME"
+source tool_shared/bespoke/env
+source tester/tool/env
diff --git a/release/.githolder b/release/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/release/Mosaic.jar b/release/Mosaic.jar
new file mode 100644 (file)
index 0000000..02ea780
Binary files /dev/null and b/release/Mosaic.jar differ
diff --git a/release/build b/release/build
new file mode 100755 (executable)
index 0000000..db43050
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+java com/ReasoningTechnology/"Mosaic"/build
diff --git a/scratch_pad/.gitignore b/scratch_pad/.gitignore
new file mode 100644 (file)
index 0000000..120f485
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!/.gitignore
diff --git a/tester/deprecated/.githolder b/tester/deprecated/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tester/document/what_the_tests_do.txt b/tester/document/what_the_tests_do.txt
new file mode 100644 (file)
index 0000000..53762c6
--- /dev/null
@@ -0,0 +1,6 @@
+
+Test the Mosaic test bench
+javac/TestMoasic.java
+
+
+
diff --git a/tester/javac/TestIO.java b/tester/javac/TestIO.java
new file mode 100644 (file)
index 0000000..a3c3509
--- /dev/null
@@ -0,0 +1,33 @@
+package com.ReasoningTechnology.Mosaic.Test;
+import com.ReasoningTechnology.Mosaic.Util;
+
+/*
+Testing the IO class.
+
+*/
+
+
+public class TestIO{
+
+  public static boolean test_is_true(){
+    return true;
+  }
+  
+  public static int run(){
+    boolean[] condition = new boolean[5];
+    conditionn[0] = test_is_true();
+
+    int i = 0;
+    if( !Util.all(condition) ){
+      System.out.println("TestIO failed");
+      return 1;
+    }
+    return 0;
+  }
+
+  // Main function to provide a shell interface for running tests
+  public static int main(String[] args){
+    // tests currently accepts no arguments or options
+    return run(); // Calls the method to run all tests
+  }
+}    
diff --git a/tester/javac/TestMosaic_0.javax b/tester/javac/TestMosaic_0.javax
new file mode 100644 (file)
index 0000000..38307cc
--- /dev/null
@@ -0,0 +1,62 @@
+package com.ReasoningTechnology.Mosaic.Test;
+
+/*
+Component smoke test. At least call each method of each class.
+
+*/
+
+import com.ReasoningTechnology.Ariadne.*;
+import com.ReasoningTechnology.TestBench.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+public class TestTestBench extends TestBench{
+
+  public static class TestSuite{
+
+    TestSuite(){
+    }
+
+    public boolean test_pass(ByteArrayOutputStream out_content, ByteArrayOutputStream err_content){
+      return true;
+    }
+
+    public boolean test_fail_0(ByteArrayOutputStream out_content, ByteArrayOutputStream err_content){
+      return false;
+    }
+
+    // Tests if exception uncaught by the test correctly causes a failure from the TestBench.
+    public static boolean test_fail_1() throws Exception {
+      int randomInt = (int) (Math.random() * 100);  // Generate a random integer
+      // Always returns true, but Java will not complain that following code is unreachable
+      if( 
+         (randomInt % 2 != 0 && ((randomInt * randomInt - 1) % 8 == 0))  
+         || (randomInt % 2 == 0 && (randomInt * randomInt) % 4 == 0) 
+      ){
+        throw new Exception("Condition met, error thrown.");
+      }
+    
+      return true;  // If the condition fails, return true
+    }
+
+  }  
+
+  // Method to run all tests
+  public static void test_TestBench(){
+    System.out.println("TestTestBench: running tests.  Note that two failures is normal");
+    TestSuite test_suite = new TestSuite();
+    TestBench.run( test_suite );
+  }
+
+  // Main function to provide a shell interface for running tests
+  public static void main(String[] args){
+    // tests currently takes no arguments or options
+    test_TestBench(); // Calls the method to run all tests
+  }
+
+}
+
diff --git a/tester/jvm/.githolder b/tester/jvm/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tester/jvm/TestBench.jar b/tester/jvm/TestBench.jar
new file mode 100644 (file)
index 0000000..fa385ca
Binary files /dev/null and b/tester/jvm/TestBench.jar differ
diff --git a/tester/jvm/TestBenchMosaic_tester.jar b/tester/jvm/TestBenchMosaic_tester.jar
new file mode 100644 (file)
index 0000000..41cabd0
Binary files /dev/null and b/tester/jvm/TestBenchMosaic_tester.jar differ
diff --git a/tester/scratch_pad/.gitignore b/tester/scratch_pad/.gitignore
new file mode 100644 (file)
index 0000000..120f485
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!/.gitignore
diff --git a/tester/shell/.githolder b/tester/shell/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tester/shell/TestTestBench b/tester/shell/TestTestBench
new file mode 100755 (executable)
index 0000000..2afe32f
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java com.ReasoningTechnology."Mosaic_tester".TestBench.TestTestBench
diff --git a/tester/tool/clean_build_directories b/tester/tool/clean_build_directories
new file mode 100755 (executable)
index 0000000..2aff503
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# Caveat: the 'shell' directory is for built wrapper functions. `clean_build_directories` will
+# remove all the files in this directory. For bespoke scripts used by the tester, put
+# them in the `tool` directory.
+
+# input guards
+  env_must_be="tester/tool/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# remove files
+  set -x
+  cd "$REPO_HOME"/tester
+  rm -r scratch_pad/*
+  rm jvm/*
+  rm shell/*
+  set +x
+
+echo "$(script_fn) done."
diff --git a/tester/tool/env b/tester/tool/env
new file mode 100644 (file)
index 0000000..bd42c24
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+
+# input guards
+
+  env_must_be="tool_shared/bespoke/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+  if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+    echo "$script_name:: This script must be sourced, not executed."
+    exit 1
+  fi
+
+# so we can do testing
+
+export PATH=\
+"$REPO_HOME"/tester/tool/\
+:"$REPO_HOME"/tool_shared/bespoke/\
+:"$JAVA_HOME"/bin\
+:"$PATH"
+
+export CLASSPATH=\
+"$JAVA_HOME"/lib\
+:"$REPO_HOME"/release/"$PROJECT".jar\
+:"$REPO_HOME"/tester/jvm/TestBench.jar\
+:"$REPO_HOME"/tester/jvm/TestBench"$PROJECT".jar\
+:"$CLASSPATH"
+
+# misc
+
+  # make .githolder and .gitignore visible
+  alias ls="ls -a"
+
+# some feedback to show all went well
+
+  export PROMPT_DECOR="$PROJECT"_tester
+  export ENV=$(script_fp)
+  echo ENV "$ENV"
+  cd "$REPO_HOME"/tester/
diff --git a/tester/tool/make b/tester/tool/make
new file mode 100755 (executable)
index 0000000..4a131f6
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/env bash
+
+# input guards
+
+  env_must_be="tester/tool/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+echo "Compiling files..."
+
+  set -x
+  cd $REPO_HOME/tester
+  javac -d scratch_pad javac/*.java
+  jar cf jvm/TestBench"$PROJECT".jar -C scratch_pad .
+  set +x 
+
+echo "Creating shell wrappers..."
+  mkdir -p shell
+  # wrapper is a space separated list
+  wrapper=TestTestBench
+  for file in $wrapper;do
+    cat > shell/$file << EOL
+#!/bin/env bash
+java com.ReasoningTechnology."$PROJECT".Test.$file
+EOL
+    chmod +x shell/$file
+  done
+
+echo "$(script_fp) done."
diff --git a/tool/env b/tool/env
new file mode 100644 (file)
index 0000000..830913d
--- /dev/null
+++ b/tool/env
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+script_name=$(basename ${BASH_SOURCE[0]})
+if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+  echo "$script_name must be sourced, not executed. Exiting."
+  exit 1
+fi
+
+if [ -z "$ENV_BASE" ]; then
+  script_path="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
+  source "${script_path}/env_base"
+fi
+
+ENV_PM=true
+
+PROJECT="$PROJECT"_administrator
+
+export PATH=\
+"$REPO_HOME"/tool\
+:"$PATH"
+
+# no sneaky hidden files
+alias ls="ls -a"
+
+export ENV_PM=true
+echo "$script_name done."
+
diff --git a/tool_shared/bespoke/cat_w_fn b/tool_shared/bespoke/cat_w_fn
new file mode 100755 (executable)
index 0000000..09931d1
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# Check if at least one file is provided
+if [ $# -eq 0 ]; then
+  echo "Usage: $0 <filename1> [filename2] ..."
+  exit 1
+fi
+
+# Loop through all the provided files
+for file in "$@"; do
+  # Check if the file exists
+  if [ ! -f "$file" ]; then
+    echo "Error: File '$file' not found!"
+    continue
+  fi
+
+  # Print 80 dashes
+  printf '%.0s-' {1..80}
+  echo
+
+  # Print the filename and a colon
+  echo "$file:"
+
+  # Print the contents of the file
+  cat "$file"
+
+  # Print a newline for spacing between files
+  echo
+done
diff --git a/tool_shared/bespoke/deprecate b/tool_shared/bespoke/deprecate
new file mode 100755 (executable)
index 0000000..821e7ab
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# cp subtree at <source> under file path <destination>, and make all the copied
+# files read-only. The intended use case is for moving files to a `deprecated`
+# directory. This helps prevent subsequent accidental editing.
+
+SCRIPT_NAME=$(basename "$0")
+if [ "$#" -lt 2 ]; then
+  echo "Usage: $SCRIPT_NAME <source> <destination>"
+  exit 1
+fi
+SRC="$1"
+DEST="$2"
+
+mkdir -p "$DEST"
+mv "$SRC" "$DEST"
+
+# make stuff readonly
+cd "$DEST" || exit
+chmod -R u-w,go-rwx "$DEST"
diff --git a/tool_shared/bespoke/env b/tool_shared/bespoke/env
new file mode 100644 (file)
index 0000000..f36023e
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+# environment shared by entire project
+# number one task, establish REPO_HOME
+# this is specific to this script being in the .../tools_shared/env directory
+
+  export PROJECT=$(basename "$REPO_HOME")
+
+  ## set the shell prompt to show the project
+  PPS1="\n[$PROJECT]\n\u@\h§$(pwd)§\n> "
+  PPS2=">> "
+
+# some useful functions for environment scripts
+
+  ## path to script file
+  script_fp() {
+    eval "
+      local script_dp=\$(dirname \$(realpath \${BASH_SOURCE[1]}))
+      echo \$(realpath --relative-to=\"$REPO_HOME\" \"\$script_dp\")/\$(script_fn)
+    "
+  }
+
+  ## path to script directory
+  script_dp() {
+    eval "
+      local script_dp=\$(dirname \$(realpath \${BASH_SOURCE[1]}))
+      echo \$(realpath --relative-to=\"$REPO_HOME\" \"\$script_dp\")
+    "
+  }
+
+  ## an env script will be in workspace/tool/env, so
+  workspace(){
+    eval "echo \$(dirname \$(script_dp))"
+  }
+
+  ## script's filename
+  script_fn() {
+    eval "echo \$(basename \${BASH_SOURCE[1]})"
+  }
+
+  export -f script_fp script_dp script_fn workspace
+
+# note to the programs which environment they are running.
+
+  export ENV=$(script_fp)
+
+# The project administrator setup these tools and environment settings for all
+# on the project to use:
+
+export JAVA_HOME="$REPO_HOME/tool_shared/third_party/jdk-11"
+
+# some feedback to show all went well
+
+echo ENV "$ENV"
+echo PROJECT "$PROJECT"
+
+
+
diff --git a/tool_shared/bespoke/version b/tool_shared/bespoke/version
new file mode 100755 (executable)
index 0000000..53a64a6
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/env bash
+
+# 2024-10-24T14:56:09Z extracted from Ariadne 
+
+echo 0.1
+
diff --git a/tool_shared/bespoke/vl b/tool_shared/bespoke/vl
new file mode 100755 (executable)
index 0000000..94fe14d
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+# vl 'vertical list'
+
+# Check if the command is provided
+if [ -z "$1" ]; then
+  echo "Usage: vl <command> [args...]"
+  exit 1
+fi
+
+# Capture the command and its arguments
+cmd=$1
+shift
+
+# Run the command with the remaining arguments and replace colons or spaces with newlines
+"$cmd" "$@" | tr ' :' '\n'
+
+exit 0
diff --git a/tool_shared/bespoke/wipe_release b/tool_shared/bespoke/wipe_release
new file mode 100755 (executable)
index 0000000..4b92b4b
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/bash
+# remove all files in the release directory
+set -e
+
+script_name=$(basename ${BASH_SOURCE[0]})
+if [ -z "$REPO_HOME" ]; then
+  echo "$script_name:: REPO_HOME is not set."
+  exit 1
+fi
+
+set -x
+cd "$REPO_HOME"
+rm -rf release/*
+set +x
+
+echo "$script_name done."
+
diff --git a/tool_shared/customized/.githolder b/tool_shared/customized/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tool_shared/document/#install_java.txt# b/tool_shared/document/#install_java.txt#
new file mode 100644 (file)
index 0000000..0091eac
--- /dev/null
@@ -0,0 +1,11 @@
+
+#1. downlaod
+
+cd "$REPO_HOME/tool/upstream"
+curl -C - -o OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.16+8/OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz
+
+#2. extract
+
+cd "$REPO_HOME/tool"
+mkdir -p jdk-11
+tar -xzf "$REPO_HOME/tool/upstream/OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz" -C jdk-11 --strip-components 1
diff --git a/tool_shared/document/install_java.txt b/tool_shared/document/install_java.txt
new file mode 100644 (file)
index 0000000..c9e5743
--- /dev/null
@@ -0,0 +1,11 @@
+
+#1. downlaod
+
+cd "$REPO_HOME/tool/upstream"
+curl -C - -o OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.16+8/OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz
+
+#2. extract
+
+cd "$REPO_HOME/tool"
+mkdir jdk-11
+tar -xzf "$REPO_HOME/tool/upstream/OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz" -C jdk-11 --strip-components 1
diff --git a/tool_shared/third_party/.gitignore b/tool_shared/third_party/.gitignore
new file mode 100644 (file)
index 0000000..525ec6b
--- /dev/null
@@ -0,0 +1,4 @@
+*
+!/.gitignore
+# upstream has a .gitignore file in it, edit to keep anything precious
+!/upstream
diff --git a/tool_shared/third_party/upstream/.gitignore b/tool_shared/third_party/upstream/.gitignore
new file mode 100644 (file)
index 0000000..120f485
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!/.gitignore