proj-man-zdo


Nameproj-man-zdo JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
Summaryproject management zdo
upload_time2025-08-07 03:21:35
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords project management
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            * website: <https://arrizza.com/python-proj-man-zdo.html>
* installation: see <https://arrizza.com/setup-common.html>

## Summary

This project is used to manage many projects from the command line.

If you have common commands that you need to run across many projects, you would
normally need to cd into each directory and manually invoke that command.
This module lets you automate those activities.

For example, you can visit all or a subset of all the projects and invoke a command in each one.
Or you can write a more complex command in python and invoke it in any directories you need to.

## run

Note: the examples here use ```sample-zdo```.
You should probably rename it to ```zdo``` to simplify typing it on the command line.
(I used sample-zdo since I already have a zdo to manage the 60+ repos I have.)

```bash
./sample-zdo            <== shows list of commands
./sample-zdo one-off    <== runs the one-off command
```

## set up repos.py

* fill in repos.py with the directories/repos/projects you want to work with.

```text
$ sample-zdo run all2 pwd
     group: "all2"
---> running cmd: pwd in project: /home/arrizza/projects/web/xplat-utils
 --  /home/arrizza/projects/web/xplat-utils] 1
OK   cmd rc=0
<snip>
---> total run :  11      <= should be total #repos/projects you've added to repos.py
OK   total fail:   0
```

The directories printed out by ```pwd``` should be the correct for each project in repos.py

Now try the groups you've named:

```text
$ sample-zdo run rb pwd
     group: "rb"
<snip>
---> total run :   3
OK   total fail:   0
```

## nesting calls

Note: you can nest calls to sample-zdo:

```text
$ sample-zdo run all sample-zdo search
     group: "rb"
<snip>
---> total run :   3
OK   total fail:   0
```

## adding commands

See sample/app.py for an example.

* create the function. The signature is no parameters, returns an error code (0 for no errors)/

```text
def one_off(self):
    errs = 0
    <snip>
    return errs
```

* add the command

```
self.add_cmd('one-off', self.one_off)
```

## Commands

#### run

Runs the given command on all repos in the given group.

* The group must be one of those listed in proj_top_groups or proj_groups in repos.py
  Note that the sample also accepts: all, all1, and all2

```text
    proj_top_groups = {
        'rb': ['rb-apps', 'rb-gems', 'rb-wip'],
        'py': ['py-mods', 'py-apps', 'py-wip'],
        'cpp': ['cpp-libs', 'cpp-apps', 'cpp-wip'],
        'ard': ['ard-libs', 'ard-apps', 'ard-wip'],
    }

    proj_groups = [
        'base',  # for projects that are common to all other projects
        'common',  # basic projects
        'py-mods',
        <snip>
        'wip',
        'non-project',
    ]
```

* The command can be any terminal command.
    * single and double quotes are stripped before the python script gets the full text of the command.
      Some commands are not possible to do.
      e.g. ```sample-zdo run all git commit -m "hi there"``` will fail because the double quotes are removed and
      git sees two arguments instead of one.
    * piping, tees etc. are stripped out as well

```text
$ sample-zdo run rb pwd
# will run the "pwd" command in each directory for ruby repos
```

#### first

Creates a new terminal in the first directory of the repos list.

Currently, the terminal is only a gnome-terminal for Ubuntu.

If the repo does not exist, a git clone is attempted.

* define ```self.set_cmn_attr('get_git_url', self._get_git_url)```
* define a ```self._get_git_url``` to return a git clone URL

#### next

Creates a new terminal in the next directory of the repos list based on the current directory.
Check if the repo exists, creates it if necessary.

If at the end of the list:

```text
$ sample-zdo next
OK   git urls match
     curr directory: /home/arrizza/projects/web/ruby/rb-falcon-logger
OK   no next project, all done!
```

#### prev

Creates a new terminal in the next directory of the repos list based on the current directory.
Check if the repo exists, creates it if necessary.

If at the start of the list:

