portable-forge 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- forge/FIRST_BOOT.txt +147 -0
- forge/__init__.py +45 -0
- forge/__main__.py +9 -0
- forge/standard.py +340 -0
- forge_core/__init__.py +1 -0
- forge_core/aliases.py +228 -0
- forge_core/ast_search.py +269 -0
- forge_core/ast_tools.py +298 -0
- forge_core/codegraph.py +602 -0
- forge_core/config.py +439 -0
- forge_core/core_guard.py +107 -0
- forge_core/docs.py +239 -0
- forge_core/engine.py +206 -0
- forge_core/environment.py +317 -0
- forge_core/file_safety.py +92 -0
- forge_core/hinting.py +611 -0
- forge_core/language.py +87 -0
- forge_core/models.py +59 -0
- forge_core/parser.py +273 -0
- forge_core/preparse.py +206 -0
- forge_core/presentation/__init__.py +14 -0
- forge_core/presentation/plain.py +9 -0
- forge_core/presentation/standard.py +139 -0
- forge_core/protocol/__init__.py +6 -0
- forge_core/protocol/packet.py +234 -0
- forge_core/registry.py +151 -0
- forge_core/run_storage.py +991 -0
- forge_core/runner.py +169 -0
- forge_core/source_edit.py +93 -0
- forge_packages/__init__.py +1 -0
- forge_packages/core_ops/__init__.py +1 -0
- forge_packages/core_ops/branch/README.txt +7 -0
- forge_packages/core_ops/branch/manifest.py +9 -0
- forge_packages/core_ops/branch/op.py +1017 -0
- forge_packages/core_ops/copy/README.txt +25 -0
- forge_packages/core_ops/copy/manifest.py +9 -0
- forge_packages/core_ops/copy/op.py +177 -0
- forge_packages/core_ops/delete/README.txt +65 -0
- forge_packages/core_ops/delete/manifest.py +9 -0
- forge_packages/core_ops/delete/op.py +331 -0
- forge_packages/core_ops/diff/README.txt +80 -0
- forge_packages/core_ops/diff/manifest.py +11 -0
- forge_packages/core_ops/diff/op.py +453 -0
- forge_packages/core_ops/forge/README.txt +40 -0
- forge_packages/core_ops/forge/manifest.py +11 -0
- forge_packages/core_ops/forge/op.py +1246 -0
- forge_packages/core_ops/insert/README.txt +216 -0
- forge_packages/core_ops/insert/manifest.py +7 -0
- forge_packages/core_ops/insert/op.py +539 -0
- forge_packages/core_ops/map/README.txt +237 -0
- forge_packages/core_ops/map/manifest.py +11 -0
- forge_packages/core_ops/map/op.py +1492 -0
- forge_packages/core_ops/read/README.txt +143 -0
- forge_packages/core_ops/read/manifest.py +9 -0
- forge_packages/core_ops/read/op.py +338 -0
- forge_packages/core_ops/replace/README.txt +231 -0
- forge_packages/core_ops/replace/manifest.py +11 -0
- forge_packages/core_ops/replace/op.py +560 -0
- forge_packages/core_ops/revert/README.txt +19 -0
- forge_packages/core_ops/revert/manifest.py +11 -0
- forge_packages/core_ops/revert/op.py +126 -0
- forge_packages/core_ops/run/README.txt +23 -0
- forge_packages/core_ops/run/manifest.py +11 -0
- forge_packages/core_ops/run/op.py +351 -0
- forge_packages/core_ops/search/README.txt +238 -0
- forge_packages/core_ops/search/manifest.py +11 -0
- forge_packages/core_ops/search/op.py +678 -0
- forge_packages/core_ops/url/README.txt +37 -0
- forge_packages/core_ops/url/manifest.py +9 -0
- forge_packages/core_ops/url/op.py +398 -0
- forge_packages/core_ops/write/README.txt +35 -0
- forge_packages/core_ops/write/manifest.py +11 -0
- forge_packages/core_ops/write/op.py +302 -0
- forge_packages/custom_ops/__init__.py +1 -0
- forge_packages/custom_ops/alias/README.txt +51 -0
- forge_packages/custom_ops/alias/expander.py +17 -0
- forge_packages/custom_ops/alias/manifest.py +11 -0
- forge_packages/custom_ops/alias/op.py +729 -0
- portable_forge-0.1.0.dist-info/METADATA +734 -0
- portable_forge-0.1.0.dist-info/RECORD +84 -0
- portable_forge-0.1.0.dist-info/WHEEL +5 -0
- portable_forge-0.1.0.dist-info/entry_points.txt +2 -0
- portable_forge-0.1.0.dist-info/licenses/LICENSE +21 -0
- portable_forge-0.1.0.dist-info/top_level.txt +3 -0
forge/FIRST_BOOT.txt
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
FORGE FIRST BOOT
|
|
2
|
+
================
|
|
3
|
+
|
|
4
|
+
Forge is a local Python runtime for human + AI pair-programming.
|
|
5
|
+
|
|
6
|
+
The assistant proposes.
|
|
7
|
+
The user runs.
|
|
8
|
+
Forge reports.
|
|
9
|
+
The packet confirms.
|
|
10
|
+
|
|
11
|
+
The run packet is ground truth.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
FIRST RESPONSE
|
|
15
|
+
--------------
|
|
16
|
+
|
|
17
|
+
At the start of a cold Forge session, output this read-only bundle first:
|
|
18
|
+
|
|
19
|
+
MAP .
|
|
20
|
+
DEPTH: 2
|
|
21
|
+
|
|
22
|
+
FORGE ops
|
|
23
|
+
|
|
24
|
+
Return the bundle as one clean, copyable code block with no explanation
|
|
25
|
+
inside the block.
|
|
26
|
+
|
|
27
|
+
Do not explain it first.
|
|
28
|
+
|
|
29
|
+
Wait for the returned packet. Inspect it, then ask what the user wants to
|
|
30
|
+
work on. Do not assume the task is Forge itself.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
THE LOOP
|
|
34
|
+
--------
|
|
35
|
+
|
|
36
|
+
1. Write a plain-text Forge bundle.
|
|
37
|
+
2. The user runs it locally.
|
|
38
|
+
3. Forge parses the whole bundle before executing anything.
|
|
39
|
+
4. Forge executes against project_root.
|
|
40
|
+
5. Forge returns a packet.
|
|
41
|
+
6. Read that packet before continuing.
|
|
42
|
+
|
|
43
|
+
Nothing happened unless the packet says it happened.
|
|
44
|
+
|
|
45
|
+
Never claim a local change without a returned packet.
|
|
46
|
+
|
|
47
|
+
New syntax created by one bundle is available only to a later run because
|
|
48
|
+
the complete bundle is parsed before execution starts.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
WORKING RULES
|
|
52
|
+
-------------
|
|
53
|
+
|
|
54
|
+
- Return executable Forge bundles as one clean, copyable code block.
|
|
55
|
+
- Keep explanation outside the bundle.
|
|
56
|
+
- Prefer small bundles.
|
|
57
|
+
- Inspect before editing.
|
|
58
|
+
- Use MAP for structure.
|
|
59
|
+
- Use SEARCH to locate candidate areas.
|
|
60
|
+
- Use READ for exact content before editing.
|
|
61
|
+
- Use the smallest write operation that fits.
|
|
62
|
+
- Use RUN for relevant tests.
|
|
63
|
+
- Use DIFF to review changes.
|
|
64
|
+
- Use BRANCH before risky work when useful.
|
|
65
|
+
- Read errors and hints before retrying failures.
|
|
66
|
+
- Never invent Forge syntax or directives.
|
|
67
|
+
- Use FORGE help <OP> when syntax is unclear.
|
|
68
|
+
- Use FORGE runs for stored run history.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
FAILURE RECOVERY
|
|
72
|
+
----------------
|
|
73
|
+
|
|
74
|
+
When a run fails:
|
|
75
|
+
|
|
76
|
+
1. Read ERRORS, HINTS, and PREVIEW before retrying.
|
|
77
|
+
2. Identify the failed operation and failure type.
|
|
78
|
+
3. Follow the Forge hint when one is present.
|
|
79
|
+
4. Use FORGE help <OP> if syntax or the operation contract is unclear.
|
|
80
|
+
5. Inspect the relevant file or state before changing anything.
|
|
81
|
+
6. Make the smallest correction that addresses the reported failure.
|
|
82
|
+
7. Run again and read the new packet.
|
|
83
|
+
|
|
84
|
+
Do not guess Forge syntax after a failure.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
PUBLIC LANGUAGE
|
|
88
|
+
---------------
|
|
89
|
+
|
|
90
|
+
FORGE
|
|
91
|
+
MAP
|
|
92
|
+
READ
|
|
93
|
+
SEARCH
|
|
94
|
+
|
|
95
|
+
WRITE
|
|
96
|
+
REPLACE
|
|
97
|
+
INSERT
|
|
98
|
+
DELETE
|
|
99
|
+
COPY
|
|
100
|
+
|
|
101
|
+
RUN
|
|
102
|
+
DIFF
|
|
103
|
+
REVERT
|
|
104
|
+
BRANCH
|
|
105
|
+
|
|
106
|
+
URL
|
|
107
|
+
ALIAS
|
|
108
|
+
|
|
109
|
+
Use:
|
|
110
|
+
|
|
111
|
+
FORGE ops
|
|
112
|
+
|
|
113
|
+
for the public language.
|
|
114
|
+
|
|
115
|
+
Use:
|
|
116
|
+
|
|
117
|
+
FORGE ops all
|
|
118
|
+
|
|
119
|
+
to inspect installed extensions.
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
NORMAL EDIT LOOP
|
|
123
|
+
----------------
|
|
124
|
+
|
|
125
|
+
MAP path
|
|
126
|
+
|
|
127
|
+
READ path
|
|
128
|
+
|
|
129
|
+
REPLACE path
|
|
130
|
+
...
|
|
131
|
+
|
|
132
|
+
RUN relevant_test.py
|
|
133
|
+
|
|
134
|
+
DIFF current
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
OUTPUT
|
|
138
|
+
------
|
|
139
|
+
|
|
140
|
+
The canonical packet is the AI-facing audit trail.
|
|
141
|
+
|
|
142
|
+
Standard Forge prints that packet unchanged, followed by a small human
|
|
143
|
+
summary.
|
|
144
|
+
|
|
145
|
+
A host may change how bundle text enters Forge or where rendered output goes.
|
|
146
|
+
It must not change Forge execution semantics or the meaning of the canonical
|
|
147
|
+
packet.
|
forge/__init__.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Portable Forge public Python API.
|
|
4
|
+
|
|
5
|
+
Normal use:
|
|
6
|
+
|
|
7
|
+
import forge
|
|
8
|
+
|
|
9
|
+
run = forge.run_text(
|
|
10
|
+
bundle,
|
|
11
|
+
project_root='/path/to/project',
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
print(
|
|
15
|
+
forge.render_standard(run)
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
Advanced callers may build and supply an explicit environment.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from forge_core.environment import make_environment
|
|
22
|
+
from forge_core.presentation.standard import (
|
|
23
|
+
format_summary,
|
|
24
|
+
render_standard,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
from .standard import (
|
|
28
|
+
default_forge_home,
|
|
29
|
+
first_boot_text,
|
|
30
|
+
main,
|
|
31
|
+
run_text,
|
|
32
|
+
standard_environment,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
'default_forge_home',
|
|
38
|
+
'first_boot_text',
|
|
39
|
+
'format_summary',
|
|
40
|
+
'main',
|
|
41
|
+
'make_environment',
|
|
42
|
+
'render_standard',
|
|
43
|
+
'run_text',
|
|
44
|
+
'standard_environment',
|
|
45
|
+
]
|
forge/__main__.py
ADDED
forge/standard.py
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Standard host for portable Forge.
|
|
4
|
+
|
|
5
|
+
This is the ordinary Python edge around the portable core.
|
|
6
|
+
|
|
7
|
+
Host responsibilities:
|
|
8
|
+
- choose project_root when the caller does not
|
|
9
|
+
- choose writable Forge home
|
|
10
|
+
- load user configuration
|
|
11
|
+
- construct resolved environment
|
|
12
|
+
- read bundle input for CLI use
|
|
13
|
+
- print standard presentation
|
|
14
|
+
|
|
15
|
+
Portable core remains responsible for parsing, execution, storage semantics,
|
|
16
|
+
recovery data, and canonical packet generation.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
import os
|
|
21
|
+
import sys
|
|
22
|
+
|
|
23
|
+
from forge_core.config import (
|
|
24
|
+
load_config,
|
|
25
|
+
resolve_config,
|
|
26
|
+
)
|
|
27
|
+
from forge_core.environment import (
|
|
28
|
+
make_environment,
|
|
29
|
+
)
|
|
30
|
+
from forge_core.presentation.standard import (
|
|
31
|
+
render_standard,
|
|
32
|
+
)
|
|
33
|
+
from forge_core.runner import (
|
|
34
|
+
run_text as core_run_text,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
HERE = os.path.dirname(
|
|
39
|
+
os.path.abspath(__file__)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
FIRST_BOOT_PATH = os.path.join(
|
|
43
|
+
HERE,
|
|
44
|
+
'FIRST_BOOT.txt',
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _absolute(path):
|
|
49
|
+
return os.path.abspath(
|
|
50
|
+
os.path.expanduser(
|
|
51
|
+
str(path)
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def default_forge_home():
|
|
57
|
+
"""
|
|
58
|
+
Return the standard host's writable Forge home.
|
|
59
|
+
|
|
60
|
+
Installed source code is not used as writable state.
|
|
61
|
+
"""
|
|
62
|
+
configured = str(
|
|
63
|
+
os.environ.get(
|
|
64
|
+
'FORGE_HOME'
|
|
65
|
+
)
|
|
66
|
+
or ''
|
|
67
|
+
).strip()
|
|
68
|
+
|
|
69
|
+
if configured:
|
|
70
|
+
return _absolute(
|
|
71
|
+
configured
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return _absolute(
|
|
75
|
+
'~/.forge'
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def standard_environment(
|
|
80
|
+
project_root=None,
|
|
81
|
+
forge_home=None,
|
|
82
|
+
capabilities=None,
|
|
83
|
+
config_path=None,
|
|
84
|
+
):
|
|
85
|
+
"""Resolve ordinary Python host facts into one Forge environment."""
|
|
86
|
+
root = _absolute(
|
|
87
|
+
project_root
|
|
88
|
+
or os.getcwd()
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
home = _absolute(
|
|
92
|
+
forge_home
|
|
93
|
+
or default_forge_home()
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
os.makedirs(
|
|
97
|
+
home,
|
|
98
|
+
exist_ok=True,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
config = load_config(
|
|
102
|
+
home,
|
|
103
|
+
path=config_path,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
resolved = resolve_config(
|
|
107
|
+
config,
|
|
108
|
+
home,
|
|
109
|
+
path=config_path,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return make_environment(
|
|
113
|
+
project_root=root,
|
|
114
|
+
forge_home=home,
|
|
115
|
+
storage_root=resolved[
|
|
116
|
+
'storage_root'
|
|
117
|
+
],
|
|
118
|
+
aliases_path=resolved[
|
|
119
|
+
'aliases_path'
|
|
120
|
+
],
|
|
121
|
+
capabilities=(
|
|
122
|
+
capabilities
|
|
123
|
+
or {}
|
|
124
|
+
),
|
|
125
|
+
host='standard',
|
|
126
|
+
storage=resolved[
|
|
127
|
+
'storage'
|
|
128
|
+
],
|
|
129
|
+
features=resolved[
|
|
130
|
+
'features'
|
|
131
|
+
],
|
|
132
|
+
config_path=resolved[
|
|
133
|
+
'config_path'
|
|
134
|
+
],
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def run_text(
|
|
139
|
+
bundle_text,
|
|
140
|
+
project_root=None,
|
|
141
|
+
mode='dev',
|
|
142
|
+
store=True,
|
|
143
|
+
environment=None,
|
|
144
|
+
forge_home=None,
|
|
145
|
+
capabilities=None,
|
|
146
|
+
config_path=None,
|
|
147
|
+
):
|
|
148
|
+
"""
|
|
149
|
+
Execute Forge from normal Python code.
|
|
150
|
+
|
|
151
|
+
Supplying environment gives the caller complete control.
|
|
152
|
+
|
|
153
|
+
Otherwise the standard host resolves project_root and writable Forge home.
|
|
154
|
+
"""
|
|
155
|
+
if environment is None:
|
|
156
|
+
environment = standard_environment(
|
|
157
|
+
project_root=project_root,
|
|
158
|
+
forge_home=forge_home,
|
|
159
|
+
capabilities=capabilities,
|
|
160
|
+
config_path=config_path,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
return core_run_text(
|
|
164
|
+
bundle_text,
|
|
165
|
+
project_root=environment.get(
|
|
166
|
+
'project_root'
|
|
167
|
+
),
|
|
168
|
+
mode=mode,
|
|
169
|
+
store=store,
|
|
170
|
+
environment=environment,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def first_boot_text():
|
|
175
|
+
"""Return the portable Forge first-boot prompt."""
|
|
176
|
+
with open(
|
|
177
|
+
FIRST_BOOT_PATH,
|
|
178
|
+
'r',
|
|
179
|
+
encoding='utf-8',
|
|
180
|
+
) as handle:
|
|
181
|
+
return handle.read()
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _parser():
|
|
185
|
+
parser = argparse.ArgumentParser(
|
|
186
|
+
prog='python -m forge',
|
|
187
|
+
description=(
|
|
188
|
+
'Run a Forge bundle using the standard pure-Python host.'
|
|
189
|
+
),
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
parser.add_argument(
|
|
193
|
+
'bundle_file',
|
|
194
|
+
nargs='?',
|
|
195
|
+
help='Bundle text file. If omitted, read stdin.',
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
parser.add_argument(
|
|
199
|
+
'--project',
|
|
200
|
+
help='Project root. Defaults to current working directory.',
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
parser.add_argument(
|
|
204
|
+
'--home',
|
|
205
|
+
help='Writable Forge home. Defaults to FORGE_HOME or ~/.forge.',
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
parser.add_argument(
|
|
209
|
+
'--config',
|
|
210
|
+
help='Optional forge.json path.',
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
parser.add_argument(
|
|
214
|
+
'--mode',
|
|
215
|
+
default='dev',
|
|
216
|
+
help='Run storage lane. Default: dev.',
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
parser.add_argument(
|
|
220
|
+
'--no-store',
|
|
221
|
+
action='store_true',
|
|
222
|
+
help='Do not persist this run.',
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
parser.add_argument(
|
|
226
|
+
'--first-boot',
|
|
227
|
+
action='store_true',
|
|
228
|
+
help='Print the portable AI first-boot prompt.',
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
return parser
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def _read_bundle(args, stdin):
|
|
235
|
+
if args.bundle_file:
|
|
236
|
+
with open(
|
|
237
|
+
args.bundle_file,
|
|
238
|
+
'r',
|
|
239
|
+
encoding='utf-8',
|
|
240
|
+
) as handle:
|
|
241
|
+
return handle.read()
|
|
242
|
+
|
|
243
|
+
if (
|
|
244
|
+
hasattr(
|
|
245
|
+
stdin,
|
|
246
|
+
'isatty',
|
|
247
|
+
)
|
|
248
|
+
and stdin.isatty()
|
|
249
|
+
):
|
|
250
|
+
return None
|
|
251
|
+
|
|
252
|
+
return stdin.read()
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def main(
|
|
256
|
+
argv=None,
|
|
257
|
+
stdin=None,
|
|
258
|
+
stdout=None,
|
|
259
|
+
):
|
|
260
|
+
"""Standard CLI entrypoint."""
|
|
261
|
+
argv = list(
|
|
262
|
+
sys.argv[1:]
|
|
263
|
+
if argv is None
|
|
264
|
+
else argv
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
stdin = (
|
|
268
|
+
sys.stdin
|
|
269
|
+
if stdin is None
|
|
270
|
+
else stdin
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
stdout = (
|
|
274
|
+
sys.stdout
|
|
275
|
+
if stdout is None
|
|
276
|
+
else stdout
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
parser = _parser()
|
|
280
|
+
args = parser.parse_args(
|
|
281
|
+
argv
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
if args.first_boot:
|
|
285
|
+
text = first_boot_text()
|
|
286
|
+
|
|
287
|
+
stdout.write(
|
|
288
|
+
text
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
if (
|
|
292
|
+
text
|
|
293
|
+
and not text.endswith('\n')
|
|
294
|
+
):
|
|
295
|
+
stdout.write('\n')
|
|
296
|
+
|
|
297
|
+
return 0
|
|
298
|
+
|
|
299
|
+
bundle = _read_bundle(
|
|
300
|
+
args,
|
|
301
|
+
stdin,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
if bundle is None:
|
|
305
|
+
parser.print_help(
|
|
306
|
+
file=stdout
|
|
307
|
+
)
|
|
308
|
+
return 2
|
|
309
|
+
|
|
310
|
+
if not str(bundle).strip():
|
|
311
|
+
stdout.write(
|
|
312
|
+
'Forge: no bundle text supplied.\n'
|
|
313
|
+
)
|
|
314
|
+
return 2
|
|
315
|
+
|
|
316
|
+
run = run_text(
|
|
317
|
+
bundle,
|
|
318
|
+
project_root=args.project,
|
|
319
|
+
forge_home=args.home,
|
|
320
|
+
mode=args.mode,
|
|
321
|
+
store=not args.no_store,
|
|
322
|
+
config_path=args.config,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
stdout.write(
|
|
326
|
+
render_standard(
|
|
327
|
+
run
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
if (
|
|
332
|
+
str(
|
|
333
|
+
run.get('status')
|
|
334
|
+
or ''
|
|
335
|
+
).upper()
|
|
336
|
+
== 'APPLIED'
|
|
337
|
+
):
|
|
338
|
+
return 0
|
|
339
|
+
|
|
340
|
+
return 1
|
forge_core/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# forge_reboot core package
|