Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
workspaces
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ssa
workspaces
Commits
6edcac0d
Commit
6edcac0d
authored
4 years ago
by
Nathan Hertz
Browse files
Options
Downloads
Patches
Plain Diff
Committing setup_to_meta changes again because I'm dumb.
parent
4b588b1c
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/setup_to_meta/setup_to_meta.py
+153
-72
153 additions, 72 deletions
src/setup_to_meta/setup_to_meta.py
with
153 additions
and
72 deletions
src/setup_to_meta/setup_to_meta.py
+
153
−
72
View file @
6edcac0d
import
setuptools
,
importlib
,
subprocess
,
os
,
re
def
write_metafile
(
metadata
,
filename
):
def
write_metafile
(
metadata
,
filepath
):
"""
Writes given metadata to file with given path.
"""
try
:
os
.
makedirs
(
file
name
[:
-
10
])
os
.
makedirs
(
file
path
[:
-
10
])
except
FileExistsError
:
pass
with
open
(
file
name
,
'
w
'
)
as
f
:
with
open
(
file
path
,
'
w
'
)
as
f
:
f
.
write
(
metadata
)
def
generate_metafile
(
setup_dict
,
path
):
metadata
=
(
'
{{% set name =
"
{name}
"
%}}
\n
'
'
{{% set version =
"
{version}
"
%}}
\n
'
'
\n
'
'
package:
\n
'
'
name:
"
{{{{ name|lower }}}}
"
\n
'
'
version:
"
{{{{ version }}}}
"
\n
'
'
\n
'
'
build:
\n
'
).
format
(
name
=
setup_dict
[
"
name
"
],
version
=
setup_dict
[
"
version
"
]
def
generate_metadata
(
setup_dict
,
path
):
"""
Uses given info extracted from setup.py file to fill out metadata template.
:param setup_dict: Dictionary of info extracted from setup.py.
:param path: Path to root directory of the subproject.
:return: String of metadata, ready to be written to a file.
"""
def
fmt_ep
():
"""
Format entry points section of metadata.
:return: Formatted string if entry points exists; else empty string.
"""
ep_string
=
''
if
'
entry_points
'
in
setup_dict
.
keys
():
ep_string
+=
'
entry_points:
\n
'
for
ep
in
setup_dict
[
'
entry_points
'
]:
ep_string
+=
'
- {}
\n
'
.
format
(
ep
)
return
ep_string
def
fmt_reqs
():
"""
Format requirements section of metadata.
:return: Formatted string if requirements exists; else empty string.
"""
reqs_string
=
''
if
'
install_requires
'
in
setup_dict
.
keys
():
reqs_string
+=
'
requirements:
\n
'
build_reqs
=
'
build:
\n
'
run_reqs
=
'
run:
\n
'
for
req
in
setup_dict
[
'
install_requires
'
].
split
(
'
,
'
):
build_reqs
+=
'
- {}
\n
'
.
format
(
req
)
run_reqs
+=
'
- {}
\n
'
.
format
(
req
)
reqs_string
+=
build_reqs
+
run_reqs
return
reqs_string
def
fmt_test
():
"""
Format test section of metadata.
:return: Formatted string if tests_require exists; else empty string.
"""
test_string
=
''
if
'
tests_require
'
in
setup_dict
.
keys
():
test_string
+=
(
'
test:
\n
'
'
source_files:
\n
'
'
- test/
\n
'
'
requires:
\n
'
)
for
req
in
setup_dict
[
'
tests_require
'
].
split
(
'
,
'
):
test_string
+=
'
- {}
\n
'
.
format
(
req
)
test_string
+=
(
'
commands:
\n
'
'
- pytest -vv --log-level=DEBUG --showlocals
\n
'
)
return
test_string
name
=
setup_dict
[
'
name
'
]
version
=
setup_dict
[
'
version
'
]
entry_points
=
fmt_ep
()
path
=
path
.
replace
(
"
./
"
,
""
)
requirements
=
fmt_reqs
()
test
=
fmt_test
()
license
=
setup_dict
[
'
license
'
]
summary
=
setup_dict
[
'
description
'
]
with
open
(
'
tools/metafile_template.txt
'
,
'
r
'
)
as
f
:
metadata
=
f
.
read
()
return
metadata
.
format
(
name
=
name
,
version
=
version
,
entry_points
=
entry_points
,
path
=
path
,
requirements
=
requirements
,
test
=
test
,
license
=
license
,
summary
=
summary
)
if
'
entry_points
'
in
setup_dict
.
keys
():
metadata
+=
'
entry_points:
\n
'
for
ep
in
setup_dict
[
'
entry_points
'
]:
metadata
+=
'
- {}
\n
'
.
format
(
ep
)
metadata
+=
(
'
script: {{{{PYTHON}}}} setup.py install
\n
'
'
\n
'
'
source:
\n
'
'
path: {}
\n
'
.
format
(
path
))
metadata
+=
'
\n
'
if
'
install_requires
'
in
setup_dict
.
keys
():
metadata
+=
'
requirements:
\n
'
build_reqs
=
'
build:
\n
'
run_reqs
=
'
run:
\n
'
for
req
in
setup_dict
[
'
install_requires
'
].
split
(
'
,
'
):
build_reqs
+=
'
- {}
\n
'
.
format
(
req
)
run_reqs
+=
'
- {}
\n
'
.
format
(
req
)
metadata
+=
build_reqs
metadata
+=
run_reqs
if
'
tests_require
'
in
setup_dict
.
keys
():
metadata
+=
(
'
test:
\n
'
'
source_files:
\n
'
'
- test/
\n
'
'
requires:
\n
'
)
for
req
in
setup_dict
[
'
tests_require
'
].
split
(
'
,
'
):
metadata
+=
'
- {}
\n
'
.
format
(
req
)
metadata
+=
(
'
commands:
\n
'
'
- pytest -vv --log-level=DEBUG --showlocals
\n
'
)
metadata
+=
(
'
\n
'
'
about:
\n
'
'
license:
"
{0}
"
\n
'
'
license_family:
"
{0}
"
\n
'
'
summary:
"
{1}
"'
.
format
(
setup_dict
[
'
license
'
],
setup_dict
[
'
description
'
]))
return
metadata
def
data_to_dict
(
setup_data
):
"""
Translates parsed setup.py data from unformatted list to formatted dictionary.
:param setup_data: Data extracted from setup.py using parse_setup.py
:return: Dictionary of formatted data.
"""
data_dict
=
{}
r_entry
=
r
"
([a-z-_]+):
"
r_id
=
r
"
[a-zA-Z0-9-_]
"
...
...
@@ -85,30 +116,59 @@ def data_to_dict(setup_data):
value
=
re
.
match
(
r_ep
,
value
).
group
(
'
values
'
)
value
=
re
.
split
(
'
,\s*
'
,
value
)
data_dict
[
field
]
=
value
# print("{}: {}".format(field, value))
return
data_dict
def
parse_setup
(
d
):
"""
Function for running parse_setup.py on each directory with a setup.py file.
NOTE: Contains a hack for getting parse_setup.py to run in each directory.
:param d: Directory with a setup.py file.
:return: Data collected from parse_setup.py.
"""
subprocess
.
run
([
'
cp
'
,
'
tools/parse_setup.py
'
,
d
])
os
.
chdir
(
d
)
proc
=
subprocess
.
run
([
'
python3
'
,
'
parse_setup.py
'
],
stdout
=
subprocess
.
PIPE
)
setup_data
=
(
proc
.
stdout
.
decode
(
'
utf-8
'
)).
split
(
'
\n
'
)
os
.
chdir
(
root
)
subprocess
.
run
([
'
rm
'
,
'
{}/parse_setup.py
'
.
format
(
d
)])
return
setup_data
def
get_outputs
(
names
):
"""
Generate list of metadata files that will be created.
:param names: List of names of all subprojects with a setup.py file.
:return: List of paths to output files as strings.
"""
outputs
=
[]
for
name
in
names
:
outputs
.
append
(
"
support/cond
a/{}/meta.yaml
"
.
format
(
name
))
outputs
.
append
(
"
metadat
a/{}/meta.yaml
"
.
format
(
name
))
return
outputs
def
get_dirs
():
find
=
subprocess
.
run
([
'
find
'
,
'
.
'
,
'
-name
'
,
'
setup.py
'
],
stdout
=
subprocess
.
PIPE
)
"""
Finds all subdirectories containing setup.py files.
:return: List of directories as strings.
"""
find
=
subprocess
.
run
([
'
find
'
,
'
.
'
,
'
-name
'
,
'
setup.py
'
,
'
-not
'
,
'
-path
'
,
'
./src/*
'
],
stdout
=
subprocess
.
PIPE
)
dirs
=
find
.
stdout
.
decode
(
'
utf-8
'
).
split
(
'
\n
'
)
dirs_cpy
=
dirs
for
i
,
d
in
enumerate
(
dirs
):
if
d
.
find
(
"
./src
"
)
>=
0
:
dirs
.
remove
(
d
)
continue
for
i
,
d
in
enumerate
(
dirs_cpy
):
dirs
[
i
]
=
d
.
replace
(
'
/setup.py
'
,
''
)
return
dirs
def
get_names
(
dirs
):
"""
Generate list of subproject names based on the rule that the name of the
subproject directory will be the name of the subproject.
:return: List of names as strings.
"""
names
=
[]
for
d
in
dirs
:
if
d
!=
''
:
...
...
@@ -122,13 +182,33 @@ def get_names(dirs):
return
names
def
del_substrings
(
s
,
substrings
):
"""
Function for deleting multiple substrings from a string.
:param s: String to be modified.
:param substrings: List of substrings to be targeted for deletion.
:return: Modified string.
"""
for
replace
in
substrings
:
s
=
s
.
replace
(
replace
,
''
)
return
s
root
=
os
.
getcwd
()
class
Recipe
:
"""
Buildout Recipe class.
For more detailed information, see the link.
http://www.buildout.org/en/latest/topics/writing-recipes.html
"""
def
__init__
(
self
,
buildout
,
name
,
options
):
"""
Initializes fields needed for recipe.
:param buildout: (Boilerplate) Dictionary of options from buildout section
of buildout.cfg
:param name: (Boilerplate) Name of section that uses this recipe.
:param options: (Boilerplate) Options of section that uses this recipe.
"""
self
.
dirs
=
get_dirs
()
self
.
names
=
get_names
(
self
.
dirs
)
self
.
outputs
=
get_outputs
(
self
.
names
)
...
...
@@ -136,19 +216,20 @@ class Recipe:
# TODO: Keep track of path in setup_dict
def
install
(
self
):
root
=
os
.
getcwd
()
"""
Install method that runs when recipe has components it needs to install.
:return: Paths to files, as strings, created by the recipe.
"""
for
i
,
d
in
enumerate
(
self
.
dirs
):
if
d
!=
''
:
os
.
chdir
(
d
)
proc
=
subprocess
.
run
([
'
python3
'
,
'
parse_setup.py
'
],
stdout
=
subprocess
.
PIPE
)
os
.
chdir
(
root
)
setup_data
=
(
proc
.
stdout
.
decode
(
'
utf-8
'
)).
split
(
'
\n
'
)
setup_data
=
parse_setup
(
d
)
data_dict
=
data_to_dict
(
setup_data
)
metadata
=
generate_meta
file
(
data_dict
,
d
)
metadata
=
generate_meta
data
(
data_dict
,
d
)
write_metafile
(
metadata
,
self
.
outputs
[
i
])
# Pass created file into options.created()
self
.
options
.
created
(
self
.
outputs
[
i
])
return
self
.
options
.
created
()
# No special procedure for updating vs. installing
update
=
install
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment