{"id":26395770,"url":"https://github.com/tamada/fritter","last_synced_at":"2025-03-17T11:19:14.790Z","repository":{"id":54277869,"uuid":"333117127","full_name":"tamada/fritter","owner":"tamada","description":"Small object programming/Object-oriented programming exercise checker.","archived":false,"fork":false,"pushed_at":"2021-02-27T13:44:32.000Z","size":517,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2023-03-22T16:29:43.432Z","etag":null,"topics":["code-quality-analyzer","java-11","object-oriented-programming","small-object-detection"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tamada.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-26T14:51:32.000Z","updated_at":"2021-02-27T08:30:16.000Z","dependencies_parsed_at":"2022-08-13T10:50:14.500Z","dependency_job_id":null,"html_url":"https://github.com/tamada/fritter","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamada%2Ffritter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamada%2Ffritter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamada%2Ffritter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamada%2Ffritter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tamada","download_url":"https://codeload.github.com/tamada/fritter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244022679,"owners_count":20385134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-quality-analyzer","java-11","object-oriented-programming","small-object-detection"],"created_at":"2025-03-17T11:19:14.132Z","updated_at":"2025-03-17T11:19:14.782Z","avatar_url":"https://github.com/tamada.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fritter\r\n\r\n[![build](https://github.com/tamada/fritter/workflows/build/badge.svg)](https://github.com/tamada/fritter/actions?query=workflow%3Abuild)\r\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/2efb1d837efe40019652723687ac9173)](https://www.codacy.com/gh/tamada/fritter/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=tamada/fritter\u0026amp;utm_campaign=Badge_Grade)\r\n[![codecov](https://codecov.io/gh/tamada/fritter/branch/main/graph/badge.svg?token=P1BFSTXHH5)](https://codecov.io/gh/tamada/fritter)\r\n[![Coverage Status](https://coveralls.io/repos/github/tamada/fritter/badge.svg?branch=main)](https://coveralls.io/github/tamada/fritter?branch=main)\r\n\r\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue?logo=spdx)](https://raw.githubusercontent.com/tamada/fritter/main/LICENSE)\r\n[![Version](https://img.shields.io/badge/Version-1.0.0-blue)](https://github.com/tamada/fritter/releases/tag/v1.0.0)\r\n\r\n[![Docker](https://img.shields.io/badge/Docker-ghcr.io%2Ftamada%2Ffritter%3A1.0.0-green?logo=docker)](https://github.com/users/tamada/packages/container/package/fritter)\r\n[![Homebrew](https://img.shields.io/badge/Homebrew-tamada/brew/fritter-green?logo=homebrew)](https://github.com/tamada/homebrew-brew)\r\n\r\n[![Discussion](https://img.shields.io/badge/GitHub-Discussion-orange?logo=github)](https://github.com/tamada/fritter/discussions)\r\n\r\nSmall object programming/Object oriented exercise checker.\r\n\r\nThis product extends [tamada/9rules](https://github.com/tamada/9rules).\r\nThe superior points of `fritter` than 9rules are as follows.\r\n\r\n*  Simplify the class relationships from 9rules.\r\n    *  In the case of `9rules`, it becomes to complicated relationships among classes to satisfy the 9rules itself.\r\n    *  Then, `fritter` prioritizes the understandability of the source codes even if to not satisfy the rules of itself.\r\n*  Introduce more rules, and ease to add more rules.\r\n    *  This is the side effect of the above point.\r\n    *  To introduce the new rule, we provide only two classes which are subclasses of `Validator` and `ValidatorService`.\r\n*  Ease to customize the parameters for validators.\r\n    *  All parameters are read from configuration files.\r\n    *  The configuration files are given by `--level` option or `--config` option.  `fritter` defines the parameters by json formatted config file also `level`.\r\n*  Enable to select the output formats.\r\n    *  `fritter` provides `json`, `xml`, and `markdown` format as result.\r\n* Thread supports.\r\n    *  `fritter` uses the threads by user requests for each analyzing target.\r\n\r\n## Description\r\n\r\nThe book titled '[The ThoughtWorks Anthology: Essays on Software Technology and Innovation](https://pragprog.com/book/twa/thoughtworks-anthology)' are published.\r\nChapter 6 in the book introduces object calisthenics for better software design.\r\nThe rules shown in the book are as follows.\r\n\r\n1.  Use 1 level of indentation per method (`indent_level`), `DONE`\r\n2.  Do not use the `else` keyword (`no_else`), `DONE`\r\n3.  Wrap all primitives and strings (`primitive_wrapping`), `DONE`\r\n4.  Use only 1 dot per line (`one_dot_per_line`), `DONE`\r\n5.  Do not abbreviate (`no_abbrev`),\r\n6.  Keep all entities small,\r\n    *  50 lines in a source file (`lines_of_class`), `DONE`\r\n    *  3 lines in a method (`lines_of_method`), and `DONE`\r\n    *  10 classses in a package (`classes_in_package`).\r\n7.  Do not use any classes with more than 2 instance variables (`field_count`), `DONE`\r\n8.  Use first-class collections (`first_class_collection`), and `DONE`\r\n9.  Do not use any getters/setters/properties (`no_accessor`) `DONE`\r\n\r\nUnfortunately, to confirm obeying the rules is by a human eye.\r\nTherefore, this tool was developed to validate the rules automatically by analyzing given Java source codes.\r\nBy the way, this tool is programed to obey above rules.\r\n\r\n### Additional rules\r\n\r\nThe following rules are the additional rules for more analysis.\r\n\r\n10.  Do not use any methods with more than 2 local variables (`local_variable_count`), `DONE`\r\n11.  Do not use `static` method except `main` method (`no_static_method`), `DONE`\r\n12.  Do not create an array (`no_new_array`), `DONE`\r\n13.  Do not use `System.exit` (`no_system_exit`) except `main` method, `DONE`\r\n14.  Do not use `\\n` in the `printf` formatter (`no_return_code_in_printf`), and `DONE`\r\n15.  Do not use only single character in the variable name, except loop control variables (`single_character_name`). `DONE`\r\n\r\n## Usage\r\n\r\n```shell\r\nUsage: fritter [-hinstV] [-c=CONFIG] [-f=FORMAT] [-l=LEVEL]\r\n               SOURCE_FILEs|SOURCE_DIRs...\r\nSmall object programming checker.\r\n      SOURCE_FILEs|SOURCE_DIRs...\r\n                            Java source files and/or directories containing\r\n                              Java source files.\r\n  -c, --config=CONFIG       specifies the configuration file.\r\n  -f, --format=FORMAT       specifies the resultant format. Default is json.\r\n                            Available values: json, markdown, yaml, and xml\r\n  -h, --help                Show this help message and exit.\r\n  -i, --no-validator-info   does not show the validator information for\r\n                              analyses.\r\n  -l, --level=LEVEL         specifies the strict level. Default is default.\r\n                            Available values: strict, general, rough, and\r\n                              default.\r\n  -n, --no-summary          does not show the summary of analysis.\r\n  -s, --show-no-violated-files\r\n                            shows file names with no violations.\r\n  -t, --with-threads        use threads for validations.\r\n  -V, --version             Print version information and exit.\r\n```\r\n\r\n## Config format\r\n\r\nThe format of config file must be JSON, like as follows.\r\n\r\n```json\r\n{\r\n  \"name\": \"default\",\r\n  \"validators\": [\r\n    \"indent_level\",\r\n    \"no_else\",\r\n    \"primitive_wrapping\",\r\n    \"dot_count_per_line\",\r\n    \"no_abbrev\",\r\n    \"lines_of_class\",\r\n    \"lines_of_method\",\r\n    \"classes_in_package\",\r\n    \"field_count\",\r\n    \"first_class_collection\",\r\n    \"no_accessor\",\r\n    \"variable_count\",\r\n    \"no_static_method\",\r\n    \"no_new_array\",\r\n    \"no_system_exit\",\r\n    \"no_return_code_in_printf\",\r\n    \"single_character_name\"\r\n  ],\r\n  \"parameters\": {\r\n    \"indent_level\": 1,\r\n    \"dot_count_per_line\": 1,\r\n    \"lines_of_class\": 50,\r\n    \"lines_of_method\": 3,\r\n    \"classes_in_package\": 10,\r\n    \"field_count\": 2,\r\n    \"variable_count\": 2\r\n  }\r\n}\r\n```\r\n\r\n## Result example\r\n\r\n### Json\r\n\r\nThe following json is validating `src/test/resources/projects/examples/HelloWorld.java` with no options, and formatted with `jq` command.\r\n\r\n```json5\r\n{\r\n   \"date\": \"2021-02-01T23:37:08.966582\",\r\n   \"validators\": [\r\n      \"indent_level\",\r\n      \"no_else\",\r\n      \"primitive_wrapping\",\r\n      \"dot_count_per_line\",\r\n      \"lines_of_class\",\r\n      \"lines_of_method\",\r\n      \"field_count\",\r\n      \"first_class_collection\",\r\n      \"no_accessor\",\r\n      \"no_static_method\",\r\n      \"no_new_array\",\r\n      \"no_system_exit\",\r\n      \"no_return_code_in_printf\",\r\n      \"single_character_name\"\r\n   ],\r\n   \"results\": [\r\n      {\r\n         \"base\": \"src/test/resources/projects/examples/HelloWorld.java\",\r\n         \"violations\": [\r\n            {\r\n               \"file\": \"\",\r\n               \"messages\": [\r\n                  {\r\n                     \"line\": 10,\r\n                     \"key\": \"lines_of_method\",\r\n                     \"message\": \"lines of method is 4, more than 3\"\r\n                  },\r\n                  {\r\n                     \"line\": 19,\r\n                     \"key\": \"lines_of_method\",\r\n                     \"message\": \"lines of method is 4, more than 3\"\r\n                  },\r\n                  {\r\n                     \"line\": 15,\r\n                     \"key\": \"no_accessor\",\r\n                     \"message\": \"getMessage: no getter method\"\r\n                  },\r\n                  {\r\n                     \"line\": 2,\r\n                     \"key\": \"no_static_method\",\r\n                     \"message\": \"violatedMethod: no static method except main method\"\r\n                  },\r\n                  {\r\n                     \"line\": 12,\r\n                     \"key\": \"no_system_exit\",\r\n                     \"message\": \"no System.exit except main method\"\r\n                  },\r\n                  {\r\n                     \"line\": 11,\r\n                     \"key\": \"no_return_code_in_printf\",\r\n                     \"message\": \"no '\\n', use '%n' in printf\"\r\n                  }\r\n               ]\r\n            }\r\n         ]\r\n      }\r\n   ],\r\n   \"summary\": {\r\n      \"violated-files\": 1,\r\n      \"total-files\": 1,\r\n      \"violated-file-count\": 6\r\n   }\r\n}\r\n```\r\n\r\n### Xml\r\n\r\nThe following xml is validating `src/test/resources/projects/examples/Primes.java` with `-f xml` options, and formatted with `xmllint` command (`xmllint --format -`).\r\n\r\n```xml\r\n\u003c?xml version=\"1.0\"?\u003e\r\n\u003cfritter\u003e\r\n   \u003cvalidators\u003e\r\n      \u003cvalidator\u003eindent_level\u003c/validator\u003e\r\n      \u003cvalidator\u003eno_else\u003c/validator\u003e\r\n      \u003cvalidator\u003eprimitive_wrapping\u003c/validator\u003e\r\n      \u003cvalidator\u003edot_count_per_line\u003c/validator\u003e\r\n      \u003cvalidator\u003elines_of_class\u003c/validator\u003e\r\n      \u003cvalidator\u003elines_of_method\u003c/validator\u003e\r\n      \u003cvalidator\u003efield_count\u003c/validator\u003e\r\n      \u003cvalidator\u003efirst_class_collection\u003c/validator\u003e\r\n      \u003cvalidator\u003eno_accessor\u003c/validator\u003e\r\n      \u003cvalidator\u003eno_static_method\u003c/validator\u003e\r\n      \u003cvalidator\u003eno_new_array\u003c/validator\u003e\r\n      \u003cvalidator\u003eno_system_exit\u003c/validator\u003e\r\n      \u003cvalidator\u003eno_return_code_in_printf\u003c/validator\u003e\r\n      \u003cvalidator\u003esingle_character_name\u003c/validator\u003e\r\n   \u003c/validators\u003e\r\n   \u003cresults\u003e\r\n      \u003cresult\u003e\r\n         \u003cbase-directory\u003esrc/test/resources/projects/examples/Primes.java\u003c/base-directory\u003e\r\n         \u003cfiles\u003e\r\n            \u003cfile\u003e\r\n               \u003cfile-name/\u003e\r\n               \u003cviolations\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003eindent_level\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e17\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003eprint: indent level is 2, more than 1\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003eindent_level\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e29\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003esieves: indent level is 2, more than 1\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003eno_else\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e51\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003eno else statement\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003elines_of_class\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e3\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003elines of class is 55, more than 50\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003elines_of_method\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e4\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003elines of method is 5, more than 3\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003elines_of_method\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e10\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003elines of method is 15, more than 3\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003elines_of_method\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e26\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003elines of method is 8, more than 3\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003elines_of_method\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e35\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003elines of method is 5, more than 3\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003elines_of_method\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e41\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003elines of method is 5, more than 3\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003elines_of_method\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e47\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003elines of method is 6, more than 3\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n                  \u003cviolation\u003e\r\n                     \u003cvalidator-type\u003eno_new_array\u003c/validator-type\u003e\r\n                     \u003clocation\u003e\r\n                        \u003cline-number\u003e42\u003c/line-number\u003e\r\n                     \u003c/location\u003e\r\n                     \u003cmessage\u003edo not use array, use List instead\u003c/message\u003e\r\n                  \u003c/violation\u003e\r\n               \u003c/violations\u003e\r\n            \u003c/file\u003e\r\n         \u003c/files\u003e\r\n      \u003c/result\u003e\r\n   \u003c/results\u003e\r\n   \u003csummary\u003e\r\n      \u003cviolated-file-count\u003e1\u003c/violated-file-count\u003e\r\n      \u003ctarget-file-count\u003e1\u003c/target-file-count\u003e\r\n      \u003cviolation-count\u003e11\u003c/violation-count\u003e\r\n   \u003c/summary\u003e\r\n\u003c/fritter\u003e\r\n```\r\n\r\n### Markdown\r\n\r\nThe following markdown is validating `src/test/resources/projects/examples/StatsValues.java` with `-f markdown` options.\r\n\r\n```markdown\r\n# fritter results\r\n\r\nDate: 2021-02-01T23:47:02.609847\r\n\r\n## Validators\r\n\r\n* indent_level\r\n* no_else\r\n* primitive_wrapping\r\n* dot_count_per_line\r\n* lines_of_class\r\n* lines_of_method\r\n* field_count\r\n* first_class_collection\r\n* no_accessor\r\n* no_static_method\r\n* no_new_array\r\n* no_system_exit\r\n* no_return_code_in_printf\r\n* single_character_name\r\n\r\n## Results\r\n\r\n### src/test/resources/projects/examples/StatsValues.java\r\n\r\n#### \r\n\r\n##### Violations\r\n\r\n* indent_level (line: 23)\r\n    * print: indent level is 2, more than 1\r\n* lines_of_method (line: 13)\r\n    * lines of method is 5, more than 3\r\n* lines_of_method (line: 19)\r\n    * lines of method is 9, more than 3\r\n* lines_of_method (line: 29)\r\n    * lines of method is 5, more than 3\r\n* lines_of_method (line: 35)\r\n    * lines of method is 4, more than 3\r\n* lines_of_method (line: 40)\r\n    * lines of method is 5, more than 3\r\n* field_count (lines: 9, 10, 11)\r\n    * field count is 3, more than 2\r\n* first_class_collection (lines: 9, 10, 11)\r\n    * not first class collection\r\n\r\n## Summary\r\n\r\n* violated files: 1\r\n* total files: 1\r\n* violated file count: 8\r\n```\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftamada%2Ffritter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftamada%2Ffritter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftamada%2Ffritter/lists"}