better-git-of-theseus 0.5.1__py3-none-any.whl → 0.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: better-git-of-theseus
3
- Version: 0.5.1
3
+ Version: 0.6.0
4
4
  Summary: Plot stats on Git repositories with interactive Plotly charts
5
5
  Home-page: https://github.com/onewesong/better-git-of-theseus
6
6
  Author: Erik Bernhardsson
@@ -0,0 +1,15 @@
1
+ better_git_of_theseus-0.6.0.dist-info/licenses/LICENSE,sha256=yNNDAWUe1WLKnuUcRp9X95C-yP2lfGl69m97Ftw-DUw,11345
2
+ git_of_theseus/__init__.py,sha256=LeG5tCOgvZMmKOjmO_HRg54sWF2K3-lTBf8H_vHMFio,273
3
+ git_of_theseus/analyze.py,sha256=17hEL8ROhSqDwS505RbEXfmoesFW3rOVgJTnZKB3GgE,22085
4
+ git_of_theseus/app.py,sha256=DWl9h-vhRSDyuP94v25ttcK9dgSy2cm00usAryEU5-U,9239
5
+ git_of_theseus/cmd.py,sha256=ftnKDSH4xiy6l5AE4MyLHcnvCSuOueAqYTDgznxeFew,716
6
+ git_of_theseus/line_plot.py,sha256=LegoVy0VEFT4sM5fYCES-I_2H9UaerCopDI3J2dyHeU,3117
7
+ git_of_theseus/plotly_plots.py,sha256=k-EuWD4c4FPLP7ZwKBF1uYwPDA8huVaYVqu_fDhiTog,7359
8
+ git_of_theseus/stack_plot.py,sha256=q4-YlW3PyiwbIBFeHBA3dsdR1I_XKUQD74hAuSfhIR4,3150
9
+ git_of_theseus/survival_plot.py,sha256=NEITAa0pMD9uJVsPd7JA71ucavnG1RxgC-F6Jk-K5bE,4868
10
+ git_of_theseus/utils.py,sha256=Xw2udch9ixSgFInGhIC4_RJ_9IB3E8MmV1dmznavCWc,1026
11
+ better_git_of_theseus-0.6.0.dist-info/METADATA,sha256=P1i_HFJIlI-48TJFWy0fewD76VMNBwlHrDMnlcbBtBI,3821
12
+ better_git_of_theseus-0.6.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
13
+ better_git_of_theseus-0.6.0.dist-info/entry_points.txt,sha256=dEBL6oCDAozY13Y_qxS_6-qkyCA7R2TpjoLH6QJR72g,66
14
+ better_git_of_theseus-0.6.0.dist-info/top_level.txt,sha256=2kpp8WgiBzqVLxua_mBS00Nj4cUORaRbJi121THJ_0o,15
15
+ better_git_of_theseus-0.6.0.dist-info/RECORD,,
git_of_theseus/analyze.py CHANGED
@@ -256,6 +256,7 @@ def analyze(
256
256
  procs=2,
257
257
  quiet=False,
258
258
  opt=False,
259
+ progress_callback=None,
259
260
  ):
260
261
  use_mailmap = (Path(repo_dir) / ".mailmap").exists()
261
262
  repo = git.Repo(repo_dir)
@@ -304,9 +305,11 @@ def analyze(
304
305
  ) # repo.git.commit_graph('write --changed-paths') doesn't work for some reason
305
306
 
306
307
  desc = "{:<55s}".format("Listing all commits")
307
- for commit in tqdm(
308
+ for i, commit in enumerate(tqdm(
308
309
  repo.iter_commits(branch), desc=desc, unit=" Commits", **tqdm_args
309
- ):
310
+ )):
311
+ if progress_callback:
312
+ progress_callback(0, f"Listing commits: {i}")
310
313
  cohort = datetime.datetime.utcfromtimestamp(commit.committed_date).strftime(
311
314
  cohortfm
312
315
  )
