Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assorted fixes required for CRAN submission #1186

Merged
merged 21 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from 15 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
Binary file not shown.
112 changes: 69 additions & 43 deletions dash/development/_r_components_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@
\\arguments{{
{item_text}
}}

\\value{{{value_text}}}

"""

description_template = """Package: {package_name}
Expand All @@ -85,15 +88,13 @@
Description: {package_description}
Depends: R (>= 3.0.2){package_depends}
Imports: {package_imports}
Suggests: {package_suggests}
License: {package_license}
Suggests: {package_suggests}{package_rauthors}
License: {package_license}{package_copyright}
URL: {package_url}
BugReports: {package_issues}
Encoding: UTF-8
LazyData: true{vignette_builder}
KeepSource: true
Author: {package_author_no_email}
Maintainer: {maintainer}
"""

rbuild_ignore_string = r"""# ignore JS config files/folders
Expand Down Expand Up @@ -381,7 +382,12 @@ def write_help_file(name, props, description, prefix, rpkg_data):
default_argtext = ""
item_text = ""

# the return value of all Dash components should be the same,
# in an abstract sense -- they produce a list
value_text = "named list of JSON elements corresponding to React.js properties and their values" # noqa:E501

prop_keys = list(props.keys())
prop_keys_wc = list(props.keys())

# Filter props to remove those we don't want to expose
for item in prop_keys[:]:
Expand All @@ -406,12 +412,12 @@ def write_help_file(name, props, description, prefix, rpkg_data):
if "**Example Usage**" in description:
description = description.split("**Example Usage**")[0].rstrip()

if any(key.endswith("-*") for key in prop_keys):
if any(key.endswith("-*") for key in prop_keys_wc):
default_argtext += ", ..."
item_text += wildcard_help_template.format(get_wildcards_r(prop_keys))
item_text += wildcard_help_template.format(get_wildcards_r(prop_keys_wc))

# in R, the online help viewer does not properly wrap lines for
# the usage string -- we will hard wrap at 80 characters using
# the usage string -- we will hard wrap at 60 characters using
# textwrap.fill, starting from the beginning of the usage string

file_path = os.path.join("man", file_name)
Expand All @@ -421,9 +427,10 @@ def write_help_file(name, props, description, prefix, rpkg_data):
funcname=funcname,
name=name,
default_argtext=textwrap.fill(
default_argtext, width=80, break_long_words=False
default_argtext, width=60, break_long_words=False
),
item_text=item_text,
value_text=value_text,
description=description.replace("\n", " "),
)
)
Expand All @@ -442,7 +449,7 @@ def write_help_file(name, props, description, prefix, rpkg_data):

# pylint: disable=too-many-arguments
def write_class_file(
name, props, description, project_shortname, prefix=None, rpkg_data=None
name, props, description, project_shortname, prefix=None, rpkg_data=None
):
props = reorder_props(props=props)

Expand Down Expand Up @@ -505,7 +512,7 @@ def write_js_metadata(pkg_data, project_shortname, has_wildcards):
for filename in filenames:
extension = os.path.splitext(filename)[1]

if extension not in [".css", ".js", ".map"]:
if extension in [".py", ".pyc", ".json"]:
continue