```text
$ sample-zdo prev
OK   git urls match
     curr directory: /home/arrizza/projects/web/xplat-utils
OK   no prev project, all done!
```

#### cd

Creates a new terminal for the best match of the given directory name.
The fuzzy-wuzzy module is used to select the best matching name in the repos.py list.

```text
$ sample-zdo cd logger
found matches for logger:
    rank 100: ~/projects/web/ruby/rb-falcon-logger
    rank  32: ~/projects/web/ruby/rb-cfg-parser
cd directory: ~/projects/web/ruby/rb-falcon-logger
```

Must have a ranking of 30 or greater to be considered a match

```text
$ sample-zdo cd xyz
ERR  no matches found for "xyz"
sample-zdo rc=1 cd xyz
```

#### check-repo

Report any uncommitted changes, unpushed changes and/or untracked files in the repo:

```text
sample-zdo check-repo
OK   check-repo: all changes are committed
```

The default branch is ```master```. Change that using:

```text
self.set_cmn_attr('default_branch', 'my_branch')
```

or use a command line args:

```text
sample-zdo check-repo cool-branch
WARN check-repo: not on cool-branch
WARN check-repo: actual Your branch is up to date with 'origin/master'.
```

#### check-subm

Report any uncommitted changes, unpushed changes and/or untracked files in submodules (if any):

Set ```subm_info``` with a list of tuples, one for each submodule directory and expected branch:

```text
self.set_cmn_attr('subm_info', [
    # subm directory,     subm branch
    ('tools/xplat_utils', 'v1.0.3'),
])
```

Set subm_excludes to exclude any repos that should be excluded from the check:

```text
self.set_cmn_attr('subm_excludes', ['xplat-utils'])
```

Typical output:

``` text
$ sample-zdo check-subm
WARN check-subm: untracked files found (tools/xplat_utils)
 --    1] Untracked files:
 --    2]   (use "git add <file>..." to include in what will be committed)
 --    3] 	xx
 --    4] 
 --    5] nothing added to commit but untracked files present (use "git add" to track)
```

#### check-branch

Report if the main git repo is on a given branch and if any submodules also the current branch.

Set ```subm_info``` (see check-subm above)

Typical output:

```text
$ sample-zdo check-branch
OK   check_branch: repo: branch matches: master
OK   check_branch: subm: branch matches: v1.0.3 (tools/xplat_utils)
```

Set subm_excludes as needed (see check-subm):

```text
# typical output:
sample-zdo check-branch
OK   check_branch: repo: branch matches: master
OK   check_branch: repo : does not have submodules: xplat-utils
```

#### check-size

Reports the current disk sizes for the repo and the .git subdirectory.
These are stored in proj_sizes.json file.

```text
---> running cmd: sample-zdo check-size in project: /home/arrizza/projects/web/ruby/rb-falcon-logger
 --    1] OK   cmd rc=0
 --    2]      {'.git': '2.9M', '.': '49M'}
 --    3] sample-zdo rc=0
OK   cmd rc=0
```

#### check-reqmts

Checks all Python module requirements and ruby gem requirements.

For ruby, it will run ```'bundle outdated``` which will list any outdated gems.

For python, if you have base-level files holding common modules for all your repos,
use  ```reqmts_base_paths``` to provide a list of them.

```text
root_dir = os.path.join('tools', 'xplat_utils', 'install')
self.set_cmn_attr('reqmts_base_paths', [
    os.path.join(root_dir, 'reqmts_arduino_app.txt'),
    os.path.join(root_dir, 'reqmts_arduino_common.txt'),
    <snip>
  ])
```

If you have a requirements file that contains the modules needed for the current repo,
use ```reqmts_top_path``` to provide a path to it.

```text
self.set_cmn_attr('reqmts_top_path', os.path.join('tools', 'requirements.txt'))
```

If you have some repos that don't have requirements.txt, add them to ```reqmts_skip```.

```text
self.set_cmn_attr('reqmts_skip', ['xplat-utils', 'fpga-led-blink'])
```