@@ -330,6 +333,8 @@ def analyze(
330
333
  master_commits.append(commit)
331
334
  last_date = commit.committed_date
332
335
  bar.update()
336
+ if progress_callback:
337
+ progress_callback(0, f"Backtracking branch: {len(master_commits)} commits found")
333
338
  if not commit.parents:
334
339
  break
335
340
  commit = commit.parents[0]
@@ -388,6 +393,8 @@ def analyze(
388
393
  curve_key_tuples.add(("ext", ext))
389
394
  curve_key_tuples.add(("dir", get_top_dir(entry.path)))
390
395
  bar.update()
396
+ if progress_callback:
397
+ progress_callback(0, f"Discovering entries: {entries_total}")
391
398
  master_commits[i] = MiniCommit(
392
399
  commit
393
400
  ) # Might have cached the entries, we don't want that
@@ -465,7 +472,9 @@ def analyze(
465
472
  **tqdm_args,
466
473
  ) as bar:
467
474
  cbar = tqdm(master_commits, desc=desc, unit=" Commits", position=0, **tqdm_args)
468
- for commit in cbar:
475
+ for i, commit in enumerate(cbar):
476
+ if progress_callback:
477
+ progress_callback(i / len(master_commits), f"Analyzing commit {i+1}/{len(master_commits)}")
469
478
  t = datetime.datetime.utcfromtimestamp(commit.committed_date)
470
479
  ts.append(t) # x axis
471
480
 
git_of_theseus/app.py CHANGED
@@ -51,7 +51,8 @@ if len(sys.argv) > 1:
51
51
  default_repo = sys.argv[1]
52
52
 
53
53
  repo_path = default_repo
54
- # Path display removed as per user request
54
+ repo_name = os.path.basename(os.path.abspath(repo_path))
55
+ st.sidebar.markdown(f"**Repo:** {repo_name}")
55
56
 
56
57
  # Fetch branches for the selectbox
57
58
  try:
@@ -106,6 +107,9 @@ with st.sidebar.expander("Analysis Parameters"):
106
107
 
107
108
  @st.cache_data(show_spinner=False)
108
109
  def run_analysis(repo_path, branch, cohortfm, interval, procs, ignore):
110
+ # This is a dummy wrapper for the cached function
111
+ # Because we need the callback to update the UI, we can't easily cache the callback-enabled version
112
+ # However, we can cache the final result.
109
113
  return analyze(
110
114
  repo_path,
111
115
  cohortfm=cohortfm,
@@ -117,20 +121,43 @@ def run_analysis(repo_path, branch, cohortfm, interval, procs, ignore):
117
121
  quiet=True
118
122
  )
119
123
 
124
+ def run_analysis_with_progress(repo_path, branch, cohortfm, interval, procs, ignore):
125
+ progress_bar = st.progress(0)
126
+ status_text = st.empty()
127
+
128
+ def progress_callback(progress, text):
129
+ progress_bar.progress(progress)
130
+ status_text.text(text)
131
+
132
+ results = analyze(
133
+ repo_path,
134
+ cohortfm=cohortfm,
135
+ interval=interval,
136
+ ignore=ignore,
137
+ outdir=None,
138
+ branch=branch,
139
+ procs=procs,
140
+ quiet=True,
141
+ progress_callback=progress_callback
142
+ )
143
+
144
+ progress_bar.empty()
145
+ status_text.empty()
146
+ return results
147
+
120
148
  # State management for analysis results
121
149
  if 'analysis_results' not in st.session_state:
122
150
  st.session_state.analysis_results = None
123
151
 
124
152
  if st.sidebar.button("🚀 Run Analysis") or (len(sys.argv) > 1 and st.session_state.analysis_results is None):
125
- with st.spinner("Analyzing repository... this may take a while."):
126
- try:
127
- st.session_state.analysis_results = run_analysis(
128
- repo_path, branch, cohortfm, interval, procs, ignore
129
- )
130
- st.success("Analysis completed!")
131
- except Exception as e:
132
- st.error(f"Analysis failed: {e}")
133
- st.session_state.analysis_results = None
153
+ try:
154
+ st.session_state.analysis_results = run_analysis_with_progress(
155
+ repo_path, branch, cohortfm, interval, procs, ignore
156
+ )
157
+ st.success("Analysis completed!")
158
+ except Exception as e:
159
+ st.error(f"Analysis failed: {e}")
160
+ st.session_state.analysis_results = None
134
161
 
135
162
  # Main View
136
163
  if st.session_state.analysis_results:
git_of_theseus/cmd.py CHANGED
@@ -12,12 +12,16 @@ def main():
12
12
 
13
13
  # Run streamlit
14
14
  # We pass the repo_path as an argument to the streamlit script
15
- subprocess.run([
16
- sys.executable, "-m", "streamlit", "run",
17
- app_path,
18
- "--browser.gatherUsageStats", "false",
19
- "--", repo_path
20
- ])
15
+ try:
16
+ subprocess.run([
17
+ sys.executable, "-m", "streamlit", "run",
18
+ app_path,
19
+ "--browser.gatherUsageStats", "false",
20
+ "--", repo_path
21
+ ])
22
+ except KeyboardInterrupt:
23
+ # Exit gracefully on Ctrl+C
24
+ sys.exit(0)
21
25
 
22
26
  if __name__ == "__main__":
23
27
  main()
@@ -68,8 +68,8 @@ def plotly_stack_plot(data, max_n=20, normalize=False, title=None):
68
68
  ),
69
69
  xaxis=dict(title="Date", gridcolor='rgba(128,128,128,0.2)'),
70
70
  hovermode="x unified",
71
- margin=dict(l=20, r=20, t=60, b=100),
72
- legend=dict(orientation="h", yanchor="top", y=-0.15, xanchor="center", x=0.5),
71
+ margin=dict(l=20, r=20, t=60, b=120),
72
+ legend=dict(orientation="h", yanchor="top", y=-0.25, xanchor="center", x=0.5),
73
73
  plot_bgcolor='rgba(0,0,0,0)',
74
74
  paper_bgcolor='rgba(0,0,0,0)'
75
75
  )
