# Introduction
Codeify is a pure Python code-generation utility for accelerating development in any platform / environment.
Codeify's code generator processes an input directory and produces an output directory with similar structure
along with the aid of a provided specification file and Jinja templates for generated outputs.
# Usage
Codeify should be used for development-only purposes. This should not be tied into any critical processes
and should be seen only as a tool to speed up development.
# Example
Using a sample input directory with the following files:
**`spec.yaml`**
```
---
structs:
Account:
fields:
id: { type: int }
name: { type: std::string }
CheckingAccount:
fields:
amount: { type: double }
_extends: Account
SavingsAccount:
fields:
amount: { type: double }
interest_rate: { type: double }
_extends: Account
```
**`main.cpp.j2`**
```
{% for name, value in structs.items() %}
#include "{{ name }}.h"
{% endfor %}
int main()
{
// TODO: Implement
return 0;
}
```
**`class.j2`**
```
#pragma once
namespace structs
{
class {{ class_name }}{% if class_data._extends %} : {{ class_data._extends }}{% endif %}
{
private:
{% for field_name, field in class_data.fields.items() %}
{{ field.type }} {{ field_name }}_;
{% endfor %}
public:
{% for field_name, field in class_data.fields.items() %}
{{ field.type }} get{{ pascal_name(field_name) }}() const
{
return {{ field_name }}_;
}
void set{{ pascal_name(field_name) }}({{ field.type }} && value)
{
{{ field_name }}_ = std::move(value);
}
{% endfor %}
};
}
```
**`.codeify`**
```
---
ignore: [ spec.yaml, class.j2 ]
generate:
{% for name, data in structs.items() %}
{{ name }}.h:
input: class.j2
data:
class_name: {{ name }}
class_data: {{ data }}
{% endfor %}
```
You can then run Codeify on the input directory (`$INPUT`) specifying both an output directory (`$OUTPUT`) and a specification file (`$INPUT/spec.yaml`):
```
codeify generate -i $INPUT -o $OUTPUT -s $INPUT/spec.yaml
```
Your output directory (`$OUTPUT`) should now contain the following files:
- Account.h
- CheckingAccount.h
- SavingsAccount.h
- main.cpp
The three `Account` header files are generated from `class.j2` specified through a directory context file (`.codeify`). `main.cpp` was generated from `main.cpp.j2`.
These were all generated with the use of the `spec.yaml` file providing the inputs.
# Text Insertion
Codeify supports in-place splicing lines into files when files cannot be generated but modified.
Some example commands illustrate this functionality on imaginary files:
```
# Insert immediately before a line
codeify insert "[ ] turn off the lights" --before "\[.\] close the door" -i TODO.txt
# Insert immediately after a line
codeify insert "(C) Beeblebrox Enterprises" --after "author: Zaphod .*" -i CONTRIBUTORS.md
# Append a line
codeify insert "rsync -rv $HOME/Pictures $BACKUP" -i backup_files.sh
```
# Code generation on-the-fly
For generating code ad-hoc with some command line arguments, you can create a single Jinja template and define parameters on the command line to produce a
code-generated output. This can be used for creating source code files or copy-pasting source code segments to an IDE or text editor.
The example template file below and command line output demonstrates this feature:
**`php.tpl`**
```
{%- set php_fields = [] -%}
{%- for field in fields -%}
{%- set _ = php_fields.append('$'+field) -%}
{%- endfor -%}
{%- if namespace -%}
namespace {{ namespace }};
{% endif -%}
class {{ class_name }}
{
{%- for field in fields %}
private ${{ field }};
{%- endfor %}
public function __construct({{ php_fields | join(', ') }})
{
{%- for field in fields %}
$this->{{ field }} = ${{ field }};
{%- endfor %}
}
{% for field in fields %}
public function get{{ (field[0] | upper) + field[1:] }}()
{
return $this->{{ field }};
}
{% endfor %}
}
```
From the command line: `codeify echo php.tpl -d class_name=User -d "fields=[userId,username,passwordHash,name,email,activated]" -d namespace=App`
The following output is generated:
```
namespace App;
class User
{
private $userId;
private $username;
private $passwordHash;
private $name;
private $email;
private $activated;
public function __construct($userId, $username, $passwordHash, $name, $email, $activated)
{
$this->userId = $userId;
$this->username = $username;
$this->passwordHash = $passwordHash;
$this->name = $name;
$this->email = $email;
$this->activated = $activated;
}
public function getUserId()
{
return $this->userId;
}
public function getUsername()
{
return $this->username;
}
public function getPasswordHash()
{
return $this->passwordHash;
}
public function getName()
{
return $this->name;
}
public function getEmail()
{
return $this->email;
}
public function getActivated()
{
return $this->activated;
}
}
```
# Text Replacement
For projects and source code that require mostly minor text changes (e.g. renaming a namespace), Codeify can be instructed to find and replace all instances of a string on a per-line basis within all files in a supplied directory. All substitutions are provided either via Yaml file (in key-value form) or command line definitions (in "key=value" form). The results are output into a separate directory.
For example, the command line `codeify replace -i $INPUT/ -o $OUTPUT/ -d "::v1_1::=::v1_2::"` will replace all instances of `::v1_1::` with `::v1_2::` in all files within the directory `$INPUT` and outputs the updated files in the same structure in the directory `$OUTPUT`. Certain file names or types can be ignored if specified with the `--ignore` argument for each pattern.
An example with the `--ignore` argument is below:
```
codeify replace -i $INPUT/ -o $OUTPUT/ -d "flip=flop" --ignore "\*.bin"
```
Raw data
{
"_id": null,
"home_page": "https://www.nuradius.com",
"name": "codeify",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "",
"author": "Nuradius Software",
"author_email": "todd@datacomponents.net",
"download_url": "",
"platform": null,
"description": "# Introduction\n\nCodeify is a pure Python code-generation utility for accelerating development in any platform / environment.\n\nCodeify's code generator processes an input directory and produces an output directory with similar structure\nalong with the aid of a provided specification file and Jinja templates for generated outputs.\n\n# Usage\n\nCodeify should be used for development-only purposes. This should not be tied into any critical processes\nand should be seen only as a tool to speed up development.\n\n# Example\n\nUsing a sample input directory with the following files:\n\n**`spec.yaml`**\n```\n---\nstructs:\n Account:\n fields:\n id: { type: int }\n name: { type: std::string }\n\n CheckingAccount:\n fields:\n amount: { type: double }\n _extends: Account\n\n SavingsAccount:\n fields:\n amount: { type: double }\n interest_rate: { type: double }\n _extends: Account\n```\n\n**`main.cpp.j2`**\n```\n{% for name, value in structs.items() %}\n#include \"{{ name }}.h\"\n{% endfor %}\n\nint main()\n{\n // TODO: Implement\n return 0;\n}\n```\n\n**`class.j2`**\n```\n#pragma once\n\nnamespace structs\n{\n class {{ class_name }}{% if class_data._extends %} : {{ class_data._extends }}{% endif %}\n {\n private:\n {% for field_name, field in class_data.fields.items() %}\n {{ field.type }} {{ field_name }}_;\n {% endfor %}\n public:\n {% for field_name, field in class_data.fields.items() %}\n {{ field.type }} get{{ pascal_name(field_name) }}() const\n {\n return {{ field_name }}_;\n }\n\n void set{{ pascal_name(field_name) }}({{ field.type }} && value)\n {\n {{ field_name }}_ = std::move(value);\n }\n\n {% endfor %}\n };\n}\n```\n\n**`.codeify`**\n```\n---\nignore: [ spec.yaml, class.j2 ]\ngenerate:\n{% for name, data in structs.items() %}\n {{ name }}.h:\n input: class.j2\n data:\n class_name: {{ name }}\n class_data: {{ data }}\n{% endfor %}\n\n```\n\nYou can then run Codeify on the input directory (`$INPUT`) specifying both an output directory (`$OUTPUT`) and a specification file (`$INPUT/spec.yaml`):\n\n```\ncodeify generate -i $INPUT -o $OUTPUT -s $INPUT/spec.yaml\n```\n\nYour output directory (`$OUTPUT`) should now contain the following files:\n - Account.h\n - CheckingAccount.h\n - SavingsAccount.h\n - main.cpp\n\nThe three `Account` header files are generated from `class.j2` specified through a directory context file (`.codeify`). `main.cpp` was generated from `main.cpp.j2`.\nThese were all generated with the use of the `spec.yaml` file providing the inputs.\n\n# Text Insertion\n\nCodeify supports in-place splicing lines into files when files cannot be generated but modified.\n\nSome example commands illustrate this functionality on imaginary files:\n```\n# Insert immediately before a line\ncodeify insert \"[ ] turn off the lights\" --before \"\\[.\\] close the door\" -i TODO.txt\n\n# Insert immediately after a line\ncodeify insert \"(C) Beeblebrox Enterprises\" --after \"author: Zaphod .*\" -i CONTRIBUTORS.md\n\n# Append a line\ncodeify insert \"rsync -rv $HOME/Pictures $BACKUP\" -i backup_files.sh\n```\n\n# Code generation on-the-fly\n\nFor generating code ad-hoc with some command line arguments, you can create a single Jinja template and define parameters on the command line to produce a\ncode-generated output. This can be used for creating source code files or copy-pasting source code segments to an IDE or text editor.\n\nThe example template file below and command line output demonstrates this feature:\n\n**`php.tpl`**\n```\n{%- set php_fields = [] -%}\n{%- for field in fields -%}\n {%- set _ = php_fields.append('$'+field) -%}\n{%- endfor -%}\n{%- if namespace -%}\nnamespace {{ namespace }};\n\n{% endif -%}\nclass {{ class_name }}\n{\n {%- for field in fields %}\n private ${{ field }};\n {%- endfor %}\n\n public function __construct({{ php_fields | join(', ') }})\n {\n {%- for field in fields %}\n $this->{{ field }} = ${{ field }};\n {%- endfor %}\n }\n{% for field in fields %}\n public function get{{ (field[0] | upper) + field[1:] }}()\n {\n return $this->{{ field }};\n }\n{% endfor %}\n}\n```\n\nFrom the command line: `codeify echo php.tpl -d class_name=User -d \"fields=[userId,username,passwordHash,name,email,activated]\" -d namespace=App`\n\nThe following output is generated:\n```\nnamespace App;\n\nclass User\n{\n private $userId;\n private $username;\n private $passwordHash;\n private $name;\n private $email;\n private $activated;\n\n public function __construct($userId, $username, $passwordHash, $name, $email, $activated)\n {\n $this->userId = $userId;\n $this->username = $username;\n $this->passwordHash = $passwordHash;\n $this->name = $name;\n $this->email = $email;\n $this->activated = $activated;\n }\n\n public function getUserId()\n {\n return $this->userId;\n }\n\n public function getUsername()\n {\n return $this->username;\n }\n\n public function getPasswordHash()\n {\n return $this->passwordHash;\n }\n\n public function getName()\n {\n return $this->name;\n }\n\n public function getEmail()\n {\n return $this->email;\n }\n\n public function getActivated()\n {\n return $this->activated;\n }\n\n}\n```\n\n# Text Replacement\n\nFor projects and source code that require mostly minor text changes (e.g. renaming a namespace), Codeify can be instructed to find and replace all instances of a string on a per-line basis within all files in a supplied directory. All substitutions are provided either via Yaml file (in key-value form) or command line definitions (in \"key=value\" form). The results are output into a separate directory.\n\nFor example, the command line `codeify replace -i $INPUT/ -o $OUTPUT/ -d \"::v1_1::=::v1_2::\"` will replace all instances of `::v1_1::` with `::v1_2::` in all files within the directory `$INPUT` and outputs the updated files in the same structure in the directory `$OUTPUT`. Certain file names or types can be ignored if specified with the `--ignore` argument for each pattern.\n\nAn example with the `--ignore` argument is below:\n\n```\ncodeify replace -i $INPUT/ -o $OUTPUT/ -d \"flip=flop\" --ignore \"\\*.bin\"\n```\n",
"bugtrack_url": null,
"license": "Apache Software License",
"summary": "Python-based development utilities",
"version": "0.3.3",
"project_urls": {
"Homepage": "https://www.nuradius.com"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "23434bc250654b12f8fa1a0c11a3a27099d56924a3860b32cead5bc1bbd60fe8",
"md5": "e03b0db6d65ce1070a0da61833274630",
"sha256": "21827a3ba9c09f62f2d31434e614f1336fbe159358b7b56e1966d83d0a591c46"
},
"downloads": -1,
"filename": "codeify-0.3.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e03b0db6d65ce1070a0da61833274630",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 9748,
"upload_time": "2024-02-26T04:54:28",
"upload_time_iso_8601": "2024-02-26T04:54:28.596722Z",
"url": "https://files.pythonhosted.org/packages/23/43/4bc250654b12f8fa1a0c11a3a27099d56924a3860b32cead5bc1bbd60fe8/codeify-0.3.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-02-26 04:54:28",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "codeify"
}