Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/test-mlc-core-actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,68 @@ jobs:
run: |
cd .github/scripts && python -c "import test_mlc_access as test; test.run_tests()"

test_mlc_help:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: ["3.12", "3.8"]
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
exclude:
- os: windows-latest
- os: macos-latest

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}

- name: Configure git longpaths (Windows)
if: matrix.os == 'windows-latest'
run: |
git config --system core.longpaths true

- name: Install mlcflow from the pull request's source repository and branch
run: |
python -m pip install --upgrade pip
python -m pip install --ignore-installed --verbose pip setuptools
python -m pip install .
- name: MLC intro
run: |
mlc help
- name: MLC scripts - full
run: |
mlc help script
- name: MLC scripts - individual actions
run: |
mlc help add script
mlc help docker script
mlc help find script
mlc help search script
mlc help list script
mlc help rm script
mlc help run script
mlc help show script
mlc help test script
- name: MLC repos - full
run: |
mlc help repo
- name: MLC repos - individual actions
run: |
mlc help add repo
mlc help find repo
mlc help pull repo
mlc help list repo
mlc help rm repo
- name: MLC cache - full
run: |
mlc help cache
- name: MLC cache - individual actions
run: |
mlc help find cache
mlc help list cache
mlc help rm cache
mlc help search cache
mlc help show cache
18 changes: 16 additions & 2 deletions docs/targets/script/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ MLC scripts can be identified in different ways:

---

## **Find**
## **Find(Alias: Search)**

The `find` action retrieves the path of scripts available in MLC repositories.
The `find/search` action retrieves the path of scripts available in MLC repositories.

### **Syntax Variations**

Expand Down Expand Up @@ -135,6 +135,17 @@ mlc rm script --tags=detect,os -f

---

## **List**

Lists all the scripts and their paths present in repos which are registered in MLC.

**Example Command:**
```bash
mlc list script
```

---

## **Run**

Executes a script from an MLC repository.
Expand Down Expand Up @@ -171,8 +182,11 @@ mlc run script --tags=detect,os -j
- *`<Individual script inputs>`: In addition to the above options an `mlcr` command also takes any input specified with in a script meta in `input_mappings` as its input.

**Log Levels**

- *Default* : Provides all logs at the `info` level.

- *Silent* `[--silent/-s]` : Disables all `debug` and `info` level logs from automation. Logs from individual scripts will still be visible.

- *verbose* `[--verbose/-v]` : Displays both `info` and `debug` level logs from automation, along with logs from individual scripts.

<details>
Expand Down
85 changes: 85 additions & 0 deletions mlc/cache_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,97 @@
from .logger import logger

class CacheAction(Action):
"""
####################################################################################################################
Cache Action
####################################################################################################################
Currently, the following actions are supported for Cache:
1. find/search
2. show
3. list
4. remove(rm)

"""

def __init__(self, parent=None):
#super().__init__(parent)
self.parent = parent
self.__dict__.update(vars(parent))

def search(self, i):
"""
####################################################################################################################
Target: Cache
Action: Find (Alias: Search)
####################################################################################################################

The `find` (or `search`) action retrieves the path of cache generated by a particular script.

Syntax:

mlc find cache --tags=<list_of_tag_used_to_run_the_particular_script>

Example Command:

mlc find cache --tags=get,dataset,igbh

"""
i['target_name'] = "cache"
#logger.debug(f"Searching for cache with input: {i}")
return self.parent.search(i)

find = search

def rm(self, i):
"""
####################################################################################################################
Target: Cache
Action: Remove(rm)
####################################################################################################################

The `rm` action removes one or more caches generated while running scripts through MLCFlow.

Syntax:

mlc rm cache --tags=<list_of_tag_used_to_run_the_particular_script>

Options:
1. `-f`: Force removes caches without confirmation. Without `-f`, the user will be prompted for confirmation before deletion.

To remove all generated caches, use:

mlc rm cache

Example Command:

mlc rm cache --tags=get,dataset,igbh

"""
i['target_name'] = "cache"
#logger.debug(f"Removing cache with input: {i}")
return self.parent.rm(i)

def show(self, run_args):
"""
####################################################################################################################
Target: Cache
Action: Show
####################################################################################################################

Retrieves the path and metadata of caches generated while running scripts through MLCFlow.

Syntax:

mlc show cache --tags=<list_of_tags_used_while_running_script>

Example Command:

mlc show cache --tags=get,dataset,igbh

Note:
- The `find` action is a subset of `show`. It retrieves only the path of the searched cache.

"""
self.action_type = "cache"
res = self.search(run_args)
logger.info(f"Showing cache with tags: {run_args.get('tags')}")
Expand Down Expand Up @@ -59,6 +131,19 @@ def show(self, run_args):
return {'return': 0}