@@ -97,8 +97,8 @@ def plotly_line_plot(data, max_n=20, normalize=False, title=None):
97
97
  ),
98
98
  xaxis=dict(title="Date", gridcolor='rgba(128,128,128,0.2)'),
99
99
  hovermode="x unified",
100
- margin=dict(l=20, r=20, t=60, b=100),
101
- legend=dict(orientation="h", yanchor="top", y=-0.15, xanchor="center", x=0.5),
100
+ margin=dict(l=20, r=20, t=60, b=120),
101
+ legend=dict(orientation="h", yanchor="top", y=-0.25, xanchor="center", x=0.5),
102
102
  plot_bgcolor='rgba(0,0,0,0)',
103
103
  paper_bgcolor='rgba(0,0,0,0)'
104
104
  )
@@ -169,8 +169,8 @@ def plotly_survival_plot(commit_history, exp_fit=False, years=5, title=None):
169
169
  yaxis=dict(title="Lines still present (%)", range=[0, 105], gridcolor='rgba(128,128,128,0.2)'),
170
170
  xaxis=dict(title="Years", range=[0, years], gridcolor='rgba(128,128,128,0.2)'),
171
171
  hovermode="x unified",
172
- margin=dict(l=20, r=20, t=50, b=100),
173
- legend=dict(orientation="h", yanchor="top", y=-0.15, xanchor="center", x=0.5),
172
+ margin=dict(l=20, r=20, t=50, b=120),
173
+ legend=dict(orientation="h", yanchor="top", y=-0.25, xanchor="center", x=0.5),
174
174
  plot_bgcolor='rgba(0,0,0,0)',
175
175
  paper_bgcolor='rgba(0,0,0,0)'
176
176
  )
@@ -1,15 +0,0 @@
1
- better_git_of_theseus-0.5.1.dist-info/licenses/LICENSE,sha256=yNNDAWUe1WLKnuUcRp9X95C-yP2lfGl69m97Ftw-DUw,11345
2
- git_of_theseus/__init__.py,sha256=LeG5tCOgvZMmKOjmO_HRg54sWF2K3-lTBf8H_vHMFio,273
3
- git_of_theseus/analyze.py,sha256=78E1G2FdSS9VZd0jKSnO5gpXwzNCjtzkSAxSzadYM3A,21547
4
- git_of_theseus/app.py,sha256=6GuBWC3WaN0VkwHAmKM_6ZNalf7NcXgXYq3ZP6XMDvY,8463
5
- git_of_theseus/cmd.py,sha256=y0ML5YtCSGZ1Qp9XNTnfZyAkuWY_3j_e3-eVx-3pLpo,597
6
- git_of_theseus/line_plot.py,sha256=LegoVy0VEFT4sM5fYCES-I_2H9UaerCopDI3J2dyHeU,3117
7
- git_of_theseus/plotly_plots.py,sha256=jO1ix0B17t5ytejlTBX01xbqTDs_N9Ia-qzZsrfq76A,7359
8
- git_of_theseus/stack_plot.py,sha256=q4-YlW3PyiwbIBFeHBA3dsdR1I_XKUQD74hAuSfhIR4,3150
9
- git_of_theseus/survival_plot.py,sha256=NEITAa0pMD9uJVsPd7JA71ucavnG1RxgC-F6Jk-K5bE,4868
10
- git_of_theseus/utils.py,sha256=Xw2udch9ixSgFInGhIC4_RJ_9IB3E8MmV1dmznavCWc,1026
11
- better_git_of_theseus-0.5.1.dist-info/METADATA,sha256=Q_9TmvZZmFgj5Ym_73oOK6AHNqYnyNsUkzO7w_ocaDo,3821
12
- better_git_of_theseus-0.5.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
13
- better_git_of_theseus-0.5.1.dist-info/entry_points.txt,sha256=dEBL6oCDAozY13Y_qxS_6-qkyCA7R2TpjoLH6QJR72g,66
14
- better_git_of_theseus-0.5.1.dist-info/top_level.txt,sha256=2kpp8WgiBzqVLxua_mBS00Nj4cUORaRbJi121THJ_0o,15
15
- better_git_of_theseus-0.5.1.dist-info/RECORD,,