Skip to content
This repository was archived by the owner on Aug 25, 2024. It is now read-only.

Commit 7d2874b

Browse files
committed
alice: please: contribute: recommended community standards: Refactor into own files for readme and contributing overlays
Signed-off-by: John Andersen <[email protected]>
1 parent 296dc59 commit 7d2874b

File tree

5 files changed

+500
-263
lines changed

5 files changed

+500
-263
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
import pathlib
2+
import textwrap
3+
import itertools
4+
from typing import NamedTuple, NewType, Optional, Type
5+
6+
7+
import dffml
8+
import dffml_feature_git.feature.definitions
9+
10+
from .recommended_community_standards import *
11+
12+
13+
# NOTE Not sure if the orchestrator will know what to do if we do this
14+
# ContributingGitRepo = AliceGitRepo
15+
class ContributingGitRepo(NamedTuple):
16+
directory: str
17+
URL: str
18+
19+
20+
@dffml.entrypoint(
21+
"dffml.overlays.alice.please.contribute.recommended_community_standards.contributing"
22+
)
23+
class OverlayCONTRIBUTING:
24+
ContributingPath = NewType("ContributingPath", object)
25+
ContributingContents = NewType("repo.directory.contributing.contents", str)
26+
ContributingCommitMessage = NewType("repo.contributing.git.commit.message", str)
27+
ContributingBranch = NewType("repo.contributing.git.branch", str)
28+
ContributingPR = NewType("ContributingPR", str)
29+
ContributingIssue = NewType("ContributingIssue", str)
30+
ContributingIssueBody = NewType("ContributingIssueBody", str)
31+
ContributingIssueTitle = NewType("ContributingIssueTitle", str)
32+
ContributingPRTitle = NewType("contributing.github.pr.title", str)
33+
ContributingPRBody = NewType("contributing.github.pr.body", str)
34+
35+
# async def cli_run_on_repo(self, repo: "CLIRunOnRepo"):
36+
async def alice_contribute_contributing(
37+
self, repo: AliceGitRepo
38+
) -> ContributingGitRepo:
39+
async for ctx, results in dffml.subflow_typecast(
40+
self, OverlayCONTRIBUTING, AliceGitRepoInputSetContext(repo), repo,
41+
):
42+
pass
43+
44+
# TODO Run this system context where contributing contexts is given on CLI or
45+
# overriden via disabling of static overlay and application of overlay to
46+
# generate contents dynamiclly.
47+
# aka, test with `-inputs` option
48+
def create_contributing_file_if_not_exists(
49+
self,
50+
repo: ContributingGitRepo,
51+
contributing_contents: Optional[
52+
"ContributingContents"
53+
] = "# My Awesome Project's CONTRIBUTING",
54+
) -> "ContributingPath":
55+
# Do not create contributing if it already exists
56+
path = pathlib.Path(repo.directory, "CONTRIBUTING.md")
57+
if path.exists():
58+
return path
59+
path.write_text(contributing_contents)
60+
return path
61+
62+
async def contribute_contributing_md(
63+
self,
64+
repo: ContributingGitRepo,
65+
base: OverlayGit.BaseBranch,
66+
commit_message: "ContributingCommitMessage",
67+
) -> "ContributingBranch":
68+
branch_name: str = "alice-contribute-recommended-community-standards-contributing"
69+
# Attempt multiple commands
70+
async for event, result in dffml.run_command_events(
71+
["git", "checkout", base, "-b", branch_name,],
72+
cwd=repo.directory,
73+
logger=self.logger,
74+
raise_on_failure=False,
75+
events=[dffml.Subprocess.STDERR, dffml.Subprocess.COMPLETED,],
76+
):
77+
if event is dffml.Subprocess.STDERR:
78+
if b"is not a commit and a branch" in result:
79+
# Retry without explict branch when repo has no commits
80+
await dffml.run_command(
81+
["git", "checkout", "-b", branch_name,],
82+
cwd=repo.directory,
83+
logger=self.logger,
84+
)
85+
elif event is dffml.Subprocess.COMPLETED:
86+
if result != 0:
87+
raise RuntimeError("Failed to create branch for contribution")
88+
await dffml.run_command(
89+
["git", "add", "CONTRIBUTING.md"], cwd=repo.directory, logger=self.logger,
90+
)
91+
await dffml.run_command(
92+
["git", "commit", "-sm", commit_message],
93+
cwd=repo.directory,
94+
logger=self.logger,
95+
)
96+
return branch_name
97+
98+
async def contributing_pr(
99+
self,
100+
repo: ContributingGitRepo,
101+
base: OverlayGit.BaseBranch,
102+
origin: OverlayGit.WriteableGitRemoteOrigin,
103+
head: "ContributingBranch",
104+
title: "ContributingPRTitle",
105+
body: "ContributingPRBody",
106+
) -> "ContributingPR":
107+
"""
108+
109+
Check if we have any other issues open for the repo
110+
111+
.. code-block:: console
112+
:exec:
113+
114+
$ gh issue -R "${GITHUB_REPO_URL}" create --title "Recommended Community Standards (alice)" --body "${META_ISSUE_BODY}"
115+
116+
"""
117+
# Ensure an origin we can write to has an up to date version of head
118+
# with what we have locally so that GitHub can reference that branch for
119+
# the pull request.
120+
await dffml.run_command(
121+
# TODO Remove -f
122+
["git", "push", "-fu", origin, head],
123+
cwd=repo.directory,
124+
logger=self.logger,
125+
)
126+
await dffml.run_command(
127+
[
128+
"gh",
129+
"pr",
130+
"create",
131+
"--base",
132+
base,
133+
"--head",
134+
head,
135+
"--title",
136+
title,
137+
"--body",
138+
body,
139+
],
140+
cwd=repo.directory,
141+
logger=self.logger,
142+
)
143+
144+
# body: Optional['ContributingIssueBody'] = "References:\n- https://docs.github.com/articles/setting-guidelines-for-repository-contributors/",
145+
async def contributing_issue(
146+
self,
147+
repo: ContributingGitRepo,
148+
title: Optional[
149+
"ContributingIssueTitle"
150+
] = "Recommended Community Standard: CONTRIBUTING",
151+
body: Optional[
152+
"ContributingIssueBody"
153+
] = "References:\n- https://docs.github.com/articles/about-contributings/",
154+
) -> "ContributingIssue":
155+
async for event, result in dffml.run_command_events(
156+
[
157+
"gh",
158+
"issue",
159+
"create",
160+
"-R",
161+
repo.URL,
162+
"--title",
163+
title,
164+
"--body",
165+
body,
166+
],
167+
logger=self.logger,
168+
events=[dffml.Subprocess.STDOUT],
169+
):
170+
if event is dffml.Subprocess.STDOUT:
171+
# The URL of the issue created
172+
return result.strip().decode()
173+
174+
@staticmethod
175+
def contributing_commit_message(
176+
issue_url: "ContributingIssue",
177+
) -> "ContributingCommitMessage":
178+
return textwrap.dedent(
179+
f"""
180+
Recommended Community Standard: CONTRIBUTING
181+
182+
Closes: {issue_url}
183+
"""
184+
).lstrip()
185+
186+
@staticmethod
187+
async def contributing_pr_body(
188+
contributing_issue: "ContributingIssue",
189+
) -> "ContributingPRBody":
190+
return f"Closes: {contributing_issue}"
191+
192+
async def contributing_pr_title(
193+
self, contributing_issue: "ContributingIssue",
194+
) -> "ContributingPRTitle":
195+
"""
196+
Use the issue title as the pull request title
197+
"""
198+
async for event, result in dffml.run_command_events(
199+
[
200+
"gh",
201+
"issue",
202+
"view",
203+
"--json",
204+
"title",
205+
"-q",
206+
".title",
207+
contributing_issue,
208+
],
209+
logger=self.logger,
210+
events=[dffml.Subprocess.STDOUT],
211+
):
212+
if event is dffml.Subprocess.STDOUT:
213+
return result.strip().decode()
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import pathlib
2+
import textwrap
3+
import itertools
4+
from typing import NamedTuple, NewType, Optional, Type
5+
6+
7+
import dffml
8+
import dffml_feature_git.feature.definitions
9+
10+
from .recommended_community_standards import *
11+
12+
13+
class OverlayMetaIssue:
14+
"""
15+
16+
Check if we have any other issues open for the repo
17+
18+
.. code-block:: console
19+
:test:
20+
21+
$ gh issue -R "${GITHUB_REPO}" list --search "Recommended Community Standard"
22+
no issues match your search in intel/dffml
23+
24+
"""
25+
26+
MetaIssue = NewType("MetaIssue", str)
27+
MetaIssueTitle = NewType("MetaIssueTitle", str)
28+
MetaIssueBody = NewType("MetaIssueBody", str)
29+
30+
# TODO(alice) There is a bug with Optional which can be revield by use here
31+
@staticmethod
32+
def meta_issue_body(
33+
repo: AliceGitRepo,
34+
base: OverlayGit.BaseBranch,
35+
readme_path: OverlayREADME.ReadmePath,
36+
readme_issue: OverlayREADME.ReadmeIssue,
37+
) -> "MetaIssueBody":
38+
"""
39+
>>> AlicePleaseContributeRecommendedCommunityStandardsGitHubIssueOverlay.meta_issue_body(
40+
... repo=AliceGitRepo(
41+
... ),
42+
... )
43+
- [] [README](https://github.com/intel/dffml/blob/main/README.md)
44+
- [] Code of conduct
45+
- [] [Contributing](https://github.com/intel/dffml/blob/main/CONTRIBUTING.md)
46+
- [] [License](https://github.com/intel/dffml/blob/main/LICENSE)
47+
- [] Security
48+
"""
49+
return "\n".join(
50+
[
51+
"- ["
52+
+ ("x" if readme_issue is None else " ")
53+
+ "] "
54+
+ (
55+
"README: " + readme_issue
56+
if readme_issue is not None
57+
else f"[README]({repo.URL}/blob/{base}/{readme_path.relative_to(repo.directory).as_posix()})"
58+
),
59+
]
60+
)
61+
62+
async def create_meta_issue(
63+
self,
64+
repo: AliceGitRepo,
65+
body: "MetaIssueBody",
66+
title: Optional["MetaIssueTitle"] = "Recommended Community Standards",
67+
) -> "MetaIssue":
68+
# TODO Spawn background task (could use an orchestrator which creates a
69+
# GitHub Actions cron job to execute later).
70+
# set_close_meta_issue_trigger.
71+
async for event, result in dffml.run_command_events(
72+
[
73+
"gh",
74+
"issue",
75+
"create",
76+
"-R",
77+
repo.URL,
78+
"--title",
79+
title,
80+
"--body",
81+
body,
82+
],
83+
logger=self.logger,
84+
events=[dffml.Subprocess.STDOUT],
85+
):
86+
if event is dffml.Subprocess.STDOUT:
87+
# The URL of the issue created
88+
return result.strip().decode()

0 commit comments

Comments
 (0)