def list(self, args):
"""
####################################################################################################################
Target: Cache
Action: List
####################################################################################################################

Lists all cached items along with their paths.

Example Command:

mlc list cache

"""
self.action_type = "cache"
run_args = {"fetch_all": True} # to fetch the details of all the caches generated

Expand Down
75 changes: 72 additions & 3 deletions mlc/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import sys
from pathlib import Path
import inspect

from . import utils

Expand All @@ -17,7 +18,6 @@
from .logger import logger



class Automation:
action_object = None
automation_type = None
Expand Down Expand Up @@ -103,7 +103,37 @@ def process_console_output(res, target, action, run_args):

# Main CLI function
def main():
parser = argparse.ArgumentParser(prog='mlc', description='A CLI tool for managing repos, scripts, and caches.')
"""
MLCFlow is a CLI tool for managing repos, scripts, and caches.
This framework is designed to streamline automation workflows for MLPerf benchmarks more efficiently.
You can also use this tool for any of your workflow automation tasks.

MLCFlow CLI operates using actions and targets. It enables users to perform actions on specified targets using the following syntax:

mlc <action> <target> [options]

Here, actions represent the operations to be performed, and the target is the object on which the action is executed.

Each target has a specific set of actions to tailor automation workflows, as shown below:

| Target | Actions |
|---------|-------------------------------------------------------|
| script | run, find/search, rm, mv, cp, add, test, docker, show |
| cache | find/search, rm, show |
| repo | pull, search, rm, list, find/search |

Example:
mlc run script detect-os

For help related to a particular target, run:

mlc help <target>

For help related to a specific action for a target, run:

mlc help <action> <target>
"""
parser = argparse.ArgumentParser(prog='mlc', description='A CLI tool for managing repos, scripts, and caches.', add_help=False)

# Subparsers are added to main parser, allowing for different commands (subcommands) to be defined.
# The chosen subcommand will be stored in the "command" attribute of the parsed arguments.
Expand All @@ -118,7 +148,7 @@ def main():
action_parser.add_argument('extra', nargs=argparse.REMAINDER, help='Extra options (e.g., -v)')

# Script and specific subcommands
for action in ['docker', 'help']:
for action in ['docker']:
action_parser = subparsers.add_parser(action, help=f'{action.capitalize()} a target.')
action_parser.add_argument('target', choices=['script', 'run'], help='Target type (script).')
# the argument given after target and before any extra options like --tags will be stored in "details"
Expand All @@ -129,10 +159,49 @@ def main():
load_parser = subparsers.add_parser(action, help=f'{action.capitalize()} a target.')
load_parser.add_argument('target', choices=['cfg'], help='Target type (cfg).')

for action in ['help']:
action_parser = subparsers.add_parser(action, help=f'{action.capitalize()} a target.')
action_parser.add_argument('action', help='action type (run).', nargs='?', default=None)
action_parser.add_argument('target', choices=['script', 'cache', 'repo'], help='Target type (script).', nargs='?', default=None)


# Parse arguments
args = parser.parse_args()

# handle help in mlcflow
if args.command in ['help']:
help_text = ""
if not args.action and not args.target:
print(main.__doc__)
sys.exit(0)
elif args.action and not args.target:
if args.action not in ['script', 'cache', 'repo']:
logger.error(f"Invalid target {args.action}")
raise Exception(f"""Invalid target {args.action}""")
else:
args.target = args.action
args.action = None
actions = get_action(args.target, default_parent)
help_text += actions.__doc__

# iterate through every method
for method_name, method in inspect.getmembers(actions.__class__, inspect.isfunction):
method = getattr(actions, method_name)
if method.__doc__ and not method.__doc__.startswith("_"):
help_text += method.__doc__
print(help_text)
sys.exit(0)
else:
actions = get_action(args.target, default_parent)
try:
method = getattr(actions, args.action)
help_text += actions.__doc__
help_text += method.__doc__
print(help_text)
except:
logger.error(f"Error: '{args.action}' is not supported for {args.target}.")
sys.exit(0)

#logger.info(f"Args = {args}")

res = utils.convert_args_to_dictionary(args.extra)
Expand Down
Loading
Loading