{"id":16189365,"url":"https://github.com/caolan/cpm","last_synced_at":"2025-03-19T03:30:52.027Z","repository":{"id":1013564,"uuid":"837304","full_name":"caolan/cpm","owner":"caolan","description":"CouchDB Package Manager - a tool for the management of CouchApps and associated libraries","archived":false,"fork":false,"pushed_at":"2011-02-08T18:00:12.000Z","size":268,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-28T15:05:37.351Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/caolan.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":"2010-08-14T07:20:38.000Z","updated_at":"2023-02-17T17:01:42.000Z","dependencies_parsed_at":"2022-08-16T11:50:12.926Z","dependency_job_id":null,"html_url":"https://github.com/caolan/cpm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caolan%2Fcpm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caolan%2Fcpm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caolan%2Fcpm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caolan%2Fcpm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/caolan","download_url":"https://codeload.github.com/caolan/cpm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243965774,"owners_count":20375917,"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":[],"created_at":"2024-10-10T07:35:13.169Z","updated_at":"2025-03-19T03:30:51.726Z","avatar_url":"https://github.com/caolan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CPM\n\n__WARNING: CPM is no longer supported, please see [kansojs.org](http://kansojs.org)__\n\nA [couchapp](http://couchapp.org) management tool built with\n[node.js](http://nodejs.org)\n\n* Understands JavaScript, which allows for a more relaxed JSON interpretation.\n* Object literals can replace folder strucutres where convenient.\n* Can evaluate CommonJS modules and use exported functions for list, show,\n  validation functions etc, __including the correct scope__.\n\n\n## Relax! - its 'not quite JSON'\n\nProperties can be added to the final design doc using a relaxed JSON format,\nwhere properties don't need to be properly quoted, and functions are converted\nto a string after loading. By writing CPM in node.js, parsing JavaScript\nis made much easier, allowing for a more flexible interpretation of structure.\n\nLet's take an example that uses the couchapp tool. It contains some views with\nboth map and reduce functions. With couchapp, this requires the following\ndirectory structure:\n\n    helloworld\n      |- views\n         |- view-name\n            |- map.js\n            |- reduce.js\n         |- another-view\n            |- map.js\n            |- reduce.js\n\nThere is something to be said for the simplicity of this approach, but now you\nhave to edit 4 files should you want to update your views. I find this format\na bit unwieldy and would prefer to have a single __views.js__ containing all\nof these functions. With CPM, this is possible!\n\n    helloworld\n      |- views.js\n\nviews.js:\n\n    {\n        \"view-name\": {\n            map: function (doc) {\n                ...\n            },\n            reduce: function () {\n                ...\n            }\n        },\n        \"another-view\": {\n            map: function (doc) {\n                ...\n            },\n            reduce: function () {\n                ...\n            }\n        }\n    }\n\nAlternatively, you could have a separate file for each view. You can substitute\nfolders for JSON structures and vice-versa, its totally flexible:\n\n    helloworld\n      |- views\n         |- view-name.js\n         |- another-view.js\n\nviews/view-name.js:\n\n    {\n        map: function (doc) {\n            ...\n        },\n        reduce: function () {\n            ...\n        }\n    }\n\nviews/another-view.js:\n\n    {\n        map: function (doc) {\n            ...\n        },\n        reduce: function () {\n            ...\n        }\n    }\n\n\n## CPM understands CommonJS too!\n\nOne thing I don't like about couchapp is the use of macros to include code from\nother files, especially when there is a CommonJS module system supported by\nCouchDB. Using \"require('a')\" makes more sense than: \"// !code a.js\"...\n'Magic' comments are __really bad__.\n\nThis is why CPM supports loading apps from CommonJS modules. The module\nsimply has to export rewrites, show and list functions and the like, and they\ncan be used in the resulting design document. What's more, these functions\n__operate in the scope they are defined__. The functions are not simply\nconverted to a string and inserted into the design document, they are executed\nin the module's context!\n\nThis has potentially interesting applications for pure JavaScript frameworks\non top of CPM, allowing the generation of URLs, show and list functions\netc... using an imported framework. Think sammy.js for the server-side. Or,\nhow about auto-generating forms and validation rules based on JavaScript type\ndefinitions?\n\n### Using context in a commonjs show function:\n\n    function greet(name) {\n        return 'hello ' + name;\n    }\n\n    exports.shows = {\n        example: function (doc, req) {\n            return greet('world');\n        }\n    };\n\nIn CPM, this 'just works'.\n\nThe one caveat, is that view functions cannot be defined inside a CommonJS\nmodule, this is because CouchDB needs to know when the views property has\nchanged so it can rebuild its index. This prevents us running it from the\nCommonJS module.\n\n\n## Installation\n\nClone this repository, cd to the cloned directory, then:\n\n    make \u0026\u0026 sudo make install\n\n\n## Usage\n\n    help                                Display this help message\n    push url [package]                  Upload a package to a CouchDB database\n    publish package [repository]        Publish a package to a repository\n    unpublish package [repository]      Unpublish a package from a repository\n    list [repository]                   Lists the packages available in a repository\n    info package [repository]           Show information on a package\n    clone url path                      Clone a package from a CouchDB database\n\nThe repository tools are currently quite basic, and still in development.\n\n\n## App Config (package.json)\n\nThe package.json file stores information about your project.\nThis is _real_ JSON (for now), obey the rules!\n\n### Example\n\n    {\n        \"name\": \"app name\",       \u003c-- the name of your app\n        \"version\": \"0.0.1\",       \u003c-- the version of your app\n        \"description\": \"testing\", \u003c-- a description of your app\n        \"app\": \"lib/app\",         \u003c-- use the exported properties of this\n                                      commonjs module for show / list functions\n                                      etc. [optional]\n        \"paths\": {                \u003c-- paths to load data from [all optional]\n            \"properties\": [            \u003c-- load as properties of the design doc\n                \"views\",               \u003c-- ...can be folders\n                \"fulltext.js\"          \u003c-- ...or single files\n            ],\n            \"modules\": \"lib\",          \u003c-- load commonjs modules from here\n            \"attachments\": \"static\"    \u003c-- load attachments from this dir,\n                                           notice path values can be arrays\n                                           or strings\n        }\n    }\n\nThe package.json file should be stored in the project directory and will be\nautomatically loaded by CPM when using this directory as a source / target.\n\n\n## CPM Preferences (.cpmrc)\n\nYour CPM preferences are stored in .cpmrc files. CPM will work without any\n.cpmrc file defined, and will just use the default settings.\n\nSettings are loaded in preference order, starting with the default settings\nbuilt into CPM, which are overridden by any settings in ~/.cpmrc, which in\nturn can be overridden by a .cpmrc file in your project directory.\n\nOne useful trick when developing an app is to add a named CouchDB to a .cpmrc\nfile in your project:\n\n    {\n        \"instances\": {\n            \"dev\": \"http://localhost:5984/myapp\"\n        }\n    }\n\nYou can now use this as a target in cpm commands:\n\n    cpm push dev\n\nYou might want to make sure that this file is ignored by your version control\nso that you don't accidentally commit your password to the repository.\n\nThe format of the rest of the .cpmrc file is currently still quite fluid, look\nat the code in lib/settings.js for more information on how these settings are\ndefined.\n\n\n## Repositories\n\nThis feature is still in development, but if you want to try it out you can\ncreate a repository by pushing the repository couchapp in the cpm directory.\nYou can then use the database you pushed the app to as a repository.\n\nIf you add dependencies to your package.json, they will be loaded from the\nrepository defined in your CPM preferences.\n\n__package.json__\n\n    {\n        \"name\": \"dep_test\",\n        \"description\": \"Dependency test package\",\n        \"version\": \"0.1.0\",\n        \"dependencies\": {\n            \"dep_test_lib\": [    \u003c-- the dependencies are keyed by\n                \"0.0.2\",             package name, and the value should\n                \"0.0.3\"              be an array of version numbers or\n            ]                        a single version number as a string\n        }\n    }\n\n__.cpmrc__\n\n    {\n        \"repositories\": [\n            \"http://localhost:5984/repository\"    \u003c-- this is where you pushed the\n                                                      repository app to. more\n                                                      can be added here if you wish,\n                                                      and dependencies will be\n                                                      resolved by looking at the\n                                                      first repository, then going\n                                                      through the list in order,\n                                                      stopping on the first match.\n        ]\n    }\n\nLoaded dependencies will be uploaded as seperate design docs when pushed to a\nCouchDB database, and are also available at the loading stage. This means\ndependencies are available for generating exports from a commonjs module:\n\n    var mylib = require('../dependency_name/mylib');\n\n    exports.rewrites = mylib.generateURLs();\n\nIn this way it's possible to break-up and share common libraries between your apps,\nand also load frameworks for building your app.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaolan%2Fcpm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcaolan%2Fcpm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaolan%2Fcpm/lists"}