-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathinfo.py
More file actions
171 lines (145 loc) · 6.44 KB
/
Copy pathinfo.py
File metadata and controls
171 lines (145 loc) · 6.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# -*- coding:utf-8 -*-
#
# File : info.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2025-06-23 Dongly Add get_rt_env_version function
# 2026-09-10 Dongly Add get_rt_env_description function, Extract load_env_json common helper
# 2026-09-12 Dongly Rename version.py to info.py; single access layer for env.json (metadata, repositories, submodule mirrors, service endpoints)
import json
import os
import platform
from collections import namedtuple
# Fallback snapshot of the shipped env.json, WITHOUT mirror entries: the
# defaults only guarantee the primary source of each repository. A mirror is
# an optional accelerator that comes from env.json alone — with no mirror
# configured, the primary source is used.
DEFAULTS = {
'name': 'RT-Thread Env Tool',
'version': 'v2.0.2',
'description': 'A command-line toolkit for RT-Thread development.',
'repositories': {
'env': {
'url': 'https://github.com/RT-Thread/env.git',
'branch': 'master',
},
'sdk': {
'url': 'https://github.com/RT-Thread/sdk.git',
'branch': 'main',
},
'packages': {
'url': 'https://github.com/RT-Thread/packages.git',
'branch': 'master',
},
},
'submodule_mirrors': {
'rt-thread': 'https://gitee.com/RT-Thread-Mirror/submod_{name}.git',
'esp': 'https://gitee.com/esp-submodules/{name}.git',
},
'apis': {
'mirror_query': 'https://api.rt-thread.org/packages/queries',
'statistics': 'https://www.rt-thread.org/studio/statistics/api/envuse',
},
}
# A repository source is an atomic (url, branch) pair: selecting a mirror
# switches the whole pair, so a primary URL can never be paired with a
# mirror branch.
Source = namedtuple('Source', ['url', 'branch'])
def load_env_json():
# try to read env.json to get information
try:
# Get the directory where this script is located
script_dir = os.path.dirname(os.path.abspath(__file__))
env_json_path = os.path.join(script_dir, 'env.json')
# If not found in script directory, try ENV_ROOT
if not os.path.exists(env_json_path):
env_root = os.getenv("ENV_ROOT")
if env_root is None:
if platform.system() != 'Windows':
env_root = os.path.join(os.getenv('HOME'), '.env')
else:
env_root = os.path.join(os.getenv('USERPROFILE'), '.env')
env_json_path = os.path.join(env_root, 'tools', 'scripts', 'env.json')
with open(env_json_path, 'r') as file:
return json.load(file)
except Exception as e:
# Only print error if running interactively (not imported)
if __name__ == '__main__':
print("Failed to read env.json: %s" % str(e))
return None
def _config_section(section):
# return the raw config section ({} when absent or malformed)
config = load_env_json() or {}
value = config.get(section)
return value if isinstance(value, dict) else {}
def get_name():
name = (load_env_json() or {}).get('name')
if not isinstance(name, str):
name = DEFAULTS['name']
return name
def get_version():
version = (load_env_json() or {}).get('version')
if not isinstance(version, str):
version = DEFAULTS['version']
return version
def get_description():
description = (load_env_json() or {}).get('description')
if not isinstance(description, str):
description = DEFAULTS['description']
return description
def get_source(repo, use_mirror=False, branch=None):
# Resolve a repository source as Source(url, branch).
# Priority: explicit branch argument > configured branch of that source
# (a mirror without 'branch' inherits the primary branch) > DEFAULTS
# branch. DEFAULTS never supplies a mirror: with no mirror url in
# env.json, the primary source is used. Unknown repository names and
# entries without a url raise KeyError — config problems fail loudly.
raw_entry = _config_section('repositories').get(repo)
if not isinstance(raw_entry, dict):
raw_entry = {}
if repo not in DEFAULTS['repositories'] and not raw_entry:
raise KeyError('unknown repository: %r' % (repo,))
default_entry = DEFAULTS['repositories'].get(repo, {})
url = raw_entry.get('url') or default_entry.get('url')
resolved_branch = raw_entry.get('branch') or default_entry.get('branch')
if use_mirror:
mirror = raw_entry.get('mirror') if isinstance(raw_entry.get('mirror'), dict) else {}
if mirror.get('url'):
url = mirror['url']
resolved_branch = mirror.get('branch') or resolved_branch
if url is None:
raise KeyError("repository %r is configured without a 'url'" % (repo,))
if branch is not None:
resolved_branch = branch
return Source(url=url, branch=resolved_branch)
def get_submodule_mirror_url(kind, name):
# Instantiate a submodule mirror template ('{name}' placeholder) for the
# given submodule name. kind: 'rt-thread' or 'esp'. ESP name case mapping
# (unity -> Unity) is caller-side logic, not configuration.
template = _config_section('submodule_mirrors').get(kind) or DEFAULTS['submodule_mirrors'].get(kind)
if not isinstance(template, str):
raise KeyError('unknown submodule mirror kind: %r' % (kind,))
return template.replace('{name}', name)
def get_api_url(name):
# Service endpoints. name: 'mirror_query' or 'statistics'.
url = _config_section('apis').get(name) or DEFAULTS['apis'].get(name)
if not isinstance(url, str):
raise KeyError('unknown api name: %r' % (name,))
return url