From 334fc4a318ea2863e4857a111311e898489333fc Mon Sep 17 00:00:00 2001 From: Gabor Loki Date: Fri, 13 Jan 2017 11:58:58 +0100 Subject: [PATCH] Restructure docs folder. (#596) The final goal is to combine different guides and documentation scattered various places to a common one. This commit does the followings: - create new folders to introduce some logic here - copy the Wiki pages to the repository - update the links and references in the MD files. - do quick typo fixes IoT.js-DCO-1.0-Signed-off-by: Gabor Loki loki@inf.u-szeged.hu --- docs/README.md | 18 ++ docs/{ => api}/IoT.js-API-ADC.md | 2 +- docs/{ => api}/IoT.js-API-Assert.md | 0 docs/{ => api}/IoT.js-API-Buffer.md | 0 docs/{ => api}/IoT.js-API-DGRAM.md | 0 docs/{ => api}/IoT.js-API-DNS.md | 0 docs/{ => api}/IoT.js-API-Events.md | 0 docs/{ => api}/IoT.js-API-File-System.md | 0 docs/{ => api}/IoT.js-API-GPIO.md | 0 docs/{ => api}/IoT.js-API-HTTP.md | 0 docs/{ => api}/IoT.js-API-I2C.md | 0 docs/{ => api}/IoT.js-API-Module.md | 0 docs/{ => api}/IoT.js-API-Net.md | 0 docs/{ => api}/IoT.js-API-PWM.md | 2 +- docs/{ => api}/IoT.js-API-Process.md | 0 docs/{ => api}/IoT.js-API-Stream.md | 0 docs/{ => api}/IoT.js-API-Timers.md | 0 docs/{ => api}/IoT.js-API-UART.md | 0 docs/{ => api}/IoT.js-API-reference.md | 0 docs/build/Build-Script.md | 244 +++++++++++++++ docs/{ => build}/Build-for-Linux.md | 4 +- docs/{ => build}/Build-for-NuttX.md | 4 +- docs/{ => build}/Build-for-RPi2.md | 0 docs/devs/Inside-IoT.js-Validated-Struct.md | 195 ++++++++++++ docs/devs/Inside-IoT.js.md | 292 ++++++++++++++++++ docs/{ => devs}/IoT.js-Package-(outdated).md | 4 +- docs/{ => devs}/Logging-IoT.js-execution.md | 0 docs/devs/Memory-savings-with-libtuv.md | 241 +++++++++++++++ docs/{ => devs}/Optimization-Tips.md | 0 docs/{ => devs}/Writing-New-Builtin-Module.md | 2 +- docs/help/Assigned-people.md | 11 + docs/help/Coding-Style-Guideline.md | 208 +++++++++++++ docs/help/Community-Guidelines.md | 20 ++ docs/help/Developer's-Guide.md | 3 + docs/help/Developer-Tutorial.md | 161 ++++++++++ docs/{ => help}/Development-Process.md | 10 +- docs/{ => help}/Getting-Started.md | 16 +- docs/{ => help}/Getting-involved.md | 16 +- docs/help/Governance.md | 81 +++++ ...s-Developer's-Certificate-of-Origin-1.0.md | 0 docs/help/Patch-Submission-Process.md | 40 +++ 41 files changed, 1544 insertions(+), 30 deletions(-) create mode 100644 docs/README.md rename docs/{ => api}/IoT.js-API-ADC.md (94%) rename docs/{ => api}/IoT.js-API-Assert.md (100%) rename docs/{ => api}/IoT.js-API-Buffer.md (100%) rename docs/{ => api}/IoT.js-API-DGRAM.md (100%) rename docs/{ => api}/IoT.js-API-DNS.md (100%) rename docs/{ => api}/IoT.js-API-Events.md (100%) rename docs/{ => api}/IoT.js-API-File-System.md (100%) rename docs/{ => api}/IoT.js-API-GPIO.md (100%) rename docs/{ => api}/IoT.js-API-HTTP.md (100%) rename docs/{ => api}/IoT.js-API-I2C.md (100%) rename docs/{ => api}/IoT.js-API-Module.md (100%) rename docs/{ => api}/IoT.js-API-Net.md (100%) rename docs/{ => api}/IoT.js-API-PWM.md (97%) rename docs/{ => api}/IoT.js-API-Process.md (100%) rename docs/{ => api}/IoT.js-API-Stream.md (100%) rename docs/{ => api}/IoT.js-API-Timers.md (100%) rename docs/{ => api}/IoT.js-API-UART.md (100%) rename docs/{ => api}/IoT.js-API-reference.md (100%) create mode 100644 docs/build/Build-Script.md rename docs/{ => build}/Build-for-Linux.md (97%) rename docs/{ => build}/Build-for-NuttX.md (97%) rename docs/{ => build}/Build-for-RPi2.md (100%) create mode 100644 docs/devs/Inside-IoT.js-Validated-Struct.md create mode 100644 docs/devs/Inside-IoT.js.md rename docs/{ => devs}/IoT.js-Package-(outdated).md (94%) rename docs/{ => devs}/Logging-IoT.js-execution.md (100%) create mode 100644 docs/devs/Memory-savings-with-libtuv.md rename docs/{ => devs}/Optimization-Tips.md (100%) rename docs/{ => devs}/Writing-New-Builtin-Module.md (96%) create mode 100644 docs/help/Assigned-people.md create mode 100644 docs/help/Coding-Style-Guideline.md create mode 100644 docs/help/Community-Guidelines.md create mode 100644 docs/help/Developer's-Guide.md create mode 100644 docs/help/Developer-Tutorial.md rename docs/{ => help}/Development-Process.md (94%) rename docs/{ => help}/Getting-Started.md (77%) rename docs/{ => help}/Getting-involved.md (50%) create mode 100644 docs/help/Governance.md rename docs/{ => help}/IoT.js-Developer's-Certificate-of-Origin-1.0.md (100%) create mode 100644 docs/help/Patch-Submission-Process.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..9fa0a47b7c --- /dev/null +++ b/docs/README.md @@ -0,0 +1,18 @@ +Welcome to the IoT.js! + +* If you would like to try IoT.js, please check [Getting Started](help/Getting-Started.md). +* If you would like to jump into IoT.js, please follow [Development Process](help/Development-Process.md) of IoT.js. + +### IoT.js +- Project Overview +> IoT.js is a framework for "Internet of Things" built on +> lightweight JavaScript interpreter ['JerryScript'](https://github.com/jerryscript-project/jerryscript) +> and libtuv for event driven(non-blocking I/O model) similar to node.js. + +- [License](License.md) +
+ + +### [Getting Started](Getting-Started) - Developer guide +### [Getting Involved](Getting-involved) +### Roadmap(TBD) \ No newline at end of file diff --git a/docs/IoT.js-API-ADC.md b/docs/api/IoT.js-API-ADC.md similarity index 94% rename from docs/IoT.js-API-ADC.md rename to docs/api/IoT.js-API-ADC.md index 79afe312af..d8fd2769b5 100644 --- a/docs/IoT.js-API-ADC.md +++ b/docs/api/IoT.js-API-ADC.md @@ -14,7 +14,7 @@ The following shows ADC module APIs available for each platform. ### `pin` * On Nuttx, you have to know pin name. The pin name is defined in target board module. For more module information, please see below list. - * [STM32F4-discovery](../targets/nuttx-stm32f4/Stm32f4dis-Module.md). + * [STM32F4-discovery](../../targets/nuttx-stm32f4/Stm32f4dis-Module.md). ### Constructor diff --git a/docs/IoT.js-API-Assert.md b/docs/api/IoT.js-API-Assert.md similarity index 100% rename from docs/IoT.js-API-Assert.md rename to docs/api/IoT.js-API-Assert.md diff --git a/docs/IoT.js-API-Buffer.md b/docs/api/IoT.js-API-Buffer.md similarity index 100% rename from docs/IoT.js-API-Buffer.md rename to docs/api/IoT.js-API-Buffer.md diff --git a/docs/IoT.js-API-DGRAM.md b/docs/api/IoT.js-API-DGRAM.md similarity index 100% rename from docs/IoT.js-API-DGRAM.md rename to docs/api/IoT.js-API-DGRAM.md diff --git a/docs/IoT.js-API-DNS.md b/docs/api/IoT.js-API-DNS.md similarity index 100% rename from docs/IoT.js-API-DNS.md rename to docs/api/IoT.js-API-DNS.md diff --git a/docs/IoT.js-API-Events.md b/docs/api/IoT.js-API-Events.md similarity index 100% rename from docs/IoT.js-API-Events.md rename to docs/api/IoT.js-API-Events.md diff --git a/docs/IoT.js-API-File-System.md b/docs/api/IoT.js-API-File-System.md similarity index 100% rename from docs/IoT.js-API-File-System.md rename to docs/api/IoT.js-API-File-System.md diff --git a/docs/IoT.js-API-GPIO.md b/docs/api/IoT.js-API-GPIO.md similarity index 100% rename from docs/IoT.js-API-GPIO.md rename to docs/api/IoT.js-API-GPIO.md diff --git a/docs/IoT.js-API-HTTP.md b/docs/api/IoT.js-API-HTTP.md similarity index 100% rename from docs/IoT.js-API-HTTP.md rename to docs/api/IoT.js-API-HTTP.md diff --git a/docs/IoT.js-API-I2C.md b/docs/api/IoT.js-API-I2C.md similarity index 100% rename from docs/IoT.js-API-I2C.md rename to docs/api/IoT.js-API-I2C.md diff --git a/docs/IoT.js-API-Module.md b/docs/api/IoT.js-API-Module.md similarity index 100% rename from docs/IoT.js-API-Module.md rename to docs/api/IoT.js-API-Module.md diff --git a/docs/IoT.js-API-Net.md b/docs/api/IoT.js-API-Net.md similarity index 100% rename from docs/IoT.js-API-Net.md rename to docs/api/IoT.js-API-Net.md diff --git a/docs/IoT.js-API-PWM.md b/docs/api/IoT.js-API-PWM.md similarity index 97% rename from docs/IoT.js-API-PWM.md rename to docs/api/IoT.js-API-PWM.md index 9d9c344058..ec9e93549b 100644 --- a/docs/IoT.js-API-PWM.md +++ b/docs/api/IoT.js-API-PWM.md @@ -17,7 +17,7 @@ The following shows PWM module APIs available for each platform. ### `pin` * On Linux, `pin` is a pwm number which is 0 or 1. * On Nuttx, you have to know pin name. The pin name is defined in target board module. For more module information, please see below list. - * [STM32F4-discovery](../targets/nuttx-stm32f4/Stm32f4dis-Module.md). + * [STM32F4-discovery](../../targets/nuttx-stm32f4/Stm32f4dis-Module.md). ### Constructor diff --git a/docs/IoT.js-API-Process.md b/docs/api/IoT.js-API-Process.md similarity index 100% rename from docs/IoT.js-API-Process.md rename to docs/api/IoT.js-API-Process.md diff --git a/docs/IoT.js-API-Stream.md b/docs/api/IoT.js-API-Stream.md similarity index 100% rename from docs/IoT.js-API-Stream.md rename to docs/api/IoT.js-API-Stream.md diff --git a/docs/IoT.js-API-Timers.md b/docs/api/IoT.js-API-Timers.md similarity index 100% rename from docs/IoT.js-API-Timers.md rename to docs/api/IoT.js-API-Timers.md diff --git a/docs/IoT.js-API-UART.md b/docs/api/IoT.js-API-UART.md similarity index 100% rename from docs/IoT.js-API-UART.md rename to docs/api/IoT.js-API-UART.md diff --git a/docs/IoT.js-API-reference.md b/docs/api/IoT.js-API-reference.md similarity index 100% rename from docs/IoT.js-API-reference.md rename to docs/api/IoT.js-API-reference.md diff --git a/docs/build/Build-Script.md b/docs/build/Build-Script.md new file mode 100644 index 0000000000..aee48b3688 --- /dev/null +++ b/docs/build/Build-Script.md @@ -0,0 +1,244 @@ +## Overview + +build.py help you build IoT.js. + +It locates in "./tools" directory of source tree. + +It automatically creates a directory where build object and outputs will be generated, +checks configurations, tidiness of source code, licenses, and more. +Also it downloads, updates and builds submodules. +And finally generate IoT.js binary. + + +## How to use + +You can build IoT.js with default setting for your host machine with; +``` +./tools/build.py +``` +The command will generate runnable IoT.js binary in "./build//debug/iotjs/iotjs". + +You can also build release binary with; +``` +./tools/build.py --buildtype=release +``` + +## Parameters Candidates +**NOTE: some parameters are not supported by current version of build.py** + +-- +#### `--buildtype` +* `release` | `debug` + +Specify whether build output will be for 'debug' or 'release'. + +``` +./tools/build.py --buildtype=release +``` + +-- +#### `--builddir` + +Specify a directory where build outputs will be generated. + +If given path is not exist, build.py will create it. + +``` +./tools/build.py --builddir=./build +``` + +-- +#### `--clean` +With given this option, build.py will clear all the build directory before start new build. + +``` +./tools/build.py --clean +``` + +-- +#### `--buildlib` +With given this option, build.py will generate IoT.js output as a library. + +``` +./tools/build.py ---buildlib +``` + +-- +#### `--target-arch` +* `arm` | `x86` | `i686` | `x86_64` | `x64` + +Specify target architecture. + +``` +./tools/build.py --target-arch=arm +``` +-- +#### `--target-os` +* `linux` | `darwin` | `osx` | `nuttx` + +Specify target OS. + +``` +./tools/build.py --target-os=nuttx --target-arch=arm +``` + +-- +#### `--target-board` +* `stm32f4dis` | empty + +Specify target board. + +``` +./tools/build.py --target-os=nuttx --target-arch=arm --target-board=stm32f4dis +``` +-- +#### `--cmake-param` +Specify CMake parameters for IoT.js. + +"cmake" command for IoT.js will be executed with the given parameter applied. + +If you have multiple parameters, supply it with multiple use of this option; + +``` +./tools/build.py --cmake-param="..." --cmake-param="..." +``` + +-- +#### `--compile-flag` +Specify C compiler flags for IoT.js. + +If you have multiple compile flags, supply it with multiple use of this option; +``` +./tools/build.py --compile-flag="..." --compile-flag="..." +``` + +-- +#### `--link-flag` +Specify linker flags for IoT.js. + +If you have multiple link flags, supply it with multiple use of this option; +``` +./tools/build.py --link-flag="..." --link-flag="..." +``` + +-- +#### `--external-include-dir` +Specify external include directory for IoT.js. + +If you have multiple external include directoies, supply it with multiple use of this option; +``` +./tools/build.py --external-include-dir="..." --external-include-dir="..." +``` + +-- +#### `--external-static-lib` +Specify external static library that will be liked with IoT.js statically. + +If you have multiple such libraries, supply it with multiple use of this option; +``` +./tools/build.py --external-static-lib="libxxx.a" +``` + +-- +#### `--jerry-cmake-param` +Specify CMake parameters for JerryScript. + +"cmake" command for JerryScript will be executed with the given parameter applied. + +If you have multiple parameters, supply it with multiple use of this option + +-- +#### `--jerry-compile-flag` +Specify C compiler flags for JerryScript. + +If you have multiple cflags, supply it with multiple use of this option + +``` +./tools/build.py --jerry-compile-flag="-DCONFIG_ECMA_LCACHE_DISABLE" +``` + +-- +#### `--jerry-link-flag` +Specify linker flags for JerryScript. + +If you have multiple ldflags, supply it with multiple use of this option + +-- +#### `--jerry-heaplimit` +Specify object heap limit for JerryScript engine. + +``` +./tools/build.py --jerry-heaplimit=80 +``` + +-- +#### `--jerry-memstat` +Enable memstat of JerryScript engine. + +``` +./tools/build.py --jerry-memstat +``` + +-- +#### `--jerry-lto` +With given this option, JerryScript will be built with LTO. + +``` +./tools/build.py --jerry-lto +``` + +-- +#### `--no-init-submodule` +With given this option, submoduls will not initialized before start build. + +``` +./tools/build.py --no-init-submodule +``` + +-- +#### `--no-check-tidy` +With given this option, tidy checking will not performed. + +``` +./tools/build.py --no-check-tidy +``` + +-- +#### `--no-check-test` +With given this option, unit test checking will not performed. + +``` +./tools/build.py --no-check-test +``` + +-- +#### `--no-parallel-build` +With given this option, compilation process will not run in parallel. In other words, executes `make` without `-j` option. + +``` +./tools/build.py --no-parallel-build +``` + +-- +#### `--nuttx-home` +To build for nuttx os, nuttx home directory must be given. + +``` +./tools/build.py --target-os=nuttx --target-arch=arm --target-board=stm32f4dis --nuttx-home="..." +``` + +-- +#### `--config` +Specify build configuration file path. + +``` +./tools/build.py --config=build.arm.nuttx.stm32f4dis.config +``` + +`build.default.config` file is in the source tree for default setting. + +If this option is not specified, `build.config` file will be applied. If the file is not exist, it will be copied from `build.default.config`. + +Parameters specified by the config file is applied, and then the parameters given by command line overwrite over the settings. + +If you need to apply the same set of parameters for each build, making your own config file and trigger build.py with the config file would be more convenient. \ No newline at end of file diff --git a/docs/Build-for-Linux.md b/docs/build/Build-for-Linux.md similarity index 97% rename from docs/Build-for-Linux.md rename to docs/build/Build-for-Linux.md index 4c3949feee..1cb2dcb357 100644 --- a/docs/Build-for-Linux.md +++ b/docs/build/Build-for-Linux.md @@ -104,11 +104,11 @@ Options that may need explanations. * no-check-test: do not run all tests in test folder after build. * nuttx-home: it's NuttX platform specific, to tell where the NuttX configuration and header files are. -If you want to know more details about options, please check the [Build Script](https://github.com/Samsung/iotjs/wiki/Build%20Script) page. +If you want to know more details about options, please check the [Build Script](Build-Script.md) page. #### Include extended module -There are two ways to include [extended module](IoT.js-API-reference.md). +There are two ways to include [extended module](../api/IoT.js-API-reference.md). The first way is to modify a property value of module in `build.config` file. You can move a module name from 'exclude' to 'include'. diff --git a/docs/Build-for-NuttX.md b/docs/build/Build-for-NuttX.md similarity index 97% rename from docs/Build-for-NuttX.md rename to docs/build/Build-for-NuttX.md index 60297151c4..651ed91c19 100644 --- a/docs/Build-for-NuttX.md +++ b/docs/build/Build-for-NuttX.md @@ -51,7 +51,7 @@ $ brew install gcc-arm-none-eabi libusb minicom Currently we checked that NuttX with commit id ** 419fd6e ** works well. To generate headers which are required to build IoT.js, for the first time, you need to build NuttX at least once. This time nuttx build will be failed. But don't worry at this time. After one execution, you don't need this sequence any more. #### Follow the instruction -* [STM32F4-discovery](../targets/nuttx-stm32f4/README.md) +* [STM32F4-discovery](../../targets/nuttx-stm32f4/README.md) ### 3. Build IoT.js for NuttX @@ -84,7 +84,7 @@ libhttpparser.a libiotjs.a libjerrycore.a libtuv.a This time make command for NuttX has to be successful unlike above. #### Follow the instruction -* [STM32F4-discovery](../targets/nuttx-stm32f4/README.md) +* [STM32F4-discovery](../../targets/nuttx-stm32f4/README.md) ### 5. Run IoT.js diff --git a/docs/Build-for-RPi2.md b/docs/build/Build-for-RPi2.md similarity index 100% rename from docs/Build-for-RPi2.md rename to docs/build/Build-for-RPi2.md diff --git a/docs/devs/Inside-IoT.js-Validated-Struct.md b/docs/devs/Inside-IoT.js-Validated-Struct.md new file mode 100644 index 0000000000..97341be843 --- /dev/null +++ b/docs/devs/Inside-IoT.js-Validated-Struct.md @@ -0,0 +1,195 @@ +Validated Struct +================ + +Validated struct is C struct wrapper for encapsulation and validity check. + +* Validated Struct Declaration +* Constructors, Destructor, Methods +* Ownership of validated struct instance + * Case 1: Validated struct instance as local variable + * Case 2: Validated struct instance as parameter & return + * Case 3: Validated struct instance as member variable of other struct + * Case 4: Validated struct instance as data of asynchronous execution + +# Validated Struct Declaration + +```c +typedef struct { + int a; + void* b; +} IOTJS_VALIDATED_STRUCT(iotjs_myclass_t); +``` + +Above struct will make the member variable encapsulated by wrapping real members with wrapper like below. + +```c +typedef struct { + int a; + void* b; +} iotjs_myclass_t_impl_t; + +typedef struct { + iotjs_myclass_impl_t unsafe; + /* More members for struct validity check exist in debug mode */ +} iotjs_myclass_t; + +int main() { + iotjs_myclass_t x; +} +``` + +Only wizards will access the members directly by using `x.unsafe.a`, `x.unafe.b`, ... . Otherwize the members are only accessible with its accessor function. + +See `src/iotjs_def.h` for more details on real implementation. + +# Constructors, Destructor, Methods + +You should create C++-like constructors, destructor and methods with provided accessor. Then you can access the encapsulated member variables using `_this` variable, which has almost same role with C++ `this` keyword. +You must call `destroy` for every validated structs you've created. + +```c +/* Constructor */ +iotjs_myclass_t iotjs_myclass_create(int a) { + iotjs_myclass_t instance; + IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_myclass_t, &instance); + + _this->a = a; + _this->b = malloc(a); + + return instance; +} + +/* Destructor */ +void iotjs_myclass_destroy(iotjs_myclass_t* instance) { + IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_myclass_t, instance); + free(_this->b); +} + +/* Method */ +int iotjs_myclass_get_a(iotjs_myclass_t* instance) { + IOTJS_VALIDATED_STRUCT_METHOD(iotjs_myclass_t, instance); + return _this->a; +} + +int main() { + /* Validated struct as local variable */ + iotjs_myclass_t local_instance = iotjs_myclass_create(3); + printf("%d\n", iotjs_myclass_get_a(&local_instance)); + iotjs_myclass_destroy(&local_instance); + return 0; +} +``` + +# Ownership of validated struct instance + +The ground rule is: + +* Use `iotjs_classname_t` typed variable if the variable *is* responsible for destruction of instance. +* Use `iotjs_classname_t*` typed variable if the variable *is not* responsible for destruction of instance. + +Below Case 1 ~ Case 4 shows the case-by-case example of the ownership rule. + +## Case 1: Validated struct instance as local variable +The `local_instance` variable in previous example was the local instance of validated struct. +Since `local_instance` should be destructed inside the function scope, `iotjs_myclass_t` type was used. + +## Case 2: Validated struct instance as parameter & return +Previous example also included the example of validated struct instance as parameter and return. +When accessing member variable `a` by calling `iotjs_myclass_get_a()`, +`iotjs_myclass_t*` type was used as the parameter type, since it *does not* move the responsibility to destruct the instance. + +And when returning the newly created instance by calling `iotjs_myclass_create()`, +`iotjs_myclass_t` type was used as return type, since it *does* move the responsibility to destruct the instance. + +## Case 3: Validated struct instance as member variable of other struct + +```c +/* Validated struct as member variable of other struct */ + +typedef struct { + iotjs_myclass_t member_instance; +} IOTJS_VALIDATED_STRUCT(iotjs_otherclass_t) + +iotjs_otherclass_t iotjs_otherclass_create() { + /* Initialization steps for iotjs_otherclass_t */ + _this->member_instance = iotjs_myclass_create(3); +} + +void iotjs_otherclass_destroy() { + /* Finalization steps for iotjs_otherclass_t */ + iotjs_myclass_destroy(&_this->member_instance); +} +``` + +In the case above, `iotjs_myclass_t` instance is used as member variable of other class. +Since `iotjs_otherclass_t` is responsible for finalizing the `member_instance`, +it owns the variable as `iotjs_myclass_t` type, not pointer type. + +## Case 4: Validated struct instance as data of asynchronous execution +Another usecase would be using validated struct as callback data. +Currently, our all asynchronous datas are wrapped with `iotjs_*wrap_t` type, +and they are destructed automatically. + +```c +/* + * Public APIs in iotjs_module_fs.h + */ + +typedef struct { + iotjs_reqwrap_t reqwrap; + uv_fs_t req; +} IOTJS_VALIDATED_STRUCT(iotjs_fsreqwrap_t); + +iotjs_fsreqwrap_t* iotjs_fsreqwrap_create(const iotjs_jval_t* jcallback); +void iotjs_fsreqwrap_dispatched(iotjs_fsreqwrap_t* fsreqwrap); +``` + +As you can see, constructor returns the `iotjs_fsreqwrap_t*` type, +because it does not pass the responsibility to destruct the return value. +It is destructed when request is dispatched, which can be informed by calling `iotjs_fsreqwrap_dispatched()`. +The destructor `iotjs_fsreqwrap_destroy()` is hidden in c file. + +```c +/* + * Implementation in iotjs_module_fs.c + */ + +iotjs_fsreqwrap_t* iotjs_fsreqwrap_create(const iotjs_jval_t* jcallback) { + iotjs_fsreqwrap_t* fsreqwrap = IOTJS_ALLOC(iotjs_fsreqwrap_t); + IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_fsreqwrap_t, fsreqwrap); + iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); + return fsreqwrap; +} + +static void iotjs_fsreqwrap_destroy(iotjs_fsreqwrap_t* fsreqwrap) { // private function + IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_fsreqwrap_t, fsreqwrap); + uv_fs_req_cleanup(&_this->req); + iotjs_reqwrap_destroy(&_this->reqwrap); + IOTJS_RELEASE(fsreqwrap); +} + +void iotjs_fsreqwrap_dispatched(iotjs_fsreqwrap_t* fsreqwrap) { + IOTJS_VALIDATED_STRUCT_METHOD(iotjs_fsreqwrap_t, fsreqwrap); + iotjs_fsreqwrap_destroy(fsreqwrap); +} + +/* + * Use of iotjs_fsreqwrap_t + */ + +void callback(uv_fs_t* req) { + do_something(req); + iotjs_fsreqwrap_dispatched(req); /* Call iotjs_*reqwrap_dispatched() when callback called */ +} + +void request(iotjs_jval_t* jcallback) { + iotjs_fsreqwrap_t* wrap = iotjs_fsreqwrap_create(jcallback); + uv_fs_request(loop, wrap->req, callback); +} +``` + +In the case of tuv request wrapper, `iotjs_*reqwrap_dispatched()` should be called when the request has been dispatched. +In the case of tuv handle wrapper, `iotjs_handlewrap_close()` should be called when the handle has been closed. +in the case of JavaScript object wrapper, you don't have to do anything because JavaScript engine will call the destructor when the object becomes inaccessible. + + diff --git a/docs/devs/Inside-IoT.js.md b/docs/devs/Inside-IoT.js.md new file mode 100644 index 0000000000..c41e81b624 --- /dev/null +++ b/docs/devs/Inside-IoT.js.md @@ -0,0 +1,292 @@ +Inside IoT.js +============= + +* [Design](#design) +* [Javascript Binding](#javascript-binding) + * iotjs_jval_t + * iotjs_jobjectwrap_t + * Native handler + * Embedding API +* [libuv Binding](#libuv-binding) + * iotjs_handlewrap_t + * iotjs_reqwrap_t +* [IoT.js Core](#iotjscoe) + * Life cycle of IoT.js + * Builtin + * Native module + * Event loop + +# Design + +IoT.js is built on top of [JerryScript](http://jerryscript.net/) and [libuv](http://libuv.org). JerryScript is a lightweight Javascript engine intended to run on small devices for IoT and libuv is a library for supporting asynchronous I/O. There is a layer that binds JerryScript and libuv to IoT.js. +We will deals with the layer in [Javascript Binding](#javascript-binding) and [libuv Binding](#javascript-binding) section on this document respectively. + +IoT.js core layer locates above these binding layer. +This core layer plays a central role in this project providing upper layer with fundamental functionality of running main event loop, interacting with Javascript engine, managing I/O resources via libuv, managing life cycle of objects, providing builtin modules, and so forth. +[IoT.js Core](#iotjs-core) section deals with the layer in detail. + +IoT.js provides APIs for user applications to help creating IoT friendly services. +You can see the list of API from [IoT.js API Reference](../api/IoT.js-API-reference.md). + +# Javascript Binding + +Many modern Javascript Engines come with [embedding API](#embedding-api) to provide functionality for compiling and executing Javascript program, accessing Javascript object and its value, handling errors, managing lifecyles of objects and so on. + +You can think of Javascript binding layer as an interface between upper layer (IoT.js core) and underlying Javascript engine. +Although IoT.js only supports JerryScript for now, there will be a chance that we extend supporting Javascript engine (such as [Duktape](http://duktape.org/) or [V8](https://code.google.com/p/v8/)) in the future. +For this reason, we want to keep the layer independent from a specific Javascript engine. +You can see interface of the layer in [iotjs_binding.h](../../src/iotjs_binding.h). + +## iotjs_jval_t + +`iotjs_jval_t` struct stands for a real Javascript object. Upper layers will access Javascript object via this struct. +This struct provides following functionalities: + +* Creating a Javascript object using `iotjs_jval_create_*()` constructor. +* Creating a Javascript object by a value. +* Creating a Javascript function object where its body is implemented in C. +* Creating a Javascript Error object. +* Creating reference for a Javascript object increasing reference count. +* Increasing reference count. +* Decreasing reference count. +* Checking object type. +* Retrieving value. +* Calling a Javascript function. +* Evaluating a Javascript script. +* Set and Get corresponding native data to the Javascript object. + +## iotjs_jobjectwrap_t + +You can refer Javascript object from C code side using `iotjs_jval_t` as saw above. +When a reference for a Javascript object was made using `iotjs_jval_t`, it will increase the reference count and will decrease the count when it goes out of scope. + +```c +{ + // Create JavaScript object + // It increases reference count in JerryScript side. + iotjs_jval_t jobject = iotjs_jval_create(); + + // Use `jobject` + ... + + // Before jobject goes out of scope, destroy it. + // It decreases reference count in JerryScript side so that it can be GC-ed. + iotjs_jval_destroy(&jobject) +} +``` + +But the situation is different if you want to refer a Javascript object through out program execution until the object is live. +You may write code like this: + +```c + iotjs_jval_t* jobject = (iotjs_jval_t*)malloc(sizeof(iotjs_jval_t)); // Not allowed +``` + +Unfortunately, we strongly do not recommend that kind of pattern. We treat pointer-types variables in special way. (See [Validated Struct](Inside-IoT.js-Validated-Struct.md) for more details.) + +To achieve your wish, we recommend using `iotjs_jobjectwrap_t` for that purpose. +`iotjs_jobjectwrap_t` is kind of weak pointer to a Javascript Object. +It refers a Javascript object but never increase reference count so that Javascript engine can collect the object when it turns into garbage. +The `iotjs_jobjectwrap_t` instance will be released at the time the corresponding Javascript object is being reclaimed. + +Do not hold pointer to the wrapper in native code side globally because even if you are holding a wrapper by pointer, Javascript engine probably releases the corresponding Javascript object resulting deallocation of wrapper. Consequentially your pointer will turned into dangling. + +The only safe way to get wrapper is to get it from Javascript object. When a wrapper is being created, it links itself with corresponding Javascript object with `iotjs_jval_set_object_native_handle()` method of `iotjs_jval_t`. And you can get the wrapper from the object with `iotjs_jval_get_object_native_handle()` method of `iotjs_jval_t` later when you need it. + + +## Native handler + +Some operations - such as file I/O, networking, device control, multitasking, and etc - can not be performed by pure Javascript. +IoT.js uses a mechanism called "native handler" to enable such operations performed from Javascript. +You can regard native handler as Javascript function object with its body implemented in C. + +You might think it is somewhat similar to [FFI](https://en.wikipedia.org/wiki/Foreign_function_interface). +In a wide sense, it's true for native handler is for calling C function from Javascript. +But in a narrow sense, it's not true. + +Usually main purpose of [FFI](https://en.wikipedia.org/wiki/Foreign_function_interface) is to call a routine written in one language from a program written in another. +After a routine was invoked, it is common that the routine just do what it is supposed to do without knowing the surrounding context except arguments. +Whereas native handler does know that it is being called from Javascript (actually it is a Javascript function although not written in Javascript) and does access surrounding Javascript execution context using [embedding API](#embedding-api). + +## Embedding API + +Many Javascript engines these days provide embedding API. IoT.js uses the API to create [builtin module](#builtin) and [native handler](#native-handler). See following link if you want further information about the API: + * [JerryScript API](http://jerryscript.net/api-reference) + * [Duktape API](http://duktape.org/api.html) + * [V8 embedder's guide](https://developers.google.com/v8/embed) + * [SpiderMonkey API](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference) + +# libuv Binding + +IoT.js is using [libuv](http://libuv.org/) to perform various asynchronous I/O and threading. +Because IoT.js adopts asynchronous programming model, libuv plays very important role in this project. Actually the [main loop](#event-loop) of IoT.js is libuv event loop waiting I/O event, picks the event, and dispatches it to corresponding event handler function. + +You can read [libuv design document](http://docs.libuv.org/en/v1.x/design.html) to get detailed information about asynchronous programming model based on libuv. + +## iotjs_handlewrap_t + +`iotjs_handlewrap_t` is to bind a Javascript object and a libuv handle (e.g. file descriptor) together. +`iotjs_handlewrap_t` inherits `iotjs_jobjectwrap_t` since it is linked with a Javascript object. + +Unlike `iotjs_jobjectwrap_t`, `iotjs_jobjectwrap_t` increases RC for the Javascript object when an instance of it is created to prevent GC while the handle is alive. The reference counter will be decreased after the handle is closed, allowing GC. + +## iotjs_reqwrap_t + +`iotjs_reqwrap_t` is for wrapping libuv request data and Javascript callback function. And make sure that the Javascript callback function is alive during the I/O operation. + +Let's look at how asynchronous I/O are treated in IoT.js: + +1. Javascript module calls builtin function to perform I/O applying arguments including callback. +2. Builtin creates `iotjs_reqwrap_t` to wrap `uv_req_s` and Javascript callback function. +3. Builtin calls libuv to perform the I/O. +4. After I/O finished, libuv calls builtin after handler. +5. Builtin after handler takes `iotjs_reqwrap_t` containing I/O result and Javascript callback function. +6. Builtin after handler calls Javascript callback. +7. Builtin after handler release `iotjs_reqwrap_t` by calling `iotjs_*reqwrap_dispatch()` + +`iotjs_reqwrap_t` does not inherits `iotjs_handlewrap_t` for wrapping the callback function object. +Note that `HandleWrap` does not increase reference count of wrapping object. It does not guarantee guarantee liveness of the object even if the wrapper is alive. + +On the other hand, `iotjs_reqwrap_t` increases the reference count for the callback function and decreases when it is being freed to guarantee the liveness of callback function during the request is ongoing. +After request is finished and `iotjs_reqwrap_t` released by calling `iotjs_*reqwrap_dispatch()`, the callback function could be collected by GC when it need to be. + +# IoT.js Core + +## Life cycle of IoT.js + +_Note:_ +_We are currently focusing on implementing IoT.js upon JerryScript engine._ +_Implementation of initializing process depends on JerryScript API._ +_That could be changed when we adopt other Javascript engines._ +_Anyway, in this chapter we will explain initialization process based on current implementation._ + +The process of IoT.js can be summarized as follow: + +1. Initialize JerryScript engine. +2. Execute empty script + * Create initial Javascript context. +3. Initialize builtin modules. + * Create builin modules including ['process'](../api/IoT.js-API-Process.md). +4. Evaluate ['iotjs.js'](../../src/js/iotjs.js). + * Generate entry function. +5. Run the entry function passing 'process'. + 1. Initialize 'process' module. + 2. Load user application script. + 3. Run user application. +6. Run [event loop](#event-loop) until there are no more events to be handled. +7. Clean up. + +## Builtin + +"Builtin" is Javascript objects fully implemented in C using [embedding API](#embedding-api). +The list of builtin objects can be found at `MAP_MODULE_LIST` macro in ['iotjs_module.h'](../../src/iotjs_module.h). + +Because methods of builtin modules are implemented as [native handler](#native-handler), +are able to access underlying system using libuv, C/C++ library, and system call. +Also, builtin modules could be used for optimizing performance of CPU bound routine or reduce binary size. + +Builtin modules are initialized during [intializing step of IoT.js](#life-cycle-of-iotjs) and released just before program terminates. + +## Native module + +The [basic modules and extended modules](../api/IoT.js-API-reference.md) provided by IoT.js are called 'native module' because it will be included IoT.js as binary format.(not as script). +There is a [tool](../../tools/js2c.py) that transfer Javascript script source file into C file. + +Usually a native module needs help from couple of [builtin](#builtin) modules which are implemented in C thus able to access underlying system. + +Some native modules are bound to global object while others are on demand. +On demand modules will be created at the moment when it is first required and will not released until the program terminates. + +## Event loop + +_Note:_ +_It would be helpful to read [libuv design overview](http://docs.libuv.org/en/v1.x/design.html) to understand asynchronous I/O programming model if you are not familiar with it._ + +_Note:_ +_In this section we will see simple file open example and relevant code segment. You can find the source files at ['iotjs.c'](../../src/iotjs.c), [`iotjs_module_fs.c`](../../src/module/iotjs_module_fs.c) and ['fs.js'](../../src/js/fs.js)_ + + +IoT.js follows asynchronous I/O programming model proposed by libuv to perform non-blocking, single-threaded, asynchronous I/O. + +You can find main loop of the program at the file ['iotjs.c'](../../src/iotjs.c) in the source tree. It looks like this: + +```c + // Run event loop. + bool more; + do { + more = uv_run(iotjs_environment_loop(env), UV_RUN_ONCE); + more |= iotjs_process_next_tick(); + if (more == false) { + more = uv_loop_alive(iotjs_environment_loop(env)); + } + } while (more); +``` + +While running a IoT.js application, it could make requests for I/O operations using [IoT.js API](../api/IoT.js-API-reference.md). +For example, You can write a code for opening 'hello.txt' file and printing file descriptor out like this: +```js +fs.open('hello.txt', 'r', function(err, fd) { + console.log('fd:' + fd); +}); +conosle.log('requested'); +``` + +To handle the request, IoT.js will wrapping the request and callback function using `iotjs_reqwrap_t`. +```c + iotjs_fsreqwrap_t* req_wrap = iotjs_fsreqwrap_create(jcallback); +``` + +libuv will take charge of actual I/O processing taking the request. +```c + uv_fs_t* fs_req = iotjs_fsreqwrap_req(req_wrap); + int err = uv_fs_open(iotjs_environment_loop(env), + fs_req, + path, flags, mode, + AfterAsync); +``` + +Since all I/O are treated as non-blocking, calling for async I/O API returns immediately right after request was sent to libuv. +And then next line of javascript program will be executed immediately without waiting the I/O. +Thus in the above example 'requested' will be printed out right after file open request was made. + +If there were I/O requests, `uv_run()` in the main loop waits by polling the requests until at least one of the request processing were finished. +When a result for a request was produced, internal part of libuv calls corresponding handler function (let it be after function) back. + +Usually, the after function retrieves I/O result and `iotjs_reqwrap_t` object from request data. +And calling the javascript callback function with the result. + +```c + iotjs_fsreqwrap_t* req_wrap = (iotjs_fsreqwrap_t*)(req->data); // get request wrapper + const iotjs_jval_t* cb = iotjs_fsreqwrap_jcallback(req_wrap); // javascript callback function + + iotjs_jargs_t jarg = iotjs_jargs_create(2); + iotjs_jargs_append_null(&jarg); // in case of success. + iotjs_jargs_append_number(req->result); // result - file descriptor for open syscall + + // callback + iotjs_jhelper_make_callback(cb, iotjs_jval_get_null(), &jarg); + + // cleanup + iotjs_jargs_destroy(&jarg); + iotjs_fsreqwrap_dispatched(req_wrap); +``` + +For above file open example, calling javascript callback function would result execution of the handler. +```js +function(err, fd) { + console.log('fd:' + fd); +} +``` + +One iteration of event loop is finished and `uv_run()` finally returns after all results were handled. +Next, it calls next tick handler. +```c + more |= iotjs_process_next_tick(); +``` +And for next step, main event loop checks if there were no more request to be treated. +```c + if (more == false) { + more = uv_loop_alive(iotjs_environment_loop(env)); + } +``` +If there are another iteration of the loop executed. Otherwise, main event loop ends. diff --git a/docs/IoT.js-Package-(outdated).md b/docs/devs/IoT.js-Package-(outdated).md similarity index 94% rename from docs/IoT.js-Package-(outdated).md rename to docs/devs/IoT.js-Package-(outdated).md index 95794c4a2e..0a5d944b56 100644 --- a/docs/IoT.js-Package-(outdated).md +++ b/docs/devs/IoT.js-Package-(outdated).md @@ -74,7 +74,7 @@ Please visit [npmjs.org](https://docs.npmjs.com/getting-started/publishing-npm-p ### About the license of each packages -IoT.js is released under Apache 2.0 license, [this page](https://github.com/Samsung/iotjs/wiki/License). We assume you also agree on this license when publishing to ipm registry. +IoT.js is released under Apache 2.0 license, [this page](../License.md). We assume you also agree on this license when publishing to ipm registry. ### Downloading packages @@ -108,7 +108,7 @@ As mentioned above, npm has local and global packages. But for IoT.js lets stick ### Package license -You may use ipm packages freely under Apache 2.0 license, read [this page](https://github.com/Samsung/iotjs/wiki/License) +You may use ipm packages freely under Apache 2.0 license, read [this page](../License.md) ### Searching for packages diff --git a/docs/Logging-IoT.js-execution.md b/docs/devs/Logging-IoT.js-execution.md similarity index 100% rename from docs/Logging-IoT.js-execution.md rename to docs/devs/Logging-IoT.js-execution.md diff --git a/docs/devs/Memory-savings-with-libtuv.md b/docs/devs/Memory-savings-with-libtuv.md new file mode 100644 index 0000000000..ca1f64bb0e --- /dev/null +++ b/docs/devs/Memory-savings-with-libtuv.md @@ -0,0 +1,241 @@ +Memory usage with libtuv on iotjs is described here and compared to libuv. + +* Compared with release version in i686. +* iotjs version: hash f8e8391d8c30a76c2f82644e454056c11a2bad1a + +#### runtime memory usage compare with libuv running iotjs + +1) how to build + +1-1) with libuv +``` +./tools/build.py --buildtype=release --nochecktest +``` +1-2) with libtuv +``` +./tools/build.py --buildtype=release --nochecktest --tuv +``` +2) memory usage measurement with valgrind running `test httpserver` +``` +valgrind ./build/i686-linux/release/iotjs/iotjs ./test/run_pass/test_httpserver.js +``` + +2-1) with libuv +``` +==5740== Memcheck, a memory error detector +==5740== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==5740== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info +==5740== Command: ./build/i686-linux/release/iotjs/iotjs ./test/run_pass/test_httpserver.js +==5740== +==5740== +==5740== HEAP SUMMARY: +==5740== in use at exit: 0 bytes in 0 blocks +==5740== total heap usage: 959 allocs, 959 frees, 482,669 bytes allocated +==5740== +==5740== All heap blocks were freed -- no leaks are possible +==5740== +==5740== For counts of detected and suppressed errors, rerun with: -v +==5740== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +``` + +2-2) with libtuv +``` +==7584== Memcheck, a memory error detector +==7584== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==7584== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info +==7584== Command: ./build/i686-linux/release/iotjs/iotjs ./test/run_pass/test_httpserver.js +==7584== +==7584== +==7584== HEAP SUMMARY: +==7584== in use at exit: 0 bytes in 0 blocks +==7584== total heap usage: 955 allocs, 955 frees, 481,645 bytes allocated +==7584== +==7584== All heap blocks were freed -- no leaks are possible +==7584== +==7584== For counts of detected and suppressed errors, rerun with: -v +==7584== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +``` + +482,669 vs 481,645 = 1,024 bytes saved + +#### binary size + +1) build +``` +./tools/build.py --buildtype=release --nochecktest --target-arch=arm --target-os=linux +./tools/build.py --buildtype=release --nochecktest --target-arch=arm --target-os=linux --tuv +``` + +2) binary size in i686-linux + +* libuv : 213,130 / iotjs: 2,512,292, stripped: 782,152 +* libtuv: 103,158 / iotjs: 2,460,357, stripped: 732,776 +* itself: 109,972 smaller, iotjs: 51,935(striped 49,376) saved + +3) binary size in arm-linux + +* libuv : 176,614 / iotjs: 2,543,525, stripped: 536,460 +* libtuv: 83,458 / iotjs: 2,506,455, stripped: 507,548 +* itself: 93,156 smaller, iotjs: 37,070(stripped: 28,912) saved + +#### libuv vs libtuv itself + +1) use `tuvtester` as an application to compare. + +2) codes changes to make both libuv.a and libtuv.a interchangeable. + +2-1) as libtuv uses c++ compiler, wrap all codes with +``` +extern "C" { +... +} +``` +2-2) for libuv, give `libuv.a` by changing `tuvtest.cmake` file. use file from iotjs build. +``` +target_link_libraries(${TUVTESTNAME} LINK_PUBLIC + #${TARGETLIBNAME} + "/(absolute path to libuv)/libuv.a" + ${TUV_LINK_LIBS}) +``` + +2-3) some functions that does not exist in libuv. add this bottom of in runner_main.cpp +``` +#if 1 + +#define uv__handle_deinit(h) \ + do { \ + QUEUE_REMOVE(&(h)->handle_queue); \ + QUEUE_INIT(&(h)->handle_queue); \ + } \ + while (0) + +void uv_deinit(uv_loop_t* loop, uv_handle_t* handle) { + QUEUE* q; + uv_handle_t* h; + + QUEUE_FOREACH(q, &loop->handles_queue) { + h = QUEUE_DATA(q, uv_handle_t, handle_queue); + if (h == handle) { + uv__handle_deinit(handle); + break; + } + } +} + +#endif +``` + +2-4) remove test codes that does not run with libuv, tested codes are like this in runner_list.h +``` +#define TEST_LIST_ALL(TE) \ + TE(idle_basic, 5000) \ + TE(timer_init, 5000) \ + \ + TE(condvar_2, 5000) \ + TE(condvar_3, 5000) \ + TE(cwd, 5000) \ + \ + TE(fs_file_noent, 5000) \ + TE(fs_file_sync, 5000) \ + TE(fs_file_async, 5000) \ + TE(fs_file_write_null_buffer, 5000) \ + TE(fs_stat_missing_path, 5000) \ + TE(fs_open_dir, 5000) \ + TE(fs_file_open_append, 5000) \ + TE(fs_read_file_eof, 5000) \ + \ + TE(threadpool_queue_work_simple, 5000) \ + + +// shutdown_eof should be last of tcp test, it'll stop "echo_sevrer" + +#if defined(__linux__) +#define TEST_LIST_EXT(TE) \ + +#else +#define TEST_LIST_EXT(TE) \ + +#endif + +#define HELPER_LIST_ALL(TE) \ + +``` + +3) measure + +run with valgrind +``` +valgrind ./build/i686-linux/release/bin/tuvtester +``` + +3-1) with libuv +``` +==24952== Memcheck, a memory error detector +==24952== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==24952== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info +==24952== Command: ./build/i686-linux/release/bin/tuvtester +==24952== +Run Helpers... +[idle_basic ]...OK +[timer_init ]...OK +[condvar_2 ]...OK +[condvar_3 ]...OK +[cwd ]...OK +[fs_file_noent ]...OK +[fs_file_sync ]...OK +[fs_file_async ]...OK +[fs_file_write_null_buffer ]...OK +[fs_stat_missing_path ]...OK +[fs_open_dir ]...OK +[fs_file_open_append ]...OK +[fs_read_file_eof ]...OK +[threadpool_queue_work_simple ]...OK +Waiting Helpers to end... +==24952== +==24952== HEAP SUMMARY: +==24952== in use at exit: 0 bytes in 0 blocks +==24952== total heap usage: 44 allocs, 44 frees, 1,727 bytes allocated +==24952== +==24952== All heap blocks were freed -- no leaks are possible +==24952== +==24952== For counts of detected and suppressed errors, rerun with: -v +==24952== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +``` + +3-2) with libtuv +``` +==26621== Memcheck, a memory error detector +==26621== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==26621== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info +==26621== Command: ./build/i686-linux/release/bin/tuvtester +==26621== +Run Helpers... +[idle_basic ]...OK +[timer_init ]...OK +[condvar_2 ]...OK +[condvar_3 ]...OK +[cwd ]...OK +[fs_file_noent ]...OK +[fs_file_sync ]...OK +[fs_file_async ]...OK +[fs_file_write_null_buffer ]...OK +[fs_stat_missing_path ]...OK +[fs_open_dir ]...OK +[fs_file_open_append ]...OK +[fs_read_file_eof ]...OK +[threadpool_queue_work_simple ]...OK +Waiting Helpers to end... +==26621== +==26621== HEAP SUMMARY: +==26621== in use at exit: 0 bytes in 0 blocks +==26621== total heap usage: 40 allocs, 40 frees, 991 bytes allocated +==26621== +==26621== All heap blocks were freed -- no leaks are possible +==26621== +==26621== For counts of detected and suppressed errors, rerun with: -v +``` + +3-3) result + +* libuv: 1,727 bytes +* libtuv: 991 bytes \ No newline at end of file diff --git a/docs/Optimization-Tips.md b/docs/devs/Optimization-Tips.md similarity index 100% rename from docs/Optimization-Tips.md rename to docs/devs/Optimization-Tips.md diff --git a/docs/Writing-New-Builtin-Module.md b/docs/devs/Writing-New-Builtin-Module.md similarity index 96% rename from docs/Writing-New-Builtin-Module.md rename to docs/devs/Writing-New-Builtin-Module.md index b3ef88ae24..ceb1170612 100644 --- a/docs/Writing-New-Builtin-Module.md +++ b/docs/devs/Writing-New-Builtin-Module.md @@ -55,7 +55,7 @@ OK ## Writing Native Module Builtin -You can implement some part of the builtin module in C, to enhance performance and to fully exploit the H/W functionality, etc. It has similar concept with [Node.js native addon](https://nodejs.org/api/addons.html), but we have different set of APIs. Node.js uses its own binding layer with v8 API, but we use [our own binding layer](https://github.com/Samsung/iotjs/blob/master/src/iotjs_binding.h) which wraps [JerryScript API](https://github.com/Samsung/JerryScript/blob/master/jerry-core/jerry-api.h). You can see `src/iotjs_binding.*` files to find more APIs to communicate with JS-side values from native-side. +You can implement some part of the builtin module in C, to enhance performance and to fully exploit the H/W functionality, etc. It has similar concept with [Node.js native addon](https://nodejs.org/api/addons.html), but we have different set of APIs. Node.js uses its own binding layer with v8 API, but we use [our own binding layer](../../src/iotjs_binding.h) which wraps [JerryScript API](https://github.com/jerryscript-project/JerryScript/blob/master/jerry-core/jerry-api.h). You can see `src/iotjs_binding.*` files to find more APIs to communicate with JS-side values from native-side. For simple explanation, `console` module will be used as an example. diff --git a/docs/help/Assigned-people.md b/docs/help/Assigned-people.md new file mode 100644 index 0000000000..60a9a9857d --- /dev/null +++ b/docs/help/Assigned-people.md @@ -0,0 +1,11 @@ +#### Maintainers +* akiss77 (integration) +* LaszloLango (integration) +* zherczeg (Steering Committee) +* yichoi (Steering Committee, Project main contact) + +#### Committers +* chokobole +* nova0821 +* glistening +* hs0225 \ No newline at end of file diff --git a/docs/help/Coding-Style-Guideline.md b/docs/help/Coding-Style-Guideline.md new file mode 100644 index 0000000000..ebf5c29004 --- /dev/null +++ b/docs/help/Coding-Style-Guideline.md @@ -0,0 +1,208 @@ +Coding Style Guideline +====================== + +* [Coding Style Guideline for C](#coding-style-guideline-for-c) + * Validated Struct + * Header Files + * Formatting + * Naming + * Comments +* [Coding Style Guideline for Javascript](#coding-style-guideline-for-javascript) + * Javascript Language Rules + * Javascript Style Rules + * Naming + * Formatting +* [Coding Style Guideline for Python](#coding-style-guideline-for-python) + + +# Coding Style Guideline for C + +Our coding style guideline is based on [google c++ coding standard](https://google.github.io/styleguide/cppguide.html), +but modified due to some difference between C and C++. +When this guideline is ambiguous, just follow the result of running `./tools/check_tidy.py` + +## Validated Struct +Use [Validated Struct](../devs/Inside-IoT.js-Validated-Struct.md) whenever possible, for encapsulation and validity check. + +## Header Files + +### #define guard +Use #define guard in all header files. `_H` format is recommended. + + #ifndef FILE_H + #define FILE_H + ... + #endif // FILE_H + +## Formatting + +### Line length +maximum 80 characters in a line. + +### Indentation +2 space indent at a time. Do not use a tab for indentation. + +### Vertical whitespace +Add two blank lines between functions. + +Otherwise minimize use of vertical whitespace. + +This is more a principle than a rule: don't use blank lines when you don't have to. In particular, don't put more than two blank lines between functions, resist starting functions with a blank line, don't end functions with a blank line, and be discriminating with your use of blank lines inside functions. + +### Function call +Write a function call all in a line if it fits. If not, break the line into multiple lines after assignment operator, or insert newline between parameters. +Do not insert spaces after open paren and before close paren. + + int value = foo(arg1, arg2, arg3); + + int value = + foo(arg1, arg2, arg3); + + int value = foo(arg1, arg2, + arg3); + +### Function Declaration and Definition +Use named parameters in function declaration. + + return_type function_name(int, char); // not allowed + return_type function_name(int arg1, char arg2); // Use this + +Return type should be on the same line as function name and parameters if it fits. If not, break between them aligned with the first argument. + + return_type function_name(int arg1, + char arg2); + +If even first argument does not fit in a line, write it in a new line with 4 space indent. + + return_type function_name( + int arg1, char arg2); + + +The open curly brace should be at the same line. The close curly brace should be either at the same line as its open curly brace or at new line. + + return_type function_name(int arg1, char arg2) { }; + return_type function_name(int arg1, char arg2) { + ... + } + return_type function_name(int arg1, char arg2) + { // not allowed + ... + } + +### Conditionals +Use a space between the if and open brace. Open brace on the same line as the if. + + if (condition) { + ... + } + +Short conditional statements may be written without braces. + + if (condition) + do_something(); + +### Loops and Switches +Use a space between the switch and loops(for, while, do-while) and open brace. Open brace on the same line as the switch and loops. + + while (condition) { + ... + } + +Single loop body statement may be written without braces. + + while (condition) + do_something(); // ok + for (condition) + do_something(); // ok + + +## Naming + +### Type names +Use lower cases and underscore for struct names, and add prefix `iotjs_` and suffix `_t`. + + typedef struct { + ... + } iotjs_name_t; + +### Function names +Use lower cases and underscore for function names. + +For constructors, destructor, and methods of validated struct `iotjs_mystruct_t`, use names starting with `iotjs_mystruct_*`. +Constructor function name should be either `iotjs_mystruct_create` or `iotjs_mystruct_initialize`, +depending on whether the constructor returns the instance as return value, or the constructor just initializes the instance passed by parameter. + +```c +typedef struct { +} IOTJS_VALIDATED_STRUCT(iotjs_mystruct_t); + +iotjs_mystruct_t iotjs_mystruct_create(); // Ok +iotjs_mystruct_t* iotjs_mystruct_create(); // Ok +void iotjs_mystruct_initialize(iotjs_mystruct_t*); // Ok + +void iotjs_mystruct_destroy(); + +int iotjs_mystruct_method(); +``` + +### Variable names +Use lower cases and underscore for variable names. + + int lower_case_variable; + + +## Comments + +### Comment style +Use either // or /* */ style comments. However, // style is much prefered. + + + +# Coding Style Guideline for Javascript + +This coding standard is based on [google javascript coding standard](https://google.github.io/styleguide/javascriptguide.xml) + +## Javascript Language Rules + +### var +Always declare variable before use. + +### Semicolons +Always use semicolons. + +### Function Declaration in blocks +Do not declare functions within a block. + +### Wrapper objects of primitive types +Do not use wrapper objects for primitive types. + +### with +Do not use `with` statement. + +### Modifying prototypes of builtin objects +Do not modify prototypes of builtin objects + +## Javascript Style Rules + +### Naming +Use lowerCamelCase for varible names and function names. + + var myFirstVariable; + function myFirstFunction { + ... + } + +Use UpperCamelCase for constructor names + + function MyConstructorFunction(input) { + this.variable = input; + ... + } + +### Formatting +Follow C/C++ formatting above. + + +# Coding Style Guideline For Python + +The coding conventions for Python code follows [PEP 8 - Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) diff --git a/docs/help/Community-Guidelines.md b/docs/help/Community-Guidelines.md new file mode 100644 index 0000000000..9789400fd3 --- /dev/null +++ b/docs/help/Community-Guidelines.md @@ -0,0 +1,20 @@ +All community members must abide by rules of common sense, civility and good neighborliness. Frank discussion is welcomed and encouraged with the goal of arriving at the best technical solution possible. +Community participants must adhere to these simple rules: +- Respect and acknowledge all contributions, suggestions and comments from the community. +- Listen and be open to all opinions, which are subject to open discussion. +- Help each other. +- Assume people mean well. + +
+ +### Community Consensus, Lazy Consensus and Slient Consent + +Community consensus about a Project issue means that the issue has been submitted to and discussed by Contributors, and that ALL discussing member agree about the issue.

+Lazy consensus means that Contributors may proceed with work when they have reason to believe that other Contributors in the community will agree with the direction of their work, and do not need to stop or initiate unnecessary discussion about the work. Contributors should publish their work (that is, merge proposals to master branch) in a timely manner to allow others to possibly raise issues about the work. When the Contributor is not sure there will be consensus, they should raise a proposal to the community via appropriate public communication channels(**_currently Github issues is possible way to achieve this_**)

+Silent Consent means that those who do not offer a reasoned alternative in course of the discussion implicitly agree with the proposal. + +
+ +### Meritocracy + +Responsibilities in the project (including decision making) are given to those who exhibit both the technical skill and dedication to project via their ongoing valuable contributions. Decision making happens inside the community, with more weight given to those who are more familiar with the code. diff --git a/docs/help/Developer's-Guide.md b/docs/help/Developer's-Guide.md new file mode 100644 index 0000000000..fe8d950e46 --- /dev/null +++ b/docs/help/Developer's-Guide.md @@ -0,0 +1,3 @@ + - [Getting Started](Getting-Started.md) + - [Developer Tutorial](Developer-Tutorial.md) + - [IoT.js API Reference](../api/IoT.js-API-reference.md) \ No newline at end of file diff --git a/docs/help/Developer-Tutorial.md b/docs/help/Developer-Tutorial.md new file mode 100644 index 0000000000..cb7189ff42 --- /dev/null +++ b/docs/help/Developer-Tutorial.md @@ -0,0 +1,161 @@ +### Getting Started with Examples +As **IoT.js** is asynchronous and event-driven, programming style is pretty much different from traditional blocking synchronous style. This tutorial lets you know how to code with **IoT.js** mainly focused on asynchronous and event-driven style. + +#### Hello World +Firstly, create a javascript file (e.g. `hello.js`) and open it. Then type as following. +```javascript +console.log('Hello, world!'); +``` + +You must be familiar with the code above if you have ever worked with Javascript in web. This is exactly same way as in major web browsers. + +You can run it with: +``` +$ ./iotjs hello.js +``` + +Then it gives: +``` +Hello, world! +``` + +Pretty simple. But where did `console` come from? `console` is not defined in Global Object according to ECMAScript spec. + +The answer is `console` is a builtin module so it should have been `require`ed. However, `console` is a special case so we can use it directly without `require`. This is about Module System which we will cover later. + +#### File Reader +To read a file, we need to import *File System* module. +When importing a module, we use function `require`. +*File System* module is abbreviated as `fs`. You can import it like: +```javascript +var fs = require('fs'); +``` + +Then we can use APIs of `fs`. To read the whole file, use `readFile()`. +```javascript +fs.readFile("hello_iotjs.txt", // path + readFileCallback); // callback +``` +Let's say we want to read `hello_iotjs.txt`. Just pass it as first argument. +It may be enough for synchronous style but we must specify a callback function as last argument. `fs.readFile` does not wait for I/O to be done, it just goes on to next code. Sometime after file opening is completely done, callback will be called. This means that we must not implement `readFile` handling code on the next line, but in callback function. + +Take a look at the callback function for `fs.readFile` below. +```javascript +function readFileCallback(err, data) { + if (err) throw err; + console.log(data.toString()); +} +``` +We can find two arguments in this function. We can think of them as the results of `fs.open`. In this case(`fs.readFile`), `err` and `data` are given. Of course, each API function has their own argument list. + +`err` is an `Error` object. We just throw it if an error has occurred. Otherwise we have successfully read the file content and it is stored in `data`. In this example, it only prints the file content but you can do anything you want. + +##### full code list +```javascript +var fs = require('fs'); + +fs.readFile("hello_iotjs.txt", // path + readFileCallback); // callback + +function readFileCallback(err, data) { + if (err) throw err; + console.log(data.toString()); +} +``` + +#### TCP Echo Server +`net` module provides APIs for creating servers and clients. In this tutorial, we are going to create a server only. We can connect to the server and test it with external tools(e.g. `nc`). + +Firstly, we need to require `net` module. +```javascript +var net = require('net'); +var port = 1235; // custom port number +``` +Then create a server with `net.createServer()`. It could have some arguments +```javascript +var server = net.createServer(); +``` +After creating a server, make the server listen for connections. +```javascript +server.listen(port); +``` +By calling `listen`, object `server` starts listening with given port. Of course `listen` is processed asynchronously but we do not have to specify a callback. What we want to do next is not necessarily done in the callback because we are just going to add some event handlers. + +**IoT.js** is event-driven. We can do a lot of stuff with event handlers. +Both `Server` and `Socket` object inherits from `EventsEmitter`, so we can add event listeners for them. For servers, we probably want to add a listener for `'connection'` event which is emitted when a new connection is made. Take a look at the following. +```javascript +server.on('connection', function(socket) { + socket.on('data', function(data) { + socket.write("echo: " + data); + }); +}); +``` +In `File Reader` example, we defined callbacks outside and referred them as arguments. In this time the function is embedded as a Function Expression. + +When `'connection'` event is emitted, it creates a socket and we can get it from the first argument. In the same way we did for server, add a ``data`` listener for each socket which is emitted when data is received. As we are creating an echo server, what we want to do here is just send the `data` back to client. Note that to clarify this is an echoed data, `"echo: "` is prepended to it. + +That is all. We just implemented an echo server less than 10 lines. Actually, the server will run forever because we did not add code for closing the server. As long as the server is listening, it does not terminate even if there is no more *javascript* code to run. As this is a simple tutorial, just kill the process manually like pressing `Ctrl+C` + +##### full code list + +```javascript +var net = require('net'); +var port = 1235; + +var server = net.createServer(); +server.listen(port, 5); +server.on('connection', function(socket) { + socket.on('data', function(data) { + socket.write("echo: " + data); + }); +}); +``` +##### test the server +We have created a server but not a client. Instead of implementing a client, we are going to use a unix tool `nc`. + +Run the server first: +``` +$ ./iotjs echo_server.js & +``` + +Connect to the server with `nc` +``` +$ nc localhost 1235 +``` +Type whatever you want to send, and the message will be echoed back. +``` +hello, echo server! +echo: hello, echo server! +``` + +### Module System +Javascript(ECMAScript 5.1 or under) itself does not support module system. In web browsers, even though a web page loads several Javascript files, they are evaluated in the same context. To overcome this language limit, **IoT.js** supports [CommonJS](http://www.commonjs.org/) modules. + +We have used some of native modules through the examples above. When importing those modules, we use `require` function. Once `require`ed a module, we can use its APIs that are exported from the module. It will be covered in the section [Writing user modules](#writing-user-modules). + +#### Writing user modules +When writing a module, APIs must be exposed by adding it in `exports` object. Otherwise it can be used only inside the module. Object `exports` will be returned when another module calls `require`. + +Let's write a sample module. Save it as `mymodule.js` +```javascript +exports.hello = 'Hello, IoT.js!'; // string +exports.add = function(a, b) { // function + return a + b; +} +var local = 'local string'; // string (not exported) +``` +Let's write another module that uses the module we just wrote. By calling `require`, we get its `exports` object. We will name it `mymodule_test.js` +```javascript +var mymodule = require('mymodule'); +console.log(mymodule.hello); +console.log(mymodule.add(1, 2)); +console.log(mymodule.local); +``` +Save two files in the same directory so **IoT.js** can automatically find `mymodule.js`. Then we are ready to go. Execute the later script then you will see: +``` +$ ./iotjs mymodule_test.js +Hello, IoT.js! +3 +undefined +``` +Note that `console.log(local)` prints `undefined`. It cannot be referred because it is not added in `exports`. \ No newline at end of file diff --git a/docs/Development-Process.md b/docs/help/Development-Process.md similarity index 94% rename from docs/Development-Process.md rename to docs/help/Development-Process.md index 745906860e..707b2d7628 100644 --- a/docs/Development-Process.md +++ b/docs/help/Development-Process.md @@ -11,7 +11,7 @@ Individual developers maintain a local copy of the IoT.js codebase using the git ### Proposals, Get Answers and Report a Bug via Github Issues -If you have a question about IoT.js code, have trouble any documentation, would like to suggest new feature, or find a bug, [review the current IoT.js issues](https://github.com/Samsung/iotjs/issues) in GitHub, and if necessary, [create a new issue](https://github.com/Samsung/IoT.js/issues/new). +If you have a question about IoT.js code, have trouble any documentation, would like to suggest new feature, or find a bug, [review the current IoT.js issues](https://github.com/Samsung/iotjs/issues) in GitHub, and if necessary, [create a new issue](https://github.com/Samsung/iotjs/issues/new). **There are several labels on the Issue. Please choose proper labels on the purpose.** * **bug** @@ -32,11 +32,11 @@ The IoT.js Project development process is marked by the following highlights: * The Maintainers and Reviewers evaluate the idea, give feedback, and finally approve or reject the proposal. * The author shares the proposal with the community via **_Github issues with 'new feature request' label_** * The community provides feedback which can be used by the author to modify their proposal and share it with the community again. -* The above steps are repeated until the community reaches a consensus according to the [Community Guidelines](Community-Guidelines). +* The above steps are repeated until the community reaches a consensus according to the [Community Guidelines](Community-Guidelines.md). * After a consensus is reached, the author proceeds with the implementation and testing of the feature. * After the author is confident their code is ready for integration: - The author generates a patch and signs off on their code. - - The author submits a patch according to the [Patch Submission Process](Patch-Submission-Process). + - The author submits a patch according to the [Patch Submission Process](Patch-Submission-Process.md). * The Maintainers and Reviewers watch the pull request for the patch, test the code, and accept or reject the patch accordingly. * After the code passes code review, the Maintainers and Reviewers accept the code(integrated into the master branch), which completes the development process. * After a patch has been accepted, it remains the authoring developer's responsibility to maintain the code throughout its lifecycle, and to provide security and feature updates as needed. @@ -56,9 +56,9 @@ The IoT.js Project development process is marked by the following highlights: ### Tips on GitHub Issues -* Check existing [IoT.js issues](https://github.com/Samsung/IoT.js/issues) for the answer to your issue. +* Check existing [IoT.js issues](https://github.com/Samsung/iotjs/issues) for the answer to your issue. Duplicating an issue slows you and others. Search through open and closed issues to see if the problem you are running into has already been addressed. -* If necessary, [open a new issue](https://github.com/Samsung/IoT.js/issues/new). +* If necessary, [open a new issue](https://github.com/Samsung/iotjs/issues/new). - Clearly describe the issue. + What did you expect to happen? + What actually happened instead? diff --git a/docs/Getting-Started.md b/docs/help/Getting-Started.md similarity index 77% rename from docs/Getting-Started.md rename to docs/help/Getting-Started.md index 7fe2bc235c..bf0e4e8c55 100644 --- a/docs/Getting-Started.md +++ b/docs/help/Getting-Started.md @@ -7,14 +7,14 @@ IoT.js is built based on JerryScript(lightweight JavaScript engine) and libuv fo * libuv: https://github.com/Samsung/libuv.git ### Build script -There is a script to help you build IoT.js called "[build.py](../tools/build.py)" in source repository. +There is a script to help you build IoT.js called "[build.py](../../tools/build.py)" in source repository. ### Supported platforms Current supported platforms are **Linux and NuttX** -* [Build for Linux](Build-for-Linux.md): Ubuntu 14.04 is used as a base platform. -* [Build for NuttX](Build-for-NuttX.md) -* [Build for Raspberry Pi 2](Build-for-RPi2.md) +* [Build for Linux](../build/Build-for-Linux.md): Ubuntu 14.04 is used as a base platform. +* [Build for NuttX](../build/Build-for-NuttX.md) +* [Build for Raspberry Pi 2](../build/Build-for-RPi2.md) ##### Platforms to support * OSX 10.10 as development host @@ -31,7 +31,7 @@ Current supported platforms are **Linux and NuttX** * Intel Edison * (and your contributions including above plans) -We will support the correct behavior of APIs for above environments. However, since IoT.js is targeting various kind IoT devices and platforms, single implementation cannot be the best practice for every environments. Therefore embedders should be in charge of optimization for their own environments. For more details on optimization, see the [Optimization Tips](Optimization-Tips.md) page. +We will support the correct behavior of APIs for above environments. However, since IoT.js is targeting various kind IoT devices and platforms, single implementation cannot be the best practice for every environments. Therefore embedders should be in charge of optimization for their own environments. For more details on optimization, see the [Optimization Tips](../devs/Optimization-Tips.md) page. ### For Developers @@ -76,9 +76,9 @@ build/x86_64-linux/debug/bin/iotjs tools/check_test.js -- start-from=test_consol 3. Set attributes on the test case if it needs in **attrs.js** where the directory of your test case belongs. #### Advanced Topics -You can refer to [Writing new IoT.js builtin module](Writing-New-Builtin-Module.md) and [Optimization Tips](Optimization-Tips.md) pages for detailed information. +You can refer to [Writing new IoT.js builtin module](../devs/Writing-New-Builtin-Module.md) and [Optimization Tips](../devs/Optimization-Tips.md) pages for detailed information. ### When something goes wrong -Please read the [Logging IoT.js execution](Logging-IoT.js-execution.md) page how to display and add log messages while developing. +Please read the [Logging IoT.js execution](../devs/Logging-IoT.js-execution.md) page how to display and add log messages while developing. -### [IoT.js API Reference](IoT.js-API-reference.md) +### [IoT.js API Reference](../api/IoT.js-API-reference.md) diff --git a/docs/Getting-involved.md b/docs/help/Getting-involved.md similarity index 50% rename from docs/Getting-involved.md rename to docs/help/Getting-involved.md index 4c7b2407e6..18f2d390ac 100644 --- a/docs/Getting-involved.md +++ b/docs/help/Getting-involved.md @@ -1,12 +1,12 @@ To contribute to the IoT.js Project (such as reporting bugs and submitting patches): * Follow the [Development Process](Development-Process.md) and [GitHub contributor guidelines](https://guides.github.com/activities/contributing-to-open-source/). * Add the [IoT.js DCO](IoT.js-Developer's-Certificate-of-Origin-1.0.md) signoff to each commit message during development. -* Add the [License](License.md) if you introduce any new source code or script files +* Add the [License](../License.md) if you introduce any new source code or script files -### [Community Guideline](Community-Guidelines) -### [IoT.js Developer's Certificate of Origin 1.0](IoT.js-Developer's-Certificate-of-Origin-1.0) -### [Coding Style Guideline](Coding-Style-Guideline) -### [Inside IoT.js](https://github.com/Samsung/iotjs/wiki/Inside%20IoT.js) -### [Development Process](Development-Process) -### [Patch Submission Process](Patch-Submission-Process) -### [Governance](Governance) \ No newline at end of file +### [Community Guideline](Community-Guidelines.md) +### [IoT.js Developer's Certificate of Origin 1.0](IoT.js-Developer's-Certificate-of-Origin-1.0.md) +### [Coding Style Guideline](Coding-Style-Guideline.md) +### [Inside IoT.js](../devs/Inside-IoT.js.md) +### [Development Process](Development-Process.md) +### [Patch Submission Process](Patch-Submission-Process.md) +### [Governance](Governance.md) \ No newline at end of file diff --git a/docs/help/Governance.md b/docs/help/Governance.md new file mode 100644 index 0000000000..67d352297a --- /dev/null +++ b/docs/help/Governance.md @@ -0,0 +1,81 @@ +* [Project Roles](#project-roles) + - [Contributor](#contributor) + - [Committer](#committer) + - [Maintainer](#maintainer) + - [Selection of Committers and Maintainers](#selection-of-committers-and-maintainers) + - [Revocation of Committers/Maintainers status](#revocation-of-committersmaintainers-status) + - [Steering Committee](#steering-committee) +* [Decision Making Process](#decision-making-process) + +## Project Roles + +The IoT.js project recognizes the following formal roles: Contributor, Committer, and Maintainer. + +* [Assigned people](Assigned-people.md) + +#### Contributor +A _Contributor_ is a developer who wishes to contribute to the project, at any level. Contributors who show dedication and skill are rewarded with additional rights and responsibilities. Their opinions weigh more when decisions are made, in a fully meritocratic fashion. + +Contributors are granted the following rights and responsibilities: +* Right to contribute code, documentation, translations, artwork, etc. +* Right to report defects (bugs) and suggestions for enhancement. +* Right to participate in the process of reviewing contributions by others. +* Right to initiate and participate in discussions in any communication methods. +* Right to approach any member of the community with matters they believe to be important. +* Responsibility to abide by decisions, once made. They are welcome to provide new, relevant information to reopen decisions. +* Responsibility for issues and bugs introduced by one’s own contributions. +* Responsibility to respect the rules of the community. +* Responsibility to provide constructive advice whenever participating in discussions and in the review of contributions. + +#### Committer +A _Committer_ is a Contributor who is also responsible for the maintenance of IoT.js source code. + +Committers have the following rights and responsibilities, in addition to those listed for Contributors: +* Right to set goals for the short and medium terms for the project being maintained, alongside the Maintainer. +* Right to exceptionally make more invasive changes to the source code, when required. +* Right to approve own contribution, after discussing with other Contributors. +* Right and responsibility to participate in the feature development process. +* Responsibility to ensure all contributions of the project have been reviewed within reasonable time. +* Responsibility to ensure the quality of the code to expected levels. +* Responsibility to monitor discussions in the community. +* Responsibility to participate in the quality verification and release process, when those happen. + +#### Maintainer +A _Maintainer_ is a Contributor who is also responsible for knowing, directing and anticipating the needs of a given IoT.js source code. + +Maintainers have the following rights and responsibilities, in addition to those listed for Contributors and Committers: +* right to set the overall organization of the source code of the project +* right to participate in the decision-making of the project, in conjunction with the Committers. +* Responsibility to ensure all contributions of the project have been reviewed within reasonable time. + - In the reviewing, only Maintainers can give binding scores(refer to [Approval Path for PR(Pull Request)](#approval-path-for-prpull-request)) + +#### Selection of Committers and Maintainers + +A candidate for the Committer role should be one of the Contributors who has submitted at least 10 non-trivial patches in project and has shown characteristics consistent with the requirements of the Committer role. +A candidate for the Maintainer role should be one of the Committers. +To be a candidate for the Committer or Maintainer, a Contributor can self-nominate with proper evidences. + +The selection process should be achieved by consensus of the Contributors active in. If consensus cannot be achieved, Maintainers will make the decision by voting. + +#### Revocation of Committers/Maintainers Status + +A Maintainer or a Committer who intentionally abused his review privilege may have it temporarily suspended on the request of other Committers or Maintainers. Committers and Maintainers not including the person under consideration should discuss on the revocation of the person. If consensus cannot be reached, Maintainers will make the decision by voting. + +#### Steering Committee + +_Steering Committee_ oversees and guides the progress of IoT.js project. + +The Steering Committee have the following responsibilities: + +* responsibility to oversee the health of the project community. +* responsibility to oversee and facilitate the development of the IoT.js source code under the governance rules of the IoT.js Open Source project. +* responsibility to guide and direct the development towards goals. +* responsibility to sets the goals and roadmap for the project + +## Decision Making Process + +Decisions in the IoT.js project are made always at the lowest level possible that is applicable for the decision in question. Decision makers always need to keep in mind the rules of community and the IoT.js goals and roadmap. + +* Individual Contributors are making decisions every time they submit changes in the form of deciding what to implement and how to go about it. +* Two or more Contributors also make decisions when participating in discussions in community, on bug or feature reports, in reviewing of commits. Their arguments in why a given decision should be made are part of the consensus that needs to be reached for the decision. At this level, the principle of meritocracy is important, as the opinion of those who have contributed more will be given more weight in the consensus-building. +* If those Contributors cannot agree and reach consensus on a decision, then IoT.js provides for decisions to be made by Maintainers following their own decision-making process, avoiding stalemates. \ No newline at end of file diff --git a/docs/IoT.js-Developer's-Certificate-of-Origin-1.0.md b/docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md similarity index 100% rename from docs/IoT.js-Developer's-Certificate-of-Origin-1.0.md rename to docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md diff --git a/docs/help/Patch-Submission-Process.md b/docs/help/Patch-Submission-Process.md new file mode 100644 index 0000000000..a6ad0c4341 --- /dev/null +++ b/docs/help/Patch-Submission-Process.md @@ -0,0 +1,40 @@ +The following guidelines on the submission process are provided to help you be more effective when submitting code to the IoT.js project. + +When development is complete, a patch set should be submitted via Github pull requests. A review of the patch set will take place. When accepted, the patch set will be integrated into the master branch, verified, and tested. It is then the responsibility of the authoring developer to maintain the code throughout its lifecycle. + +Please submit all patches in public by opening a pull request. Patches sent privately to Maintainers and Committers will not be considered. Because the IoT.js Project is an Open Source project, be prepared for feedback and criticism-it happens to everyone-. If asked to rework your code, be persistent and resubmit after making changes. + +#### 1. Scope the patch + +Smaller patches are generally easier to understand and test, so please submit changes in the smallest increments possible, within reason. Smaller patches are less likely to have unintended consequences, and if they do, getting to root cause is much easier for you and the Maintainers and Committers. Additionally, smaller patches are much more likely to be accepted. + +#### 2. Sign your work with the [IoT.js DCO](IoT.js-Developer's-Certificate-of-Origin-1.0.md) + +The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an Open Source patch. The sign-off is required for a patch to be accepted. + +#### 3. Open [a Github pull request](https://github.com/Samsung/iotjs/pulls) + +#### 4. What if my patch is rejected? + +It happens all the time, for many reasons, and not necessarily because the code is bad. Take the feedback, adapt your code, and try again. Remember, the ultimate goal is to preserve the quality of the code and maintain the focus of the Project through intensive review. + +Maintainers and Committers typically have to process a lot of submissions, and the time for any individual response is generally limited. If the reason for rejection is unclear, please ask for more information to the Maintainers and Committers. +If you have a solid technical reason to disagree with feedback and you feel that reason has been overlooked, take the time to thoroughly explain it in your response. + +#### 5. Code review + +Code review can be performed by all the members of the Project (not just Maintainers and Committers). Members can review code changes and share their opinion by comments with the following principles: +* Discuss code; never discuss the code's author. +* Respect and acknowledge contributions, suggestions, and comments. +* Listen and be open to all different opinions. +* Help each other. + +Changes are submitted via pull requests and only the Maintainers and Committers should approve or reject the pull request. +Changes should be reviewed in reasonable amount of time. Maintainers and Committers should leave changes open for some time (at least 1 full business day) so others can offer feedback. Review times increase with the complexity of the review. + +### Tips on GitHub Pull Requests +* Fork the GitHub repository(https://guides.github.com/activities/forking/) and clone it locally. +Connect your local repository to the original upstream repository by adding it as a remote. +Pull in upstream changes often to stay up-to-date so that when you submit your pull request, merge conflicts will be less likely. +* For more details, see [GitHub fork synching guidelines](https://help.github.com/articles/syncing-a-fork/). +[Create a branch](https://guides.github.com/introduction/flow/) for your edits. \ No newline at end of file