Skip to content

Commit 0bbc7aa

Browse files
authored
Deploy button py (#2535)
* Python side * format * import * todo * # * git binary or GitPython not installed * undo white spaces * undo white spaces * undo white spaces * handle_git_information_request * git_info_changed * Using enum * ahead_commits and uncommitted_files as properties * format
1 parent bfb7cfc commit 0bbc7aa

File tree

9 files changed

+110
-32
lines changed

9 files changed

+110
-32
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ cffi_bin
2727

2828
# Pyenv Stuff
2929
.python-version
30+
venv
3031

3132
# Autogenerated Protobufs
3233
lib/streamlit/proto/*_pb2.py

lib/streamlit/git_util.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ def __init__(self, path):
2323

2424
self.repo = git.Repo(path, search_parent_directories=True)
2525
self.git_version = self.repo.git.version_info
26+
2627
if self.git_version >= MIN_GIT_VERSION:
2728
git_root = self.repo.git.rev_parse("--show-toplevel")
2829
self.module = os.path.relpath(path, git_root)
29-
3030
except:
3131
# The git repo must be invalid for the following reasons:
3232
# * git binary or GitPython not installed
@@ -47,13 +47,46 @@ def is_valid(self) -> bool:
4747
def tracking_branch(self):
4848
if not self.is_valid():
4949
return None
50+
51+
if self.is_head_detached:
52+
return None
53+
5054
return self.repo.active_branch.tracking_branch()
5155

56+
@property
57+
def untracked_files(self):
58+
return self.repo.untracked_files
59+
60+
@property
61+
def is_head_detached(self):
62+
return self.repo.head.is_detached
63+
64+
@property
65+
def uncommitted_files(self):
66+
if not self.is_valid():
67+
return None
68+
69+
return [item.a_path for item in self.repo.index.diff(None)]
70+
71+
@property
72+
def ahead_commits(self):
73+
if not self.is_valid():
74+
return None
75+
76+
try:
77+
remote, branch_name = self.get_tracking_branch_remote()
78+
remote_branch = "/".join([remote.name, branch_name])
79+
80+
return list(self.repo.iter_commits(f"{remote_branch}..{branch_name}"))
81+
except:
82+
return list()
83+
5284
def get_tracking_branch_remote(self):
5385
if not self.is_valid():
5486
return None
5587

5688
tracking_branch = self.tracking_branch
89+
5790
if tracking_branch is None:
5891
return None
5992

lib/streamlit/report_session.py

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from streamlit.logger import get_logger
3737
from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
3838
from streamlit.proto.ClientState_pb2 import ClientState
39+
from streamlit.proto.GitInfo_pb2 import GitInfo
3940
from streamlit.server.server_util import serialize_forward_msg
4041
from streamlit.storage.file_storage import FileStorage
4142
from streamlit.watcher.local_sources_watcher import LocalSourcesWatcher
@@ -59,6 +60,7 @@ class ReportSession(object):
5960
and widget state.
6061
6162
A ReportSession is attached to each thread involved in running its Report.
63+
6264
"""
6365

6466
def __init__(self, ioloop, script_path, command_line, uploaded_file_manager):
@@ -345,34 +347,14 @@ def _enqueue_file_change_message(self):
345347
msg.session_event.report_changed_on_disk = True
346348
self.enqueue(msg)
347349

348-
def get_deploy_params(self):
349-
try:
350-
from streamlit.git_util import GitRepo
351-
352-
self._repo = GitRepo(self._report.script_path)
353-
return self._repo.get_repo_info()
354-
except:
355-
# Issues can arise based on the git structure
356-
# (e.g. if branch is in DETACHED HEAD state,
357-
# git is not installed, etc)
358-
# In this case, catch any errors
359-
return None
360-
361350
def _enqueue_new_report_message(self):
362351
self._report.generate_new_id()
352+
363353
msg = ForwardMsg()
364354
msg.new_report.report_id = self._report.report_id
365355
msg.new_report.name = self._report.name
366356
msg.new_report.script_path = self._report.script_path
367357

368-
# git deploy params
369-
deploy_params = self.get_deploy_params()
370-
if deploy_params is not None:
371-
repo, branch, module = deploy_params
372-
msg.new_report.deploy_params.repository = repo
373-
msg.new_report.deploy_params.branch = branch
374-
msg.new_report.deploy_params.module = module
375-
376358
# Immutable session data. We send this every time a new report is
377359
# started, to avoid having to track whether the client has already
378360
# received it. It does not change from run to run; it's up to the
@@ -423,6 +405,34 @@ def _enqueue_report_finished_message(self, status):
423405
msg.report_finished = status
424406
self.enqueue(msg)
425407

408+
def handle_git_information_request(self):
409+
msg = ForwardMsg()
410+
411+
try:
412+
from streamlit.git_util import GitRepo
413+
414+
self._repo = GitRepo(self._report.script_path)
415+
416+
repo, branch, module = self._repo.get_repo_info()
417+
418+
msg.git_info_changed.repository = repo
419+
msg.git_info_changed.branch = branch
420+
msg.git_info_changed.module = module
421+
422+
msg.git_info_changed.untracked_files[:] = self._repo.untracked_files
423+
msg.git_info_changed.uncommitted_files[:] = self._repo.uncommitted_files
424+
425+
if self._repo.is_head_detached:
426+
msg.git_info_changed.state = GitInfo.GitStates.HEAD_DETACHED
427+
elif len(self._repo.ahead_commits) > 0:
428+
msg.git_info_changed.state = GitInfo.GitStates.AHEAD_OF_REMOTE
429+
else:
430+
msg.git_info_changed.state = GitInfo.GitStates.DEFAULT
431+
except:
432+
pass
433+
434+
self.enqueue(msg)
435+
426436
def handle_rerun_script_request(self, client_state=None, is_preheat=False):
427437
"""Tell the ScriptRunner to re-run its report.
428438
@@ -431,6 +441,7 @@ def handle_rerun_script_request(self, client_state=None, is_preheat=False):
431441
client_state : streamlit.proto.ClientState_pb2.ClientState | None
432442
The ClientState protobuf to run the script with, or None
433443
to use previous client state.
444+
434445
is_preheat: boolean
435446
True if this ReportSession should run the script immediately, and
436447
then ignore the next rerun request if it matches the already-ran

lib/streamlit/server/server.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,8 @@ def on_message(self, payload):
680680
yield self._session.handle_save_request(self)
681681
elif msg_type == "rerun_script":
682682
self._session.handle_rerun_script_request(msg.rerun_script)
683+
elif msg_type == "load_git_info":
684+
self._session.handle_git_information_request()
683685
elif msg_type == "clear_cache":
684686
self._session.handle_clear_cache_request()
685687
elif msg_type == "set_run_on_save":

lib/tests/streamlit/report_session_test.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,6 @@ def get_option(name):
7070
# Expect func to be called only once, inside enqueue().
7171
func.assert_called_once()
7272

73-
@patch("streamlit.report_session.LocalSourcesWatcher")
74-
@pytest.mark.usefixtures("del_path")
75-
def test_get_deploy_params_with_no_git(self, _1):
76-
"""Make sure we try to handle execution control requests."""
77-
rs = ReportSession(None, report_session.__file__, "", UploadedFileManager())
78-
79-
self.assertIsNone(rs.get_deploy_params())
80-
8173
@patch("streamlit.report_session.config")
8274
@patch("streamlit.report_session.Report")
8375
@patch("streamlit.report_session.LocalSourcesWatcher")

proto/streamlit/proto/BackMsg.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ message BackMsg {
5353
bool close_connection = 10;
5454

5555
ClientState rerun_script = 11;
56+
57+
bool load_git_info = 12;
5658
}
5759

5860
reserved 1, 3, 4, 8, 9;

proto/streamlit/proto/ForwardMsg.proto

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import "streamlit/proto/PageConfig.proto";
2222
import "streamlit/proto/PageInfo.proto";
2323
import "streamlit/proto/SessionEvent.proto";
2424
import "streamlit/proto/SessionState.proto";
25+
import "streamlit/proto/GitInfo.proto";
2526

2627
// A message sent from Proxy to the browser
2728
message ForwardMsg {
@@ -49,6 +50,7 @@ message ForwardMsg {
4950
PageInfo page_info_changed = 12;
5051
PageConfig page_config_changed = 13;
5152
ReportFinishedStatus report_finished = 6;
53+
GitInfo git_info_changed = 14;
5254

5355
// Upload progress messages.
5456

@@ -75,7 +77,7 @@ message ForwardMsg {
7577
string ref_hash = 11;
7678
}
7779

78-
// Next: 14
80+
// Next: 15
7981
}
8082

8183
// ForwardMsgMetadata contains all data that does _not_ get hashed (or cached)
@@ -102,4 +104,4 @@ message ElementDimensionSpec {
102104

103105
// height in CSS points
104106
uint32 height = 2;
105-
}
107+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Copyright 2018-2020 Streamlit Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
syntax = "proto3";
18+
19+
// Message used to update page metadata.
20+
message GitInfo {
21+
string repository = 1;
22+
string branch = 2;
23+
string module = 3;
24+
repeated string untracked_files = 4;
25+
repeated string uncommitted_files = 5;
26+
27+
enum GitStates {
28+
DEFAULT = 0;
29+
HEAD_DETACHED = 1;
30+
AHEAD_OF_REMOTE = 2;
31+
}
32+
33+
GitStates state = 6;
34+
}

proto/streamlit/proto/NewReport.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ message NewReport {
3636
// "/foo/bar/foo.py"
3737
string script_path = 4;
3838

39+
// @todo This will be deprecated with the frontend changes
3940
DeployParams deploy_params = 5;
4041
}
4142

0 commit comments

Comments
 (0)