target_dirname = os.path.join(
Expand All @@ -522,14 +529,14 @@ def write_js_metadata(pkg_data, project_shortname, has_wildcards):

# pylint: disable=R0914, R0913, R0912, R0915
def generate_rpkg(
pkg_data,
rpkg_data,
project_shortname,
export_string,
package_depends,
package_imports,
package_suggests,
has_wildcards,
pkg_data,
rpkg_data,
project_shortname,
export_string,
package_depends,
package_imports,
package_suggests,
has_wildcards,
):
"""Generate documents for R package creation.

Expand All @@ -552,6 +559,8 @@ def generate_rpkg(
# does not exist in package.json

package_name = snake_case_to_camel_case(project_shortname)
package_copyright = ""
package_rauthors = ""
lib_name = pkg_data.get("name")

if rpkg_data is not None:
Expand All @@ -563,6 +572,9 @@ def generate_rpkg(
package_description = rpkg_data.get(
"pkg_help_description", pkg_data.get("description", "")
)
if rpkg_data.get("pkg_copyright"):
package_copyright = "\nCopyright: {}".format(rpkg_data.get(
"pkg_copyright", ""))
else:
# fall back to using description in package.json, if present
package_title = pkg_data.get("description", "")
Expand Down Expand Up @@ -601,20 +613,35 @@ def generate_rpkg(

package_author = pkg_data.get("author")

package_author_no_email = package_author.split(" <")[0] + " [aut]"
package_author_name = package_author.split(" <")[0]
package_author_email = package_author.split(" <")[1][:-1]

package_author_fn = package_author_name.split(" ")[0]
package_author_ln = package_author_name.rsplit(" ", 2)[-1]

maintainer = pkg_data.get("maintainer", pkg_data.get("author"))

if "<" not in package_author or "<" not in maintainer:
if "<" not in package_author:
print(
"Error, aborting R package generation: "
"R packages require a properly formatted author or "
"maintainer field or installation will fail. Please include "
"an email address enclosed within < > brackets in package.json. ",
"R packages require a properly formatted author field "
"or installation will fail. Please include an email "
"address enclosed within < > brackets in package.json. ",
file=sys.stderr,
)
sys.exit(1)

if rpkg_data is not None:
if rpkg_data.get("pkg_authors"):
package_rauthors = '\nAuthors@R: {}'.format(rpkg_data.get(
"pkg_authors", ""))
else:
package_rauthors = '\nAuthors@R: person("{}", "{}", role = c("aut", "cre"), email = "{}")'.format(
package_author_fn,
package_author_ln,
package_author_email
)

if not (os.path.isfile("LICENSE") or os.path.isfile("LICENSE.txt")):
package_license = pkg_data.get("license", "")
else:
Expand Down Expand Up @@ -660,16 +687,15 @@ def generate_rpkg(
package_title=package_title,
package_description=package_description,
package_version=package_version,
package_author=package_author,
package_rauthors=package_rauthors,
package_depends=package_depends,
package_imports=package_imports,
package_suggests=package_suggests,
package_license=package_license,
package_copyright=package_copyright,
package_url=package_url,
package_issues=package_issues,
vignette_builder=vignette_builder,
package_author_no_email=package_author_no_email,
maintainer=maintainer,
)

with open("DESCRIPTION", "w+") as f3:
Expand Down Expand Up @@ -708,16 +734,16 @@ def format_fn_name(prefix, name):

# pylint: disable=unused-argument
def generate_exports(
project_shortname,
components,
metadata,
pkg_data,
rpkg_data,
prefix,
package_depends,
package_imports,
package_suggests,
**kwargs
project_shortname,
components,
metadata,
pkg_data,
rpkg_data,
prefix,
package_depends,
package_imports,
package_suggests,
**kwargs
):
export_string = make_namespace_exports(components, prefix)

Expand Down Expand Up @@ -747,9 +773,9 @@ def make_namespace_exports(components, prefix):
export_string = ""
for component in components:
if (
not component.endswith("-*")
and str(component) not in r_keywords
and str(component) not in ["setProps", "children"]
not component.endswith("-*")
and str(component) not in r_keywords
and str(component) not in ["setProps", "children"]
):
export_string += "export({}{})\n".format(prefix, component)

Expand Down Expand Up @@ -885,9 +911,9 @@ def get_r_type(type_object, is_flow_type=False, indent_num=0):
js_type_name = type_object["name"]
js_to_r_types = get_r_prop_types(type_object=type_object)
if (
"computed" in type_object
and type_object["computed"]
or type_object.get("type", "") == "function"
"computed" in type_object
and type_object["computed"]
or type_object.get("type", "") == "function"
):
return ""
elif js_type_name in js_to_r_types:
Expand All @@ -905,7 +931,7 @@ def print_r_type(typedata):

# pylint: disable=too-many-arguments
def create_prop_docstring_r(
prop_name, type_object, required, description, indent_num, is_flow_type=False
prop_name, type_object, required, description, indent_num, is_flow_type=False
):
"""
Create the Dash component prop docstring
Expand Down