Typical output:

```text
---> running cmd: sample-zdo check-reqmts in project: /home/arrizza/projects/web/ai/ai-linear-regression
 --    1] WARN check-reqmts: setuptools        in use:  80.8.0  latest:  80.9.0, see tools/xplat_utils/install/reqmts_arduino_common.txt
 --    2] WARN check-reqmts: scipy             in use:  1.15.2  latest:  1.15.3, see tools/requirements.txt
 --    3] ERR  check-reqmts: number errs found: 2
 --    4] sample-zdo rc=2
ERR  cmd rc=2
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "proj-man-zdo",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": "\"J. Arrizza\" <cppgent0@gmail.com>",
    "keywords": "project, management",
    "author": null,
    "author_email": "\"J. Arrizza\" <cppgent0@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/af/ef/cba13eb8b469597bd6c254e446216e53174925c9e6f5b526cd6bf2960556/proj_man_zdo-0.2.0.tar.gz",
    "platform": null,
    "description": "* website: <https://arrizza.com/python-proj-man-zdo.html>\n* installation: see <https://arrizza.com/setup-common.html>\n\n## Summary\n\nThis project is used to manage many projects from the command line.\n\nIf you have common commands that you need to run across many projects, you would\nnormally need to cd into each directory and manually invoke that command.\nThis module lets you automate those activities.\n\nFor example, you can visit all or a subset of all the projects and invoke a command in each one.\nOr you can write a more complex command in python and invoke it in any directories you need to.\n\n## run\n\nNote: the examples here use ```sample-zdo```.\nYou should probably rename it to ```zdo``` to simplify typing it on the command line.\n(I used sample-zdo since I already have a zdo to manage the 60+ repos I have.)\n\n```bash\n./sample-zdo            <== shows list of commands\n./sample-zdo one-off    <== runs the one-off command\n```\n\n## set up repos.py\n\n* fill in repos.py with the directories/repos/projects you want to work with.\n\n```text\n$ sample-zdo run all2 pwd\n     group: \"all2\"\n---> running cmd: pwd in project: /home/arrizza/projects/web/xplat-utils\n --  /home/arrizza/projects/web/xplat-utils] 1\nOK   cmd rc=0\n<snip>\n---> total run :  11      <= should be total #repos/projects you've added to repos.py\nOK   total fail:   0\n```\n\nThe directories printed out by ```pwd``` should be the correct for each project in repos.py\n\nNow try the groups you've named:\n\n```text\n$ sample-zdo run rb pwd\n     group: \"rb\"\n<snip>\n---> total run :   3\nOK   total fail:   0\n```\n\n## nesting calls\n\nNote: you can nest calls to sample-zdo:\n\n```text\n$ sample-zdo run all sample-zdo search\n     group: \"rb\"\n<snip>\n---> total run :   3\nOK   total fail:   0\n```\n\n## adding commands\n\nSee sample/app.py for an example.\n\n* create the function. The signature is no parameters, returns an error code (0 for no errors)/\n\n```text\ndef one_off(self):\n    errs = 0\n    <snip>\n    return errs\n```\n\n* add the command\n\n```\nself.add_cmd('one-off', self.one_off)\n```\n\n## Commands\n\n#### run\n\nRuns the given command on all repos in the given group.\n\n* The group must be one of those listed in proj_top_groups or proj_groups in repos.py\n  Note that the sample also accepts: all, all1, and all2\n\n```text\n    proj_top_groups = {\n        'rb': ['rb-apps', 'rb-gems', 'rb-wip'],\n        'py': ['py-mods', 'py-apps', 'py-wip'],\n        'cpp': ['cpp-libs', 'cpp-apps', 'cpp-wip'],\n        'ard': ['ard-libs', 'ard-apps', 'ard-wip'],\n    }\n\n    proj_groups = [\n        'base',  # for projects that are common to all other projects\n        'common',  # basic projects\n        'py-mods',\n        <snip>\n        'wip',\n        'non-project',\n    ]\n```\n\n* The command can be any terminal command.\n    * single and double quotes are stripped before the python script gets the full text of the command.\n      Some commands are not possible to do.\n      e.g. ```sample-zdo run all git commit -m \"hi there\"``` will fail because the double quotes are removed and\n      git sees two arguments instead of one.\n    * piping, tees etc. are stripped out as well\n\n```text\n$ sample-zdo run rb pwd\n# will run the \"pwd\" command in each directory for ruby repos\n```\n\n#### first\n\nCreates a new terminal in the first directory of the repos list.\n\nCurrently, the terminal is only a gnome-terminal for Ubuntu.\n\nIf the repo does not exist, a git clone is attempted.\n\n* define ```self.set_cmn_attr('get_git_url', self._get_git_url)```\n* define a ```self._get_git_url``` to return a git clone URL\n\n#### next\n\nCreates a new terminal in the next directory of the repos list based on the current directory.\nCheck if the repo exists, creates it if necessary.\n\nIf at the end of the list:\n\n```text\n$ sample-zdo next\nOK   git urls match\n     curr directory: /home/arrizza/projects/web/ruby/rb-falcon-logger\nOK   no next project, all done!\n```\n\n#### prev\n\nCreates a new terminal in the next directory of the repos list based on the current directory.\nCheck if the repo exists, creates it if necessary.\n\nIf at the start of the list:\n\n```text\n$ sample-zdo prev\nOK   git urls match\n     curr directory: /home/arrizza/projects/web/xplat-utils\nOK   no prev project, all done!\n```\n\n#### cd\n\nCreates a new terminal for the best match of the given directory name.\nThe fuzzy-wuzzy module is used to select the best matching name in the repos.py list.\n\n```text\n$ sample-zdo cd logger\nfound matches for logger:\n    rank 100: ~/projects/web/ruby/rb-falcon-logger\n    rank  32: ~/projects/web/ruby/rb-cfg-parser\ncd directory: ~/projects/web/ruby/rb-falcon-logger\n```\n\nMust have a ranking of 30 or greater to be considered a match\n\n```text\n$ sample-zdo cd xyz\nERR  no matches found for \"xyz\"\nsample-zdo rc=1 cd xyz\n```\n\n#### check-repo\n\nReport any uncommitted changes, unpushed changes and/or untracked files in the repo:\n\n```text\nsample-zdo check-repo\nOK   check-repo: all changes are committed\n```\n\nThe default branch is ```master```. Change that using:\n\n```text\nself.set_cmn_attr('default_branch', 'my_branch')\n```\n\nor use a command line args:\n\n```text\nsample-zdo check-repo cool-branch\nWARN check-repo: not on cool-branch\nWARN check-repo: actual Your branch is up to date with 'origin/master'.\n```\n\n#### check-subm\n\nReport any uncommitted changes, unpushed changes and/or untracked files in submodules (if any):\n\nSet ```subm_info``` with a list of tuples, one for each submodule directory and expected branch:\n\n```text\nself.set_cmn_attr('subm_info', [\n    # subm directory,     subm branch\n    ('tools/xplat_utils', 'v1.0.3'),\n])\n```\n\nSet subm_excludes to exclude any repos that should be excluded from the check:\n\n```text\nself.set_cmn_attr('subm_excludes', ['xplat-utils'])\n```\n\nTypical output:\n\n``` text\n$ sample-zdo check-subm\nWARN check-subm: untracked files found (tools/xplat_utils)\n --    1] Untracked files:\n --    2]   (use \"git add <file>...\" to include in what will be committed)\n --    3] \txx\n --    4] \n --    5] nothing added to commit but untracked files present (use \"git add\" to track)\n```\n\n#### check-branch\n\nReport if the main git repo is on a given branch and if any submodules also the current branch.\n\nSet ```subm_info``` (see check-subm above)\n\nTypical output:\n\n```text\n$ sample-zdo check-branch\nOK   check_branch: repo: branch matches: master\nOK   check_branch: subm: branch matches: v1.0.3 (tools/xplat_utils)\n```\n\nSet subm_excludes as needed (see check-subm):\n\n```text\n# typical output:\nsample-zdo check-branch\nOK   check_branch: repo: branch matches: master\nOK   check_branch: repo : does not have submodules: xplat-utils\n```\n\n#### check-size\n\nReports the current disk sizes for the repo and the .git subdirectory.\nThese are stored in proj_sizes.json file.\n\n```text\n---> running cmd: sample-zdo check-size in project: /home/arrizza/projects/web/ruby/rb-falcon-logger\n --    1] OK   cmd rc=0\n --    2]      {'.git': '2.9M', '.': '49M'}\n --    3] sample-zdo rc=0\nOK   cmd rc=0\n```\n\n#### check-reqmts\n\nChecks all Python module requirements and ruby gem requirements.\n\nFor ruby, it will run ```'bundle outdated``` which will list any outdated gems.\n\nFor python, if you have base-level files holding common modules for all your repos,\nuse  ```reqmts_base_paths``` to provide a list of them.\n\n```text\nroot_dir = os.path.join('tools', 'xplat_utils', 'install')\nself.set_cmn_attr('reqmts_base_paths', [\n    os.path.join(root_dir, 'reqmts_arduino_app.txt'),\n    os.path.join(root_dir, 'reqmts_arduino_common.txt'),\n    <snip>\n  ])\n```\n\nIf you have a requirements file that contains the modules needed for the current repo,\nuse ```reqmts_top_path``` to provide a path to it.\n\n```text\nself.set_cmn_attr('reqmts_top_path', os.path.join('tools', 'requirements.txt'))\n```\n\nIf you have some repos that don't have requirements.txt, add them to ```reqmts_skip```.\n\n```text\nself.set_cmn_attr('reqmts_skip', ['xplat-utils', 'fpga-led-blink'])\n```\n\nTypical output:\n\n```text\n---> running cmd: sample-zdo check-reqmts in project: /home/arrizza/projects/web/ai/ai-linear-regression\n --    1] WARN check-reqmts: setuptools        in use:  80.8.0  latest:  80.9.0, see tools/xplat_utils/install/reqmts_arduino_common.txt\n --    2] WARN check-reqmts: scipy             in use:  1.15.2  latest:  1.15.3, see tools/requirements.txt\n --    3] ERR  check-reqmts: number errs found: 2\n --    4] sample-zdo rc=2\nERR  cmd rc=2\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "project management zdo",
    "version": "0.2.0",
    "project_urls": {
        "Download": "https://bitbucket.org/arrizza-public/proj-man-zdo/get/master.zip",
        "Source": "https://bitbucket.org/arrizza-public/proj-man-zdo/src/master",
        "Website": "https://arrizza.com/python-proj-man-zdo"
    },
    "split_keywords": [
        "project",
        " management"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "afefcba13eb8b469597bd6c254e446216e53174925c9e6f5b526cd6bf2960556",
                "md5": "f49d968a68eada34247aa38c5c908246",
                "sha256": "8f90e8dbf39d3b1afcf2d63910776a4feff1f148f5cfa143fbaef336c3f1a782"
            },
            "downloads": -1,
            "filename": "proj_man_zdo-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f49d968a68eada34247aa38c5c908246",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 18155,
            "upload_time": "2025-08-07T03:21:35",
            "upload_time_iso_8601": "2025-08-07T03:21:35.102068Z",
            "url": "https://files.pythonhosted.org/packages/af/ef/cba13eb8b469597bd6c254e446216e53174925c9e6f5b526cd6bf2960556/proj_man_zdo-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-07 03:21:35",
    "github": false,
    "gitlab": false,
    "bitbucket": true,
    "codeberg": false,
    "bitbucket_user": "arrizza-public",
    "bitbucket_project": "proj-man-zdo",
    "lcname": "proj-man-zdo"
}
        
Elapsed time: 1.